@promptbook/cli 0.92.0-31 → 0.92.0-32
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 +55 -102
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +6 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +59 -106
- package/umd/index.umd.js.map +1 -1
package/esm/index.es.js
CHANGED
|
@@ -26,8 +26,8 @@ import http from 'http';
|
|
|
26
26
|
import { Server } from 'socket.io';
|
|
27
27
|
import swaggerUi from 'swagger-ui-express';
|
|
28
28
|
import Anthropic from '@anthropic-ai/sdk';
|
|
29
|
-
import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
|
|
30
29
|
import Bottleneck from 'bottleneck';
|
|
30
|
+
import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
|
|
31
31
|
import OpenAI from 'openai';
|
|
32
32
|
import { Readability } from '@mozilla/readability';
|
|
33
33
|
import { JSDOM } from 'jsdom';
|
|
@@ -47,7 +47,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
|
|
|
47
47
|
* @generated
|
|
48
48
|
* @see https://github.com/webgptorg/promptbook
|
|
49
49
|
*/
|
|
50
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-
|
|
50
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.92.0-32';
|
|
51
51
|
/**
|
|
52
52
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
53
53
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -3119,23 +3119,17 @@ class MultipleLlmExecutionTools {
|
|
|
3119
3119
|
* Check the configuration of all execution tools
|
|
3120
3120
|
*/
|
|
3121
3121
|
async checkConfiguration() {
|
|
3122
|
-
//
|
|
3123
|
-
|
|
3124
|
-
await llmExecutionTools.checkConfiguration();
|
|
3125
|
-
}
|
|
3122
|
+
// Note: Run checks in parallel
|
|
3123
|
+
await Promise.all(this.llmExecutionTools.map((tools) => tools.checkConfiguration()));
|
|
3126
3124
|
}
|
|
3127
3125
|
/**
|
|
3128
3126
|
* List all available models that can be used
|
|
3129
3127
|
* This lists is a combination of all available models from all execution tools
|
|
3130
3128
|
*/
|
|
3131
3129
|
async listModels() {
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
const models = await llmExecutionTools.listModels();
|
|
3136
|
-
availableModels.push(...models);
|
|
3137
|
-
}
|
|
3138
|
-
return availableModels;
|
|
3130
|
+
// Obtain all models in parallel and flatten
|
|
3131
|
+
const modelArrays = await Promise.all(this.llmExecutionTools.map((tools) => tools.listModels()));
|
|
3132
|
+
return modelArrays.flat();
|
|
3139
3133
|
}
|
|
3140
3134
|
/**
|
|
3141
3135
|
* Calls the best available chat model
|
|
@@ -15249,6 +15243,8 @@ class AnthropicClaudeExecutionTools {
|
|
|
15249
15243
|
* Anthropic Claude API client.
|
|
15250
15244
|
*/
|
|
15251
15245
|
this.client = null;
|
|
15246
|
+
const rate = this.options.maxRequestsPerMinute || DEFAULT_MAX_REQUESTS_PER_MINUTE;
|
|
15247
|
+
this.limiter = new Bottleneck({ minTime: 60000 / rate });
|
|
15252
15248
|
}
|
|
15253
15249
|
get title() {
|
|
15254
15250
|
return 'Anthropic Claude';
|
|
@@ -15300,8 +15296,6 @@ class AnthropicClaudeExecutionTools {
|
|
|
15300
15296
|
// <- TODO: [🌾] Make some global max cap for maxTokens
|
|
15301
15297
|
temperature: modelRequirements.temperature,
|
|
15302
15298
|
system: modelRequirements.systemMessage,
|
|
15303
|
-
// <- TODO: [🈁] Use `seed` here AND/OR use is `isDeterministic` for entire execution tools
|
|
15304
|
-
// <- Note: [🧆]
|
|
15305
15299
|
messages: [
|
|
15306
15300
|
{
|
|
15307
15301
|
role: 'user',
|
|
@@ -15310,14 +15304,14 @@ class AnthropicClaudeExecutionTools {
|
|
|
15310
15304
|
// @see https://docs.anthropic.com/en/docs/test-and-evaluate/strengthen-guardrails/increase-consistency#specify-the-desired-output-format
|
|
15311
15305
|
},
|
|
15312
15306
|
],
|
|
15313
|
-
// TODO: Is here some equivalent of user identification?> user: this.options.user,
|
|
15314
15307
|
};
|
|
15315
15308
|
const start = $getCurrentDate();
|
|
15316
|
-
let complete;
|
|
15317
15309
|
if (this.options.isVerbose) {
|
|
15318
15310
|
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
15319
15311
|
}
|
|
15320
|
-
const rawResponse = await
|
|
15312
|
+
const rawResponse = await this.limiter
|
|
15313
|
+
.schedule(() => client.messages.create(rawRequest))
|
|
15314
|
+
.catch((error) => {
|
|
15321
15315
|
if (this.options.isVerbose) {
|
|
15322
15316
|
console.info(colors.bgRed('error'), error);
|
|
15323
15317
|
}
|
|
@@ -15337,12 +15331,11 @@ class AnthropicClaudeExecutionTools {
|
|
|
15337
15331
|
throw new PipelineExecutionError(`Returned content is not "text" type but "${contentBlock.type}"`);
|
|
15338
15332
|
}
|
|
15339
15333
|
const resultContent = contentBlock.text;
|
|
15340
|
-
|
|
15341
|
-
complete = $getCurrentDate();
|
|
15334
|
+
const complete = $getCurrentDate();
|
|
15342
15335
|
const usage = computeAnthropicClaudeUsage(rawPromptContent || '', resultContent || '', rawResponse);
|
|
15343
15336
|
return exportJson({
|
|
15344
15337
|
name: 'promptResult',
|
|
15345
|
-
message: `Result of \`
|
|
15338
|
+
message: `Result of \`AnthropicClaudeExecutionTools.callChatModel\``,
|
|
15346
15339
|
order: [],
|
|
15347
15340
|
value: {
|
|
15348
15341
|
content: resultContent,
|
|
@@ -15359,83 +15352,59 @@ class AnthropicClaudeExecutionTools {
|
|
|
15359
15352
|
},
|
|
15360
15353
|
});
|
|
15361
15354
|
}
|
|
15362
|
-
|
|
15363
|
-
|
|
15364
|
-
|
|
15365
|
-
|
|
15366
|
-
): Promise<CompletionPromptResult> {
|
|
15367
|
-
|
|
15355
|
+
/**
|
|
15356
|
+
* Calls Anthropic Claude API to use a completion model.
|
|
15357
|
+
*/
|
|
15358
|
+
async callCompletionModel(prompt) {
|
|
15368
15359
|
if (this.options.isVerbose) {
|
|
15369
15360
|
console.info('🖋 Anthropic Claude callCompletionModel call');
|
|
15370
15361
|
}
|
|
15371
|
-
|
|
15372
15362
|
const { content, parameters, modelRequirements } = prompt;
|
|
15373
|
-
|
|
15374
|
-
// TODO: [☂] Use here more modelRequirements
|
|
15375
15363
|
if (modelRequirements.modelVariant !== 'COMPLETION') {
|
|
15376
15364
|
throw new PipelineExecutionError('Use callCompletionModel only for COMPLETION variant');
|
|
15377
15365
|
}
|
|
15378
|
-
|
|
15366
|
+
const client = await this.getClient();
|
|
15379
15367
|
const modelName = modelRequirements.modelName || this.getDefaultChatModel().modelName;
|
|
15380
|
-
const
|
|
15368
|
+
const rawPromptContent = templateParameters(content, { ...parameters, modelName });
|
|
15369
|
+
const rawRequest = {
|
|
15381
15370
|
model: modelName,
|
|
15382
|
-
|
|
15383
|
-
|
|
15384
|
-
// <- TODO: Use here `systemMessage`, `temperature` and `seed`
|
|
15385
|
-
};
|
|
15386
|
-
|
|
15387
|
-
const rawRequest: xxxx.Completions.CompletionCreateParamsNonStreaming = {
|
|
15388
|
-
...modelSettings,
|
|
15371
|
+
max_tokens_to_sample: modelRequirements.maxTokens || 2000,
|
|
15372
|
+
temperature: modelRequirements.temperature,
|
|
15389
15373
|
prompt: rawPromptContent,
|
|
15390
|
-
user: this.options.user,
|
|
15391
15374
|
};
|
|
15392
|
-
const start
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
|
|
15397
|
-
|
|
15398
|
-
|
|
15399
|
-
|
|
15400
|
-
|
|
15401
|
-
}
|
|
15402
|
-
throw error;
|
|
15403
|
-
});
|
|
15404
|
-
|
|
15405
|
-
|
|
15375
|
+
const start = $getCurrentDate();
|
|
15376
|
+
const rawResponse = await this.limiter
|
|
15377
|
+
.schedule(() => client.completions.create(rawRequest))
|
|
15378
|
+
.catch((error) => {
|
|
15379
|
+
if (this.options.isVerbose) {
|
|
15380
|
+
console.info(colors.bgRed('error'), error);
|
|
15381
|
+
}
|
|
15382
|
+
throw error;
|
|
15383
|
+
});
|
|
15406
15384
|
if (this.options.isVerbose) {
|
|
15407
15385
|
console.info(colors.bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
15408
15386
|
}
|
|
15409
|
-
|
|
15410
|
-
|
|
15411
|
-
throw new PipelineExecutionError('No choises from Anthropic Claude');
|
|
15387
|
+
if (!rawResponse.completion) {
|
|
15388
|
+
throw new PipelineExecutionError('No completion from Anthropic Claude');
|
|
15412
15389
|
}
|
|
15413
|
-
|
|
15414
|
-
|
|
15415
|
-
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
modelName: rawResponse.model || model,
|
|
15429
|
-
timing: {
|
|
15430
|
-
start,
|
|
15431
|
-
complete,
|
|
15390
|
+
const resultContent = rawResponse.completion;
|
|
15391
|
+
const complete = $getCurrentDate();
|
|
15392
|
+
const usage = computeAnthropicClaudeUsage(rawPromptContent, resultContent, rawResponse);
|
|
15393
|
+
return exportJson({
|
|
15394
|
+
name: 'promptResult',
|
|
15395
|
+
message: `Result of \`AnthropicClaudeExecutionTools.callCompletionModel\``,
|
|
15396
|
+
order: [],
|
|
15397
|
+
value: {
|
|
15398
|
+
content: resultContent,
|
|
15399
|
+
modelName: rawResponse.model || modelName,
|
|
15400
|
+
timing: { start, complete },
|
|
15401
|
+
usage,
|
|
15402
|
+
rawPromptContent,
|
|
15403
|
+
rawRequest,
|
|
15404
|
+
rawResponse,
|
|
15432
15405
|
},
|
|
15433
|
-
usage,
|
|
15434
|
-
rawResponse,
|
|
15435
|
-
// <- [🗯]
|
|
15436
15406
|
});
|
|
15437
15407
|
}
|
|
15438
|
-
*/
|
|
15439
15408
|
// <- Note: [🤖] callXxxModel
|
|
15440
15409
|
/**
|
|
15441
15410
|
* Get the model that should be used as default
|
|
@@ -15444,7 +15413,7 @@ class AnthropicClaudeExecutionTools {
|
|
|
15444
15413
|
const model = ANTHROPIC_CLAUDE_MODELS.find(({ modelName }) => modelName.startsWith(defaultModelName));
|
|
15445
15414
|
if (model === undefined) {
|
|
15446
15415
|
throw new UnexpectedError(spaceTrim((block) => `
|
|
15447
|
-
Cannot find model in
|
|
15416
|
+
Cannot find model in Anthropic Claude models with name "${defaultModelName}" which should be used as default.
|
|
15448
15417
|
|
|
15449
15418
|
Available models:
|
|
15450
15419
|
${block(ANTHROPIC_CLAUDE_MODELS.map(({ modelName }) => `- "${modelName}"`).join('\n'))}
|
|
@@ -17078,11 +17047,9 @@ function computeOpenAiUsage(promptContent, // <- Note: Intentionally using [] to
|
|
|
17078
17047
|
resultContent, rawResponse) {
|
|
17079
17048
|
var _a, _b;
|
|
17080
17049
|
if (rawResponse.usage === undefined) {
|
|
17081
|
-
console.log('!!! computeOpenAiUsage', 'The usage is not defined in the response from OpenAI');
|
|
17082
17050
|
throw new PipelineExecutionError('The usage is not defined in the response from OpenAI');
|
|
17083
17051
|
}
|
|
17084
17052
|
if (((_a = rawResponse.usage) === null || _a === void 0 ? void 0 : _a.prompt_tokens) === undefined) {
|
|
17085
|
-
console.log('!!! computeOpenAiUsage', 'In OpenAI response `usage.prompt_tokens` not defined');
|
|
17086
17053
|
throw new PipelineExecutionError('In OpenAI response `usage.prompt_tokens` not defined');
|
|
17087
17054
|
}
|
|
17088
17055
|
const inputTokens = rawResponse.usage.prompt_tokens;
|
|
@@ -17096,15 +17063,6 @@ resultContent, rawResponse) {
|
|
|
17096
17063
|
isUncertain = true;
|
|
17097
17064
|
}
|
|
17098
17065
|
}
|
|
17099
|
-
console.log('!!! computeOpenAiUsage', {
|
|
17100
|
-
inputTokens,
|
|
17101
|
-
outputTokens,
|
|
17102
|
-
rawResponse,
|
|
17103
|
-
'rawResponse.model': rawResponse.model,
|
|
17104
|
-
OPENAI_MODELS,
|
|
17105
|
-
resultContent,
|
|
17106
|
-
modelInfo,
|
|
17107
|
-
});
|
|
17108
17066
|
let price;
|
|
17109
17067
|
if (modelInfo === undefined || modelInfo.pricing === undefined) {
|
|
17110
17068
|
price = uncertainNumber();
|
|
@@ -17248,7 +17206,6 @@ class OpenAiExecutionTools {
|
|
|
17248
17206
|
user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),
|
|
17249
17207
|
};
|
|
17250
17208
|
const start = $getCurrentDate();
|
|
17251
|
-
let complete;
|
|
17252
17209
|
if (this.options.isVerbose) {
|
|
17253
17210
|
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
17254
17211
|
}
|
|
@@ -17264,6 +17221,7 @@ class OpenAiExecutionTools {
|
|
|
17264
17221
|
if (this.options.isVerbose) {
|
|
17265
17222
|
console.info(colors.bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
17266
17223
|
}
|
|
17224
|
+
const complete = $getCurrentDate();
|
|
17267
17225
|
if (!rawResponse.choices[0]) {
|
|
17268
17226
|
throw new PipelineExecutionError('No choises from OpenAI');
|
|
17269
17227
|
}
|
|
@@ -17272,8 +17230,6 @@ class OpenAiExecutionTools {
|
|
|
17272
17230
|
throw new PipelineExecutionError('More than one choise from OpenAI');
|
|
17273
17231
|
}
|
|
17274
17232
|
const resultContent = rawResponse.choices[0].message.content;
|
|
17275
|
-
// eslint-disable-next-line prefer-const
|
|
17276
|
-
complete = $getCurrentDate();
|
|
17277
17233
|
const usage = computeOpenAiUsage(content || '', resultContent || '', rawResponse);
|
|
17278
17234
|
if (resultContent === null) {
|
|
17279
17235
|
throw new PipelineExecutionError('No response message from OpenAI');
|
|
@@ -17327,7 +17283,6 @@ class OpenAiExecutionTools {
|
|
|
17327
17283
|
user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),
|
|
17328
17284
|
};
|
|
17329
17285
|
const start = $getCurrentDate();
|
|
17330
|
-
let complete;
|
|
17331
17286
|
if (this.options.isVerbose) {
|
|
17332
17287
|
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
17333
17288
|
}
|
|
@@ -17343,6 +17298,7 @@ class OpenAiExecutionTools {
|
|
|
17343
17298
|
if (this.options.isVerbose) {
|
|
17344
17299
|
console.info(colors.bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
17345
17300
|
}
|
|
17301
|
+
const complete = $getCurrentDate();
|
|
17346
17302
|
if (!rawResponse.choices[0]) {
|
|
17347
17303
|
throw new PipelineExecutionError('No choises from OpenAI');
|
|
17348
17304
|
}
|
|
@@ -17351,8 +17307,6 @@ class OpenAiExecutionTools {
|
|
|
17351
17307
|
throw new PipelineExecutionError('More than one choise from OpenAI');
|
|
17352
17308
|
}
|
|
17353
17309
|
const resultContent = rawResponse.choices[0].text;
|
|
17354
|
-
// eslint-disable-next-line prefer-const
|
|
17355
|
-
complete = $getCurrentDate();
|
|
17356
17310
|
const usage = computeOpenAiUsage(content || '', resultContent || '', rawResponse);
|
|
17357
17311
|
return exportJson({
|
|
17358
17312
|
name: 'promptResult',
|
|
@@ -17393,7 +17347,6 @@ class OpenAiExecutionTools {
|
|
|
17393
17347
|
model: modelName,
|
|
17394
17348
|
};
|
|
17395
17349
|
const start = $getCurrentDate();
|
|
17396
|
-
let complete;
|
|
17397
17350
|
if (this.options.isVerbose) {
|
|
17398
17351
|
console.info(colors.bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
17399
17352
|
}
|
|
@@ -17409,12 +17362,11 @@ class OpenAiExecutionTools {
|
|
|
17409
17362
|
if (this.options.isVerbose) {
|
|
17410
17363
|
console.info(colors.bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
17411
17364
|
}
|
|
17365
|
+
const complete = $getCurrentDate();
|
|
17412
17366
|
if (rawResponse.data.length !== 1) {
|
|
17413
17367
|
throw new PipelineExecutionError(`Expected exactly 1 data item in response, got ${rawResponse.data.length}`);
|
|
17414
17368
|
}
|
|
17415
17369
|
const resultContent = rawResponse.data[0].embedding;
|
|
17416
|
-
// eslint-disable-next-line prefer-const
|
|
17417
|
-
complete = $getCurrentDate();
|
|
17418
17370
|
const usage = computeOpenAiUsage(content || '', '',
|
|
17419
17371
|
// <- Note: Embedding does not have result content
|
|
17420
17372
|
rawResponse);
|
|
@@ -17442,7 +17394,8 @@ class OpenAiExecutionTools {
|
|
|
17442
17394
|
* Get the model that should be used as default
|
|
17443
17395
|
*/
|
|
17444
17396
|
getDefaultModel(defaultModelName) {
|
|
17445
|
-
|
|
17397
|
+
// Note: Match exact or prefix for model families
|
|
17398
|
+
const model = OPENAI_MODELS.find(({ modelName }) => modelName === defaultModelName || modelName.startsWith(defaultModelName));
|
|
17446
17399
|
if (model === undefined) {
|
|
17447
17400
|
throw new UnexpectedError(spaceTrim((block) => `
|
|
17448
17401
|
Cannot find model in OpenAI models with name "${defaultModelName}" which should be used as default.
|