@promptbook/ollama 0.94.0-1 → 0.94.0-13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/esm/index.es.js +1965 -166
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/ollama.index.d.ts +6 -0
- package/esm/typings/src/_packages/openai.index.d.ts +2 -0
- package/esm/typings/src/execution/AvailableModel.d.ts +9 -1
- package/esm/typings/src/llm-providers/_common/filterModels.d.ts +2 -2
- package/esm/typings/src/llm-providers/{openai/computeUsage.d.ts → _common/utils/pricing.d.ts} +2 -2
- package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/azure-openai/AzureOpenAiExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/deepseek/DeepseekExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/google/GoogleExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +36 -11
- package/esm/typings/src/llm-providers/ollama/OllamaExecutionToolsOptions.d.ts +23 -12
- package/esm/typings/src/llm-providers/ollama/createOllamaExecutionTools.d.ts +3 -3
- package/esm/typings/src/llm-providers/ollama/ollama-models.d.ts +14 -0
- package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionTools.d.ts +91 -0
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionTools.d.ts +12 -53
- package/esm/typings/src/llm-providers/openai/OpenAiExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/createOpenAiExecutionTools.d.ts +2 -0
- package/esm/typings/src/llm-providers/openai/openai-models.d.ts +1 -7
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +27 -2
- package/umd/index.umd.js +1969 -168
- package/umd/index.umd.js.map +1 -1
- /package/esm/typings/src/llm-providers/{openai/computeUsage.test.d.ts → _common/utils/pricing.test.d.ts} +0 -0
package/umd/index.umd.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-ollama"] = {}, global.
|
|
5
|
-
})(this, (function (exports,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('spacetrim'), require('crypto'), require('bottleneck'), require('colors'), require('openai')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'spacetrim', 'crypto', 'bottleneck', 'colors', 'openai'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-ollama"] = {}, global.spaceTrim, global.crypto, global.Bottleneck, global.colors, global.OpenAI));
|
|
5
|
+
})(this, (function (exports, spaceTrim, crypto, Bottleneck, colors, OpenAI) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
9
|
-
var Bottleneck__default = /*#__PURE__*/_interopDefaultLegacy(Bottleneck);
|
|
10
|
-
var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
|
|
11
9
|
var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
|
|
10
|
+
var Bottleneck__default = /*#__PURE__*/_interopDefaultLegacy(Bottleneck);
|
|
11
|
+
var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
|
|
12
|
+
var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);
|
|
12
13
|
|
|
13
14
|
// ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
|
|
14
15
|
/**
|
|
@@ -24,12 +25,122 @@
|
|
|
24
25
|
* @generated
|
|
25
26
|
* @see https://github.com/webgptorg/promptbook
|
|
26
27
|
*/
|
|
27
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.94.0-
|
|
28
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.94.0-13';
|
|
28
29
|
/**
|
|
29
30
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
30
31
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
31
32
|
*/
|
|
32
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Freezes the given object and all its nested objects recursively
|
|
36
|
+
*
|
|
37
|
+
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
38
|
+
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
39
|
+
*
|
|
40
|
+
* @returns The same object as the input, but deeply frozen
|
|
41
|
+
* @public exported from `@promptbook/utils`
|
|
42
|
+
*/
|
|
43
|
+
function $deepFreeze(objectValue) {
|
|
44
|
+
if (Array.isArray(objectValue)) {
|
|
45
|
+
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
46
|
+
}
|
|
47
|
+
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
48
|
+
for (const propertyName of propertyNames) {
|
|
49
|
+
const value = objectValue[propertyName];
|
|
50
|
+
if (value && typeof value === 'object') {
|
|
51
|
+
$deepFreeze(value);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
Object.freeze(objectValue);
|
|
55
|
+
return objectValue;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Represents the uncertain value
|
|
63
|
+
*
|
|
64
|
+
* @public exported from `@promptbook/core`
|
|
65
|
+
*/
|
|
66
|
+
const ZERO_VALUE = $deepFreeze({ value: 0 });
|
|
67
|
+
/**
|
|
68
|
+
* Represents the uncertain value
|
|
69
|
+
*
|
|
70
|
+
* @public exported from `@promptbook/core`
|
|
71
|
+
*/
|
|
72
|
+
const UNCERTAIN_ZERO_VALUE = $deepFreeze({ value: 0, isUncertain: true });
|
|
73
|
+
/**
|
|
74
|
+
* Represents the usage with no resources consumed
|
|
75
|
+
*
|
|
76
|
+
* @public exported from `@promptbook/core`
|
|
77
|
+
*/
|
|
78
|
+
$deepFreeze({
|
|
79
|
+
price: ZERO_VALUE,
|
|
80
|
+
input: {
|
|
81
|
+
tokensCount: ZERO_VALUE,
|
|
82
|
+
charactersCount: ZERO_VALUE,
|
|
83
|
+
wordsCount: ZERO_VALUE,
|
|
84
|
+
sentencesCount: ZERO_VALUE,
|
|
85
|
+
linesCount: ZERO_VALUE,
|
|
86
|
+
paragraphsCount: ZERO_VALUE,
|
|
87
|
+
pagesCount: ZERO_VALUE,
|
|
88
|
+
},
|
|
89
|
+
output: {
|
|
90
|
+
tokensCount: ZERO_VALUE,
|
|
91
|
+
charactersCount: ZERO_VALUE,
|
|
92
|
+
wordsCount: ZERO_VALUE,
|
|
93
|
+
sentencesCount: ZERO_VALUE,
|
|
94
|
+
linesCount: ZERO_VALUE,
|
|
95
|
+
paragraphsCount: ZERO_VALUE,
|
|
96
|
+
pagesCount: ZERO_VALUE,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* Represents the usage with unknown resources consumed
|
|
101
|
+
*
|
|
102
|
+
* @public exported from `@promptbook/core`
|
|
103
|
+
*/
|
|
104
|
+
$deepFreeze({
|
|
105
|
+
price: UNCERTAIN_ZERO_VALUE,
|
|
106
|
+
input: {
|
|
107
|
+
tokensCount: UNCERTAIN_ZERO_VALUE,
|
|
108
|
+
charactersCount: UNCERTAIN_ZERO_VALUE,
|
|
109
|
+
wordsCount: UNCERTAIN_ZERO_VALUE,
|
|
110
|
+
sentencesCount: UNCERTAIN_ZERO_VALUE,
|
|
111
|
+
linesCount: UNCERTAIN_ZERO_VALUE,
|
|
112
|
+
paragraphsCount: UNCERTAIN_ZERO_VALUE,
|
|
113
|
+
pagesCount: UNCERTAIN_ZERO_VALUE,
|
|
114
|
+
},
|
|
115
|
+
output: {
|
|
116
|
+
tokensCount: UNCERTAIN_ZERO_VALUE,
|
|
117
|
+
charactersCount: UNCERTAIN_ZERO_VALUE,
|
|
118
|
+
wordsCount: UNCERTAIN_ZERO_VALUE,
|
|
119
|
+
sentencesCount: UNCERTAIN_ZERO_VALUE,
|
|
120
|
+
linesCount: UNCERTAIN_ZERO_VALUE,
|
|
121
|
+
paragraphsCount: UNCERTAIN_ZERO_VALUE,
|
|
122
|
+
pagesCount: UNCERTAIN_ZERO_VALUE,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Orders JSON object by keys
|
|
131
|
+
*
|
|
132
|
+
* @returns The same type of object as the input re-ordered
|
|
133
|
+
* @public exported from `@promptbook/utils`
|
|
134
|
+
*/
|
|
135
|
+
function orderJson(options) {
|
|
136
|
+
const { value, order } = options;
|
|
137
|
+
const orderedValue = {
|
|
138
|
+
...(order === undefined ? {} : Object.fromEntries(order.map((key) => [key, undefined]))),
|
|
139
|
+
...value,
|
|
140
|
+
};
|
|
141
|
+
return orderedValue;
|
|
142
|
+
}
|
|
143
|
+
|
|
33
144
|
/**
|
|
34
145
|
* Name for the Promptbook
|
|
35
146
|
*
|
|
@@ -50,6 +161,34 @@
|
|
|
50
161
|
* @public exported from `@promptbook/core`
|
|
51
162
|
*/
|
|
52
163
|
const ADMIN_GITHUB_NAME = 'hejny';
|
|
164
|
+
// <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
|
|
165
|
+
/**
|
|
166
|
+
* The maximum number of iterations for a loops
|
|
167
|
+
*
|
|
168
|
+
* @private within the repository - too low-level in comparison with other `MAX_...`
|
|
169
|
+
*/
|
|
170
|
+
const LOOP_LIMIT = 1000;
|
|
171
|
+
/**
|
|
172
|
+
* Strings to represent various values in the context of parameter values
|
|
173
|
+
*
|
|
174
|
+
* @public exported from `@promptbook/utils`
|
|
175
|
+
*/
|
|
176
|
+
const VALUE_STRINGS = {
|
|
177
|
+
empty: '(nothing; empty string)',
|
|
178
|
+
null: '(no value; null)',
|
|
179
|
+
undefined: '(unknown value; undefined)',
|
|
180
|
+
nan: '(not a number; NaN)',
|
|
181
|
+
infinity: '(infinity; ∞)',
|
|
182
|
+
negativeInfinity: '(negative infinity; -∞)',
|
|
183
|
+
unserializable: '(unserializable value)',
|
|
184
|
+
circular: '(circular JSON)',
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Small number limit
|
|
188
|
+
*
|
|
189
|
+
* @public exported from `@promptbook/utils`
|
|
190
|
+
*/
|
|
191
|
+
const SMALL_NUMBER = 0.001;
|
|
53
192
|
// <- TODO: [🧜♂️]
|
|
54
193
|
/**
|
|
55
194
|
* Default settings for parsing and generating CSV files in Promptbook.
|
|
@@ -75,40 +214,6 @@
|
|
|
75
214
|
* TODO: [🧠][🧜♂️] Maybe join remoteServerUrl and path into single value
|
|
76
215
|
*/
|
|
77
216
|
|
|
78
|
-
/**
|
|
79
|
-
* Generates random token
|
|
80
|
-
*
|
|
81
|
-
* Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
|
|
82
|
-
*
|
|
83
|
-
* @private internal helper function
|
|
84
|
-
* @returns secure random token
|
|
85
|
-
*/
|
|
86
|
-
function $randomToken(randomness) {
|
|
87
|
-
return crypto.randomBytes(randomness).toString('hex');
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* TODO: Maybe use nanoid instead https://github.com/ai/nanoid
|
|
91
|
-
*/
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* This error indicates errors during the execution of the pipeline
|
|
95
|
-
*
|
|
96
|
-
* @public exported from `@promptbook/core`
|
|
97
|
-
*/
|
|
98
|
-
class PipelineExecutionError extends Error {
|
|
99
|
-
constructor(message) {
|
|
100
|
-
// Added id parameter
|
|
101
|
-
super(message);
|
|
102
|
-
this.name = 'PipelineExecutionError';
|
|
103
|
-
// TODO: [🐙] DRY - Maybe $randomId
|
|
104
|
-
this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts */)}`;
|
|
105
|
-
Object.setPrototypeOf(this, PipelineExecutionError.prototype);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* TODO: [🧠][🌂] Add id to all errors
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
217
|
/**
|
|
113
218
|
* Make error report URL for the given error
|
|
114
219
|
*
|
|
@@ -177,60 +282,6 @@
|
|
|
177
282
|
}
|
|
178
283
|
}
|
|
179
284
|
|
|
180
|
-
/**
|
|
181
|
-
* Simple wrapper `new Date().toISOString()`
|
|
182
|
-
*
|
|
183
|
-
* Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
|
|
184
|
-
*
|
|
185
|
-
* @returns string_date branded type
|
|
186
|
-
* @public exported from `@promptbook/utils`
|
|
187
|
-
*/
|
|
188
|
-
function $getCurrentDate() {
|
|
189
|
-
return new Date().toISOString();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Orders JSON object by keys
|
|
194
|
-
*
|
|
195
|
-
* @returns The same type of object as the input re-ordered
|
|
196
|
-
* @public exported from `@promptbook/utils`
|
|
197
|
-
*/
|
|
198
|
-
function orderJson(options) {
|
|
199
|
-
const { value, order } = options;
|
|
200
|
-
const orderedValue = {
|
|
201
|
-
...(order === undefined ? {} : Object.fromEntries(order.map((key) => [key, undefined]))),
|
|
202
|
-
...value,
|
|
203
|
-
};
|
|
204
|
-
return orderedValue;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Freezes the given object and all its nested objects recursively
|
|
209
|
-
*
|
|
210
|
-
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
211
|
-
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
212
|
-
*
|
|
213
|
-
* @returns The same object as the input, but deeply frozen
|
|
214
|
-
* @public exported from `@promptbook/utils`
|
|
215
|
-
*/
|
|
216
|
-
function $deepFreeze(objectValue) {
|
|
217
|
-
if (Array.isArray(objectValue)) {
|
|
218
|
-
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
219
|
-
}
|
|
220
|
-
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
221
|
-
for (const propertyName of propertyNames) {
|
|
222
|
-
const value = objectValue[propertyName];
|
|
223
|
-
if (value && typeof value === 'object') {
|
|
224
|
-
$deepFreeze(value);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
Object.freeze(objectValue);
|
|
228
|
-
return objectValue;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
232
|
-
*/
|
|
233
|
-
|
|
234
285
|
/**
|
|
235
286
|
* This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`
|
|
236
287
|
*
|
|
@@ -479,89 +530,1837 @@
|
|
|
479
530
|
*/
|
|
480
531
|
|
|
481
532
|
/**
|
|
482
|
-
*
|
|
533
|
+
* Nonce which is used for replacing things in strings
|
|
483
534
|
*
|
|
484
|
-
* @
|
|
535
|
+
* @private within the repository
|
|
485
536
|
*/
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
537
|
+
const REPLACING_NONCE = 'ptbkauk42kV2dzao34faw7FudQUHYPtW';
|
|
538
|
+
/**
|
|
539
|
+
* Nonce which is used as string which is not occurring in normal text
|
|
540
|
+
*
|
|
541
|
+
* @private within the repository
|
|
542
|
+
*/
|
|
543
|
+
const SALT_NONCE = 'ptbkghhewbvruets21t54et5';
|
|
544
|
+
/**
|
|
545
|
+
* Placeholder value indicating a parameter is missing its value.
|
|
546
|
+
*
|
|
547
|
+
* @private within the repository
|
|
548
|
+
*/
|
|
549
|
+
const RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
550
|
+
/**
|
|
551
|
+
* Placeholder value indicating a parameter is restricted and cannot be used directly.
|
|
552
|
+
*
|
|
553
|
+
* @private within the repository
|
|
554
|
+
*/
|
|
555
|
+
const RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
556
|
+
/**
|
|
557
|
+
* The names of the parameters that are reserved for special purposes
|
|
558
|
+
*
|
|
559
|
+
* @public exported from `@promptbook/core`
|
|
560
|
+
*/
|
|
561
|
+
exportJson({
|
|
562
|
+
name: 'RESERVED_PARAMETER_NAMES',
|
|
563
|
+
message: `The names of the parameters that are reserved for special purposes`,
|
|
564
|
+
value: [
|
|
565
|
+
'content',
|
|
566
|
+
'context',
|
|
567
|
+
'knowledge',
|
|
568
|
+
'examples',
|
|
569
|
+
'modelName',
|
|
570
|
+
'currentDate',
|
|
571
|
+
// <- TODO: list here all command names
|
|
572
|
+
// <- TODO: Add more like 'date', 'modelName',...
|
|
573
|
+
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
574
|
+
],
|
|
575
|
+
});
|
|
576
|
+
/**
|
|
577
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
578
|
+
*/
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Generates random token
|
|
582
|
+
*
|
|
583
|
+
* Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
|
|
584
|
+
*
|
|
585
|
+
* @private internal helper function
|
|
586
|
+
* @returns secure random token
|
|
587
|
+
*/
|
|
588
|
+
function $randomToken(randomness) {
|
|
589
|
+
return crypto.randomBytes(randomness).toString('hex');
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* TODO: Maybe use nanoid instead https://github.com/ai/nanoid
|
|
593
|
+
*/
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* This error indicates errors during the execution of the pipeline
|
|
597
|
+
*
|
|
598
|
+
* @public exported from `@promptbook/core`
|
|
599
|
+
*/
|
|
600
|
+
class PipelineExecutionError extends Error {
|
|
601
|
+
constructor(message) {
|
|
602
|
+
// Added id parameter
|
|
603
|
+
super(message);
|
|
604
|
+
this.name = 'PipelineExecutionError';
|
|
605
|
+
// TODO: [🐙] DRY - Maybe $randomId
|
|
606
|
+
this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts */)}`;
|
|
607
|
+
Object.setPrototypeOf(this, PipelineExecutionError.prototype);
|
|
556
608
|
}
|
|
557
609
|
}
|
|
610
|
+
/**
|
|
611
|
+
* TODO: [🧠][🌂] Add id to all errors
|
|
612
|
+
*/
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Counts number of characters in the text
|
|
616
|
+
*
|
|
617
|
+
* @public exported from `@promptbook/utils`
|
|
618
|
+
*/
|
|
619
|
+
function countCharacters(text) {
|
|
620
|
+
// Remove null characters
|
|
621
|
+
text = text.replace(/\0/g, '');
|
|
622
|
+
// Replace emojis (and also ZWJ sequence) with hyphens
|
|
623
|
+
text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
|
|
624
|
+
text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
|
|
625
|
+
text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
|
|
626
|
+
return text.length;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
630
|
+
*/
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Number of characters per standard line with 11pt Arial font size.
|
|
634
|
+
*
|
|
635
|
+
* @public exported from `@promptbook/utils`
|
|
636
|
+
*/
|
|
637
|
+
const CHARACTERS_PER_STANDARD_LINE = 63;
|
|
638
|
+
/**
|
|
639
|
+
* Number of lines per standard A4 page with 11pt Arial font size and standard margins and spacing.
|
|
640
|
+
*
|
|
641
|
+
* @public exported from `@promptbook/utils`
|
|
642
|
+
*/
|
|
643
|
+
const LINES_PER_STANDARD_PAGE = 44;
|
|
644
|
+
/**
|
|
645
|
+
* TODO: [🧠] Should be this `constants.ts` or `config.ts`?
|
|
646
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
647
|
+
*/
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Counts number of lines in the text
|
|
651
|
+
*
|
|
652
|
+
* Note: This does not check only for the presence of newlines, but also for the length of the standard line.
|
|
653
|
+
*
|
|
654
|
+
* @public exported from `@promptbook/utils`
|
|
655
|
+
*/
|
|
656
|
+
function countLines(text) {
|
|
657
|
+
text = text.replace('\r\n', '\n');
|
|
658
|
+
text = text.replace('\r', '\n');
|
|
659
|
+
const lines = text.split('\n');
|
|
660
|
+
return lines.reduce((count, line) => count + Math.ceil(line.length / CHARACTERS_PER_STANDARD_LINE), 0);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
664
|
+
*/
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Counts number of pages in the text
|
|
668
|
+
*
|
|
669
|
+
* Note: This does not check only for the count of newlines, but also for the length of the standard line and length of the standard page.
|
|
670
|
+
*
|
|
671
|
+
* @public exported from `@promptbook/utils`
|
|
672
|
+
*/
|
|
673
|
+
function countPages(text) {
|
|
674
|
+
return Math.ceil(countLines(text) / LINES_PER_STANDARD_PAGE);
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
678
|
+
*/
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Counts number of paragraphs in the text
|
|
682
|
+
*
|
|
683
|
+
* @public exported from `@promptbook/utils`
|
|
684
|
+
*/
|
|
685
|
+
function countParagraphs(text) {
|
|
686
|
+
return text.split(/\n\s*\n/).filter((paragraph) => paragraph.trim() !== '').length;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
690
|
+
*/
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Split text into sentences
|
|
694
|
+
*
|
|
695
|
+
* @public exported from `@promptbook/utils`
|
|
696
|
+
*/
|
|
697
|
+
function splitIntoSentences(text) {
|
|
698
|
+
return text.split(/[.!?]+/).filter((sentence) => sentence.trim() !== '');
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Counts number of sentences in the text
|
|
702
|
+
*
|
|
703
|
+
* @public exported from `@promptbook/utils`
|
|
704
|
+
*/
|
|
705
|
+
function countSentences(text) {
|
|
706
|
+
return splitIntoSentences(text).length;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
710
|
+
*/
|
|
711
|
+
|
|
712
|
+
const defaultDiacriticsRemovalMap = [
|
|
713
|
+
{
|
|
714
|
+
base: 'A',
|
|
715
|
+
letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F',
|
|
716
|
+
},
|
|
717
|
+
{ base: 'AA', letters: '\uA732' },
|
|
718
|
+
{ base: 'AE', letters: '\u00C6\u01FC\u01E2' },
|
|
719
|
+
{ base: 'AO', letters: '\uA734' },
|
|
720
|
+
{ base: 'AU', letters: '\uA736' },
|
|
721
|
+
{ base: 'AV', letters: '\uA738\uA73A' },
|
|
722
|
+
{ base: 'AY', letters: '\uA73C' },
|
|
723
|
+
{
|
|
724
|
+
base: 'B',
|
|
725
|
+
letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181',
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
base: 'C',
|
|
729
|
+
letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E',
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
base: 'D',
|
|
733
|
+
letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0',
|
|
734
|
+
},
|
|
735
|
+
{ base: 'DZ', letters: '\u01F1\u01C4' },
|
|
736
|
+
{ base: 'Dz', letters: '\u01F2\u01C5' },
|
|
737
|
+
{
|
|
738
|
+
base: 'E',
|
|
739
|
+
letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E',
|
|
740
|
+
},
|
|
741
|
+
{ base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
|
|
742
|
+
{
|
|
743
|
+
base: 'G',
|
|
744
|
+
letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E',
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
base: 'H',
|
|
748
|
+
letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D',
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
base: 'I',
|
|
752
|
+
letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197',
|
|
753
|
+
},
|
|
754
|
+
{ base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
|
|
755
|
+
{
|
|
756
|
+
base: 'K',
|
|
757
|
+
letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2',
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
base: 'L',
|
|
761
|
+
letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780',
|
|
762
|
+
},
|
|
763
|
+
{ base: 'LJ', letters: '\u01C7' },
|
|
764
|
+
{ base: 'Lj', letters: '\u01C8' },
|
|
765
|
+
{ base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
|
|
766
|
+
{
|
|
767
|
+
base: 'N',
|
|
768
|
+
letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4',
|
|
769
|
+
},
|
|
770
|
+
{ base: 'NJ', letters: '\u01CA' },
|
|
771
|
+
{ base: 'Nj', letters: '\u01CB' },
|
|
772
|
+
{
|
|
773
|
+
base: 'O',
|
|
774
|
+
letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C',
|
|
775
|
+
},
|
|
776
|
+
{ base: 'OI', letters: '\u01A2' },
|
|
777
|
+
{ base: 'OO', letters: '\uA74E' },
|
|
778
|
+
{ base: 'OU', letters: '\u0222' },
|
|
779
|
+
{ base: 'OE', letters: '\u008C\u0152' },
|
|
780
|
+
{ base: 'oe', letters: '\u009C\u0153' },
|
|
781
|
+
{
|
|
782
|
+
base: 'P',
|
|
783
|
+
letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754',
|
|
784
|
+
},
|
|
785
|
+
{ base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
|
|
786
|
+
{
|
|
787
|
+
base: 'R',
|
|
788
|
+
letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782',
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
base: 'S',
|
|
792
|
+
letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784',
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
base: 'T',
|
|
796
|
+
letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786',
|
|
797
|
+
},
|
|
798
|
+
{ base: 'TZ', letters: '\uA728' },
|
|
799
|
+
{
|
|
800
|
+
base: 'U',
|
|
801
|
+
letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244',
|
|
802
|
+
},
|
|
803
|
+
{ base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
|
|
804
|
+
{ base: 'VY', letters: '\uA760' },
|
|
805
|
+
{
|
|
806
|
+
base: 'W',
|
|
807
|
+
letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72',
|
|
808
|
+
},
|
|
809
|
+
{ base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
|
|
810
|
+
{
|
|
811
|
+
base: 'Y',
|
|
812
|
+
letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE',
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
base: 'Z',
|
|
816
|
+
letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762',
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
base: 'a',
|
|
820
|
+
letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250',
|
|
821
|
+
},
|
|
822
|
+
{ base: 'aa', letters: '\uA733' },
|
|
823
|
+
{ base: 'ae', letters: '\u00E6\u01FD\u01E3' },
|
|
824
|
+
{ base: 'ao', letters: '\uA735' },
|
|
825
|
+
{ base: 'au', letters: '\uA737' },
|
|
826
|
+
{ base: 'av', letters: '\uA739\uA73B' },
|
|
827
|
+
{ base: 'ay', letters: '\uA73D' },
|
|
828
|
+
{
|
|
829
|
+
base: 'b',
|
|
830
|
+
letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253',
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
base: 'c',
|
|
834
|
+
letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184',
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
base: 'd',
|
|
838
|
+
letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A',
|
|
839
|
+
},
|
|
840
|
+
{ base: 'dz', letters: '\u01F3\u01C6' },
|
|
841
|
+
{
|
|
842
|
+
base: 'e',
|
|
843
|
+
letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD',
|
|
844
|
+
},
|
|
845
|
+
{ base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
|
|
846
|
+
{
|
|
847
|
+
base: 'g',
|
|
848
|
+
letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F',
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
base: 'h',
|
|
852
|
+
letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265',
|
|
853
|
+
},
|
|
854
|
+
{ base: 'hv', letters: '\u0195' },
|
|
855
|
+
{
|
|
856
|
+
base: 'i',
|
|
857
|
+
letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131',
|
|
858
|
+
},
|
|
859
|
+
{ base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
|
|
860
|
+
{
|
|
861
|
+
base: 'k',
|
|
862
|
+
letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3',
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
base: 'l',
|
|
866
|
+
letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747',
|
|
867
|
+
},
|
|
868
|
+
{ base: 'lj', letters: '\u01C9' },
|
|
869
|
+
{ base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
|
|
870
|
+
{
|
|
871
|
+
base: 'n',
|
|
872
|
+
letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5',
|
|
873
|
+
},
|
|
874
|
+
{ base: 'nj', letters: '\u01CC' },
|
|
875
|
+
{
|
|
876
|
+
base: 'o',
|
|
877
|
+
letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275',
|
|
878
|
+
},
|
|
879
|
+
{ base: 'oi', letters: '\u01A3' },
|
|
880
|
+
{ base: 'ou', letters: '\u0223' },
|
|
881
|
+
{ base: 'oo', letters: '\uA74F' },
|
|
882
|
+
{
|
|
883
|
+
base: 'p',
|
|
884
|
+
letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755',
|
|
885
|
+
},
|
|
886
|
+
{ base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
|
|
887
|
+
{
|
|
888
|
+
base: 'r',
|
|
889
|
+
letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783',
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
base: 's',
|
|
893
|
+
letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B',
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
base: 't',
|
|
897
|
+
letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787',
|
|
898
|
+
},
|
|
899
|
+
{ base: 'tz', letters: '\uA729' },
|
|
900
|
+
{
|
|
901
|
+
base: 'u',
|
|
902
|
+
letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289',
|
|
903
|
+
},
|
|
904
|
+
{ base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
|
|
905
|
+
{ base: 'vy', letters: '\uA761' },
|
|
906
|
+
{
|
|
907
|
+
base: 'w',
|
|
908
|
+
letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73',
|
|
909
|
+
},
|
|
910
|
+
{ base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
|
|
911
|
+
{
|
|
912
|
+
base: 'y',
|
|
913
|
+
letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF',
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
base: 'z',
|
|
917
|
+
letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763',
|
|
918
|
+
},
|
|
919
|
+
];
|
|
920
|
+
/**
|
|
921
|
+
* Map of letters from diacritic variant to diacritless variant
|
|
922
|
+
* Contains lowercase and uppercase separatelly
|
|
923
|
+
*
|
|
924
|
+
* > "á" => "a"
|
|
925
|
+
* > "ě" => "e"
|
|
926
|
+
* > "Ă" => "A"
|
|
927
|
+
* > ...
|
|
928
|
+
*
|
|
929
|
+
* @public exported from `@promptbook/utils`
|
|
930
|
+
*/
|
|
931
|
+
const DIACRITIC_VARIANTS_LETTERS = {};
|
|
932
|
+
// tslint:disable-next-line: prefer-for-of
|
|
933
|
+
for (let i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
|
|
934
|
+
const letters = defaultDiacriticsRemovalMap[i].letters;
|
|
935
|
+
// tslint:disable-next-line: prefer-for-of
|
|
936
|
+
for (let j = 0; j < letters.length; j++) {
|
|
937
|
+
DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
// <- TODO: [🍓] Put to maker function to save execution time if not needed
|
|
941
|
+
/*
|
|
942
|
+
@see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
|
|
943
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
944
|
+
you may not use this file except in compliance with the License.
|
|
945
|
+
You may obtain a copy of the License at
|
|
946
|
+
|
|
947
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
948
|
+
|
|
949
|
+
Unless required by applicable law or agreed to in writing, software
|
|
950
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
951
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
952
|
+
See the License for the specific language governing permissions and
|
|
953
|
+
limitations under the License.
|
|
954
|
+
*/
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Removes diacritic marks (accents) from characters in a string.
|
|
958
|
+
*
|
|
959
|
+
* @param input The string containing diacritics to be normalized.
|
|
960
|
+
* @returns The string with diacritics removed or normalized.
|
|
961
|
+
* @public exported from `@promptbook/utils`
|
|
962
|
+
*/
|
|
963
|
+
function removeDiacritics(input) {
|
|
964
|
+
/*eslint no-control-regex: "off"*/
|
|
965
|
+
return input.replace(/[^\u0000-\u007E]/g, (a) => {
|
|
966
|
+
return DIACRITIC_VARIANTS_LETTERS[a] || a;
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* TODO: [Ж] Variant for cyrillic (and in general non-latin) letters
|
|
971
|
+
*/
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* Counts number of words in the text
|
|
975
|
+
*
|
|
976
|
+
* @public exported from `@promptbook/utils`
|
|
977
|
+
*/
|
|
978
|
+
function countWords(text) {
|
|
979
|
+
text = text.replace(/[\p{Extended_Pictographic}]/gu, 'a');
|
|
980
|
+
text = removeDiacritics(text);
|
|
981
|
+
// Add spaces before uppercase letters preceded by lowercase letters (for camelCase)
|
|
982
|
+
text = text.replace(/([a-z])([A-Z])/g, '$1 $2');
|
|
983
|
+
return text.split(/[^a-zа-я0-9]+/i).filter((word) => word.length > 0).length;
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
987
|
+
*/
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Helper of usage compute
|
|
991
|
+
*
|
|
992
|
+
* @param content the content of prompt or response
|
|
993
|
+
* @returns part of UsageCounts
|
|
994
|
+
*
|
|
995
|
+
* @private internal utility of LlmExecutionTools
|
|
996
|
+
*/
|
|
997
|
+
function computeUsageCounts(content) {
|
|
998
|
+
return {
|
|
999
|
+
charactersCount: { value: countCharacters(content) },
|
|
1000
|
+
wordsCount: { value: countWords(content) },
|
|
1001
|
+
sentencesCount: { value: countSentences(content) },
|
|
1002
|
+
linesCount: { value: countLines(content) },
|
|
1003
|
+
paragraphsCount: { value: countParagraphs(content) },
|
|
1004
|
+
pagesCount: { value: countPages(content) },
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Make UncertainNumber
|
|
1010
|
+
*
|
|
1011
|
+
* @param value value of the uncertain number, if `NaN` or `undefined`, it will be set to 0 and `isUncertain=true`
|
|
1012
|
+
* @param isUncertain if `true`, the value is uncertain, otherwise depends on the value
|
|
1013
|
+
*
|
|
1014
|
+
* @private utility for initializating UncertainNumber
|
|
1015
|
+
*/
|
|
1016
|
+
function uncertainNumber(value, isUncertain) {
|
|
1017
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
1018
|
+
return UNCERTAIN_ZERO_VALUE;
|
|
1019
|
+
}
|
|
1020
|
+
if (isUncertain === true) {
|
|
1021
|
+
return { value, isUncertain };
|
|
1022
|
+
}
|
|
1023
|
+
return { value };
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* Create price per one token based on the string value found on openai page
|
|
1028
|
+
*
|
|
1029
|
+
* @private within the repository, used only as internal helper for `OPENAI_MODELS`
|
|
1030
|
+
*/
|
|
1031
|
+
function pricing(value) {
|
|
1032
|
+
const [price, tokens] = value.split(' / ');
|
|
1033
|
+
return parseFloat(price.replace('$', '')) / parseFloat(tokens.replace('M tokens', '')) / 1000000;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* List of available OpenAI models with pricing
|
|
1038
|
+
*
|
|
1039
|
+
* Note: Done at 2025-05-06
|
|
1040
|
+
*
|
|
1041
|
+
* @see https://platform.openai.com/docs/models/
|
|
1042
|
+
* @see https://openai.com/api/pricing/
|
|
1043
|
+
* @public exported from `@promptbook/openai`
|
|
1044
|
+
*/
|
|
1045
|
+
const OPENAI_MODELS = exportJson({
|
|
1046
|
+
name: 'OPENAI_MODELS',
|
|
1047
|
+
value: [
|
|
1048
|
+
/*/
|
|
1049
|
+
{
|
|
1050
|
+
modelTitle: 'dall-e-3',
|
|
1051
|
+
modelName: 'dall-e-3',
|
|
1052
|
+
},
|
|
1053
|
+
/**/
|
|
1054
|
+
/*/
|
|
1055
|
+
{
|
|
1056
|
+
modelTitle: 'whisper-1',
|
|
1057
|
+
modelName: 'whisper-1',
|
|
1058
|
+
},
|
|
1059
|
+
/**/
|
|
1060
|
+
/**/
|
|
1061
|
+
{
|
|
1062
|
+
modelVariant: 'COMPLETION',
|
|
1063
|
+
modelTitle: 'davinci-002',
|
|
1064
|
+
modelName: 'davinci-002',
|
|
1065
|
+
modelDescription: 'Legacy completion model with 4K token context window. Excels at complex text generation, creative writing, and detailed content creation with strong contextual understanding. Optimized for instructions requiring nuanced outputs and extended reasoning. Suitable for applications needing high-quality text generation without conversation management.',
|
|
1066
|
+
pricing: {
|
|
1067
|
+
prompt: pricing(`$2.00 / 1M tokens`),
|
|
1068
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1069
|
+
},
|
|
1070
|
+
},
|
|
1071
|
+
/**/
|
|
1072
|
+
/*/
|
|
1073
|
+
{
|
|
1074
|
+
modelTitle: 'dall-e-2',
|
|
1075
|
+
modelName: 'dall-e-2',
|
|
1076
|
+
},
|
|
1077
|
+
/**/
|
|
1078
|
+
/**/
|
|
1079
|
+
{
|
|
1080
|
+
modelVariant: 'CHAT',
|
|
1081
|
+
modelTitle: 'gpt-3.5-turbo-16k',
|
|
1082
|
+
modelName: 'gpt-3.5-turbo-16k',
|
|
1083
|
+
modelDescription: 'Extended context GPT-3.5 Turbo with 16K token window. Maintains core capabilities of standard 3.5 Turbo while supporting longer conversations and documents. Features good balance of performance and cost for applications requiring more context than standard 4K models. Effective for document analysis, extended conversations, and multi-step reasoning tasks.',
|
|
1084
|
+
pricing: {
|
|
1085
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1086
|
+
output: pricing(`$4.00 / 1M tokens`),
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
/**/
|
|
1090
|
+
/*/
|
|
1091
|
+
{
|
|
1092
|
+
modelTitle: 'tts-1-hd-1106',
|
|
1093
|
+
modelName: 'tts-1-hd-1106',
|
|
1094
|
+
},
|
|
1095
|
+
/**/
|
|
1096
|
+
/*/
|
|
1097
|
+
{
|
|
1098
|
+
modelTitle: 'tts-1-hd',
|
|
1099
|
+
modelName: 'tts-1-hd',
|
|
1100
|
+
},
|
|
1101
|
+
/**/
|
|
1102
|
+
/**/
|
|
1103
|
+
{
|
|
1104
|
+
modelVariant: 'CHAT',
|
|
1105
|
+
modelTitle: 'gpt-4',
|
|
1106
|
+
modelName: 'gpt-4',
|
|
1107
|
+
modelDescription: 'Powerful language model with 8K context window featuring sophisticated reasoning, instruction-following, and knowledge capabilities. Demonstrates strong performance on complex tasks requiring deep understanding and multi-step reasoning. Excels at code generation, logical analysis, and nuanced content creation. Suitable for advanced applications requiring high-quality outputs.',
|
|
1108
|
+
pricing: {
|
|
1109
|
+
prompt: pricing(`$30.00 / 1M tokens`),
|
|
1110
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1111
|
+
},
|
|
1112
|
+
},
|
|
1113
|
+
/**/
|
|
1114
|
+
/**/
|
|
1115
|
+
{
|
|
1116
|
+
modelVariant: 'CHAT',
|
|
1117
|
+
modelTitle: 'gpt-4-32k',
|
|
1118
|
+
modelName: 'gpt-4-32k',
|
|
1119
|
+
modelDescription: 'Extended context version of GPT-4 with 32K token window. Maintains all capabilities of standard GPT-4 while supporting analysis of very lengthy documents, code bases, and conversations. Features enhanced ability to maintain context over long interactions and process detailed information from large inputs. Ideal for document analysis, legal review, and complex problem-solving.',
|
|
1120
|
+
pricing: {
|
|
1121
|
+
prompt: pricing(`$60.00 / 1M tokens`),
|
|
1122
|
+
output: pricing(`$120.00 / 1M tokens`),
|
|
1123
|
+
},
|
|
1124
|
+
},
|
|
1125
|
+
/**/
|
|
1126
|
+
/*/
|
|
1127
|
+
{
|
|
1128
|
+
modelVariant: 'CHAT',
|
|
1129
|
+
modelTitle: 'gpt-4-0613',
|
|
1130
|
+
modelName: 'gpt-4-0613',
|
|
1131
|
+
pricing: {
|
|
1132
|
+
prompt: computeUsage(` / 1M tokens`),
|
|
1133
|
+
output: computeUsage(` / 1M tokens`),
|
|
1134
|
+
},
|
|
1135
|
+
},
|
|
1136
|
+
/**/
|
|
1137
|
+
/**/
|
|
1138
|
+
{
|
|
1139
|
+
modelVariant: 'CHAT',
|
|
1140
|
+
modelTitle: 'gpt-4-turbo-2024-04-09',
|
|
1141
|
+
modelName: 'gpt-4-turbo-2024-04-09',
|
|
1142
|
+
modelDescription: 'Latest stable GPT-4 Turbo from April 2024 with 128K context window. Features enhanced reasoning chains, improved factual accuracy with 40% reduction in hallucinations, and better instruction following compared to earlier versions. Includes advanced function calling capabilities and knowledge up to April 2024. Provides optimal performance for enterprise applications requiring reliability.',
|
|
1143
|
+
pricing: {
|
|
1144
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1145
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1146
|
+
},
|
|
1147
|
+
},
|
|
1148
|
+
/**/
|
|
1149
|
+
/**/
|
|
1150
|
+
{
|
|
1151
|
+
modelVariant: 'CHAT',
|
|
1152
|
+
modelTitle: 'gpt-3.5-turbo-1106',
|
|
1153
|
+
modelName: 'gpt-3.5-turbo-1106',
|
|
1154
|
+
modelDescription: 'November 2023 version of GPT-3.5 Turbo with 16K token context window. Features improved instruction following, more consistent output formatting, and enhanced function calling capabilities. Includes knowledge cutoff from April 2023. Suitable for applications requiring good performance at lower cost than GPT-4 models.',
|
|
1155
|
+
pricing: {
|
|
1156
|
+
prompt: pricing(`$1.00 / 1M tokens`),
|
|
1157
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1158
|
+
},
|
|
1159
|
+
},
|
|
1160
|
+
/**/
|
|
1161
|
+
/**/
|
|
1162
|
+
{
|
|
1163
|
+
modelVariant: 'CHAT',
|
|
1164
|
+
modelTitle: 'gpt-4-turbo',
|
|
1165
|
+
modelName: 'gpt-4-turbo',
|
|
1166
|
+
modelDescription: 'More capable and cost-efficient version of GPT-4 with 128K token context window. Features improved instruction following, advanced function calling capabilities, and better performance on coding tasks. Maintains superior reasoning and knowledge while offering substantial cost reduction compared to base GPT-4. Ideal for complex applications requiring extensive context processing.',
|
|
1167
|
+
pricing: {
|
|
1168
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1169
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1170
|
+
},
|
|
1171
|
+
},
|
|
1172
|
+
/**/
|
|
1173
|
+
/**/
|
|
1174
|
+
{
|
|
1175
|
+
modelVariant: 'COMPLETION',
|
|
1176
|
+
modelTitle: 'gpt-3.5-turbo-instruct-0914',
|
|
1177
|
+
modelName: 'gpt-3.5-turbo-instruct-0914',
|
|
1178
|
+
modelDescription: 'September 2023 version of GPT-3.5 Turbo Instruct with 4K context window. Optimized for completion-style instruction following with deterministic responses. Better suited than chat models for applications requiring specific formatted outputs without conversation management. Knowledge cutoff from September 2021.',
|
|
1179
|
+
pricing: {
|
|
1180
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1181
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1182
|
+
},
|
|
1183
|
+
},
|
|
1184
|
+
/**/
|
|
1185
|
+
/**/
|
|
1186
|
+
{
|
|
1187
|
+
modelVariant: 'COMPLETION',
|
|
1188
|
+
modelTitle: 'gpt-3.5-turbo-instruct',
|
|
1189
|
+
modelName: 'gpt-3.5-turbo-instruct',
|
|
1190
|
+
modelDescription: 'Optimized version of GPT-3.5 for completion-style API with 4K token context window. Features strong instruction following with single-turn design rather than multi-turn conversation. Provides more consistent, deterministic outputs compared to chat models. Well-suited for templated content generation and structured text transformation tasks.',
|
|
1191
|
+
pricing: {
|
|
1192
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1193
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1194
|
+
},
|
|
1195
|
+
},
|
|
1196
|
+
/**/
|
|
1197
|
+
/*/
|
|
1198
|
+
{
|
|
1199
|
+
modelTitle: 'tts-1',
|
|
1200
|
+
modelName: 'tts-1',
|
|
1201
|
+
},
|
|
1202
|
+
/**/
|
|
1203
|
+
/**/
|
|
1204
|
+
{
|
|
1205
|
+
modelVariant: 'CHAT',
|
|
1206
|
+
modelTitle: 'gpt-3.5-turbo',
|
|
1207
|
+
modelName: 'gpt-3.5-turbo',
|
|
1208
|
+
modelDescription: 'Latest version of GPT-3.5 Turbo with 4K token default context window (16K available). Features continually improved performance with enhanced instruction following and reduced hallucinations. Offers excellent balance between capability and cost efficiency. Suitable for most general-purpose applications requiring good AI capabilities at reasonable cost.',
|
|
1209
|
+
pricing: {
|
|
1210
|
+
prompt: pricing(`$0.50 / 1M tokens`),
|
|
1211
|
+
output: pricing(`$1.50 / 1M tokens`),
|
|
1212
|
+
},
|
|
1213
|
+
},
|
|
1214
|
+
/**/
|
|
1215
|
+
/**/
|
|
1216
|
+
{
|
|
1217
|
+
modelVariant: 'CHAT',
|
|
1218
|
+
modelTitle: 'gpt-3.5-turbo-0301',
|
|
1219
|
+
modelName: 'gpt-3.5-turbo-0301',
|
|
1220
|
+
modelDescription: 'March 2023 version of GPT-3.5 Turbo with 4K token context window. Legacy model maintained for backward compatibility with specific application behaviors. Features solid conversational abilities and basic instruction following. Knowledge cutoff from September 2021. Suitable for applications explicitly designed for this version.',
|
|
1221
|
+
pricing: {
|
|
1222
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1223
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1224
|
+
},
|
|
1225
|
+
},
|
|
1226
|
+
/**/
|
|
1227
|
+
/**/
|
|
1228
|
+
{
|
|
1229
|
+
modelVariant: 'COMPLETION',
|
|
1230
|
+
modelTitle: 'babbage-002',
|
|
1231
|
+
modelName: 'babbage-002',
|
|
1232
|
+
modelDescription: 'Efficient legacy completion model with 4K context window balancing performance and speed. Features moderate reasoning capabilities with focus on straightforward text generation tasks. Significantly more efficient than davinci models while maintaining adequate quality for many applications. Suitable for high-volume, cost-sensitive text generation needs.',
|
|
1233
|
+
pricing: {
|
|
1234
|
+
prompt: pricing(`$0.40 / 1M tokens`),
|
|
1235
|
+
output: pricing(`$0.40 / 1M tokens`),
|
|
1236
|
+
},
|
|
1237
|
+
},
|
|
1238
|
+
/**/
|
|
1239
|
+
/**/
|
|
1240
|
+
{
|
|
1241
|
+
modelVariant: 'CHAT',
|
|
1242
|
+
modelTitle: 'gpt-4-1106-preview',
|
|
1243
|
+
modelName: 'gpt-4-1106-preview',
|
|
1244
|
+
modelDescription: 'November 2023 preview version of GPT-4 Turbo with 128K token context window. Features improved instruction following, better function calling capabilities, and enhanced reasoning. Includes knowledge cutoff from April 2023. Suitable for complex applications requiring extensive document understanding and sophisticated interactions.',
|
|
1245
|
+
pricing: {
|
|
1246
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1247
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1248
|
+
},
|
|
1249
|
+
},
|
|
1250
|
+
/**/
|
|
1251
|
+
/**/
|
|
1252
|
+
{
|
|
1253
|
+
modelVariant: 'CHAT',
|
|
1254
|
+
modelTitle: 'gpt-4-0125-preview',
|
|
1255
|
+
modelName: 'gpt-4-0125-preview',
|
|
1256
|
+
modelDescription: 'January 2024 preview version of GPT-4 Turbo with 128K token context window. Features improved reasoning capabilities, enhanced tool use, and more reliable function calling. Includes knowledge cutoff from October 2023. Offers better performance on complex logical tasks and more consistent outputs than previous preview versions.',
|
|
1257
|
+
pricing: {
|
|
1258
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1259
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1260
|
+
},
|
|
1261
|
+
},
|
|
1262
|
+
/**/
|
|
1263
|
+
/*/
|
|
1264
|
+
{
|
|
1265
|
+
modelTitle: 'tts-1-1106',
|
|
1266
|
+
modelName: 'tts-1-1106',
|
|
1267
|
+
},
|
|
1268
|
+
/**/
|
|
1269
|
+
/**/
|
|
1270
|
+
{
|
|
1271
|
+
modelVariant: 'CHAT',
|
|
1272
|
+
modelTitle: 'gpt-3.5-turbo-0125',
|
|
1273
|
+
modelName: 'gpt-3.5-turbo-0125',
|
|
1274
|
+
modelDescription: 'January 2024 version of GPT-3.5 Turbo with 16K token context window. Features improved reasoning capabilities, better instruction adherence, and reduced hallucinations compared to previous versions. Includes knowledge cutoff from September 2021. Provides good performance for most general applications at reasonable cost.',
|
|
1275
|
+
pricing: {
|
|
1276
|
+
prompt: pricing(`$0.50 / 1M tokens`),
|
|
1277
|
+
output: pricing(`$1.50 / 1M tokens`),
|
|
1278
|
+
},
|
|
1279
|
+
},
|
|
1280
|
+
/**/
|
|
1281
|
+
/**/
|
|
1282
|
+
{
|
|
1283
|
+
modelVariant: 'CHAT',
|
|
1284
|
+
modelTitle: 'gpt-4-turbo-preview',
|
|
1285
|
+
modelName: 'gpt-4-turbo-preview',
|
|
1286
|
+
modelDescription: 'Preview version of GPT-4 Turbo with 128K token context window that points to the latest development model. Features cutting-edge improvements to instruction following, knowledge representation, and tool use capabilities. Provides access to newest features but may have occasional behavior changes. Best for non-critical applications wanting latest capabilities.',
|
|
1287
|
+
pricing: {
|
|
1288
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1289
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1290
|
+
},
|
|
1291
|
+
},
|
|
1292
|
+
/**/
|
|
1293
|
+
/**/
|
|
1294
|
+
{
|
|
1295
|
+
modelVariant: 'EMBEDDING',
|
|
1296
|
+
modelTitle: 'text-embedding-3-large',
|
|
1297
|
+
modelName: 'text-embedding-3-large',
|
|
1298
|
+
modelDescription: "OpenAI's most capable text embedding model generating 3072-dimensional vectors. Designed for high-quality embeddings for complex similarity tasks, clustering, and information retrieval. Features enhanced cross-lingual capabilities and significantly improved performance on retrieval and classification benchmarks. Ideal for sophisticated RAG systems and semantic search applications.",
|
|
1299
|
+
pricing: {
|
|
1300
|
+
prompt: pricing(`$0.13 / 1M tokens`),
|
|
1301
|
+
output: 0,
|
|
1302
|
+
},
|
|
1303
|
+
},
|
|
1304
|
+
/**/
|
|
1305
|
+
/**/
|
|
1306
|
+
{
|
|
1307
|
+
modelVariant: 'EMBEDDING',
|
|
1308
|
+
modelTitle: 'text-embedding-3-small',
|
|
1309
|
+
modelName: 'text-embedding-3-small',
|
|
1310
|
+
modelDescription: 'Cost-effective embedding model generating 1536-dimensional vectors. Balances quality and efficiency for simpler tasks while maintaining good performance on text similarity and retrieval applications. Offers 20% better quality than ada-002 at significantly lower cost. Ideal for production embedding applications with cost constraints.',
|
|
1311
|
+
pricing: {
|
|
1312
|
+
prompt: pricing(`$0.02 / 1M tokens`),
|
|
1313
|
+
output: 0,
|
|
1314
|
+
},
|
|
1315
|
+
},
|
|
1316
|
+
/**/
|
|
1317
|
+
/**/
|
|
1318
|
+
{
|
|
1319
|
+
modelVariant: 'CHAT',
|
|
1320
|
+
modelTitle: 'gpt-3.5-turbo-0613',
|
|
1321
|
+
modelName: 'gpt-3.5-turbo-0613',
|
|
1322
|
+
modelDescription: "June 2023 version of GPT-3.5 Turbo with 4K token context window. Features function calling capabilities for structured data extraction and API interaction. Includes knowledge cutoff from September 2021. Maintained for applications specifically designed for this version's behaviors and capabilities.",
|
|
1323
|
+
pricing: {
|
|
1324
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1325
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1326
|
+
},
|
|
1327
|
+
},
|
|
1328
|
+
/**/
|
|
1329
|
+
/**/
|
|
1330
|
+
{
|
|
1331
|
+
modelVariant: 'EMBEDDING',
|
|
1332
|
+
modelTitle: 'text-embedding-ada-002',
|
|
1333
|
+
modelName: 'text-embedding-ada-002',
|
|
1334
|
+
modelDescription: 'Legacy text embedding model generating 1536-dimensional vectors suitable for text similarity and retrieval applications. Processes up to 8K tokens per request with consistent embedding quality. While superseded by newer embedding-3 models, still maintains adequate performance for many semantic search and classification tasks.',
|
|
1335
|
+
pricing: {
|
|
1336
|
+
prompt: pricing(`$0.1 / 1M tokens`),
|
|
1337
|
+
output: 0,
|
|
1338
|
+
},
|
|
1339
|
+
},
|
|
1340
|
+
/**/
|
|
1341
|
+
/*/
|
|
1342
|
+
{
|
|
1343
|
+
modelVariant: 'CHAT',
|
|
1344
|
+
modelTitle: 'gpt-4-1106-vision-preview',
|
|
1345
|
+
modelName: 'gpt-4-1106-vision-preview',
|
|
1346
|
+
},
|
|
1347
|
+
/**/
|
|
1348
|
+
/*/
|
|
1349
|
+
{
|
|
1350
|
+
modelVariant: 'CHAT',
|
|
1351
|
+
modelTitle: 'gpt-4-vision-preview',
|
|
1352
|
+
modelName: 'gpt-4-vision-preview',
|
|
1353
|
+
pricing: {
|
|
1354
|
+
prompt: computeUsage(`$10.00 / 1M tokens`),
|
|
1355
|
+
output: computeUsage(`$30.00 / 1M tokens`),
|
|
1356
|
+
},
|
|
1357
|
+
},
|
|
1358
|
+
/**/
|
|
1359
|
+
/**/
|
|
1360
|
+
{
|
|
1361
|
+
modelVariant: 'CHAT',
|
|
1362
|
+
modelTitle: 'gpt-4o-2024-05-13',
|
|
1363
|
+
modelName: 'gpt-4o-2024-05-13',
|
|
1364
|
+
modelDescription: 'May 2024 version of GPT-4o with 128K context window. Features enhanced multimodal capabilities including superior image understanding (up to 20MP), audio processing, and improved reasoning. Optimized for 2x lower latency than GPT-4 Turbo while maintaining high performance. Includes knowledge up to October 2023. Ideal for production applications requiring reliable multimodal capabilities.',
|
|
1365
|
+
pricing: {
|
|
1366
|
+
prompt: pricing(`$5.00 / 1M tokens`),
|
|
1367
|
+
output: pricing(`$15.00 / 1M tokens`),
|
|
1368
|
+
},
|
|
1369
|
+
},
|
|
1370
|
+
/**/
|
|
1371
|
+
/**/
|
|
1372
|
+
{
|
|
1373
|
+
modelVariant: 'CHAT',
|
|
1374
|
+
modelTitle: 'gpt-4o',
|
|
1375
|
+
modelName: 'gpt-4o',
|
|
1376
|
+
modelDescription: "OpenAI's most advanced general-purpose multimodal model with 128K context window. Optimized for balanced performance, speed, and cost with 2x faster responses than GPT-4 Turbo. Features excellent vision processing, audio understanding, reasoning, and text generation quality. Represents optimal balance of capability and efficiency for most advanced applications.",
|
|
1377
|
+
pricing: {
|
|
1378
|
+
prompt: pricing(`$5.00 / 1M tokens`),
|
|
1379
|
+
output: pricing(`$15.00 / 1M tokens`),
|
|
1380
|
+
},
|
|
1381
|
+
},
|
|
1382
|
+
/**/
|
|
1383
|
+
/**/
|
|
1384
|
+
{
|
|
1385
|
+
modelVariant: 'CHAT',
|
|
1386
|
+
modelTitle: 'gpt-4o-mini',
|
|
1387
|
+
modelName: 'gpt-4o-mini',
|
|
1388
|
+
modelDescription: 'Smaller, more cost-effective version of GPT-4o with 128K context window. Maintains impressive capabilities across text, vision, and audio tasks while operating at significantly lower cost. Features 3x faster inference than GPT-4o with good performance on general tasks. Excellent for applications requiring good quality multimodal capabilities at scale.',
|
|
1389
|
+
pricing: {
|
|
1390
|
+
prompt: pricing(`$0.15 / 1M tokens`),
|
|
1391
|
+
output: pricing(`$0.60 / 1M tokens`),
|
|
1392
|
+
},
|
|
1393
|
+
},
|
|
1394
|
+
/**/
|
|
1395
|
+
/**/
|
|
1396
|
+
{
|
|
1397
|
+
modelVariant: 'CHAT',
|
|
1398
|
+
modelTitle: 'o1-preview',
|
|
1399
|
+
modelName: 'o1-preview',
|
|
1400
|
+
modelDescription: 'Advanced reasoning model with 128K context window specializing in complex logical, mathematical, and analytical tasks. Features exceptional step-by-step problem-solving capabilities, advanced mathematical and scientific reasoning, and superior performance on STEM-focused problems. Significantly outperforms GPT-4 on quantitative reasoning benchmarks. Ideal for professional and specialized applications.',
|
|
1401
|
+
pricing: {
|
|
1402
|
+
prompt: pricing(`$15.00 / 1M tokens`),
|
|
1403
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1404
|
+
},
|
|
1405
|
+
},
|
|
1406
|
+
/**/
|
|
1407
|
+
/**/
|
|
1408
|
+
{
|
|
1409
|
+
modelVariant: 'CHAT',
|
|
1410
|
+
modelTitle: 'o1-preview-2024-09-12',
|
|
1411
|
+
modelName: 'o1-preview-2024-09-12',
|
|
1412
|
+
modelDescription: 'September 2024 version of O1 preview with 128K context window. Features specialized reasoning capabilities with 30% improvement on mathematical and scientific accuracy over previous versions. Includes enhanced support for formal logic, statistical analysis, and technical domains. Optimized for professional applications requiring precise analytical thinking and rigorous methodologies.',
|
|
1413
|
+
pricing: {
|
|
1414
|
+
prompt: pricing(`$15.00 / 1M tokens`),
|
|
1415
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1416
|
+
},
|
|
1417
|
+
},
|
|
1418
|
+
/**/
|
|
1419
|
+
/**/
|
|
1420
|
+
{
|
|
1421
|
+
modelVariant: 'CHAT',
|
|
1422
|
+
modelTitle: 'o1-mini',
|
|
1423
|
+
modelName: 'o1-mini',
|
|
1424
|
+
modelDescription: 'Smaller, cost-effective version of the O1 model with 128K context window. Maintains strong analytical reasoning abilities while reducing computational requirements by 70%. Features good performance on mathematical, logical, and scientific tasks at significantly lower cost than full O1. Excellent for everyday analytical applications that benefit from reasoning focus.',
|
|
1425
|
+
pricing: {
|
|
1426
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1427
|
+
output: pricing(`$12.00 / 1M tokens`),
|
|
1428
|
+
},
|
|
1429
|
+
},
|
|
1430
|
+
/**/
|
|
1431
|
+
/**/
|
|
1432
|
+
{
|
|
1433
|
+
modelVariant: 'CHAT',
|
|
1434
|
+
modelTitle: 'o1',
|
|
1435
|
+
modelName: 'o1',
|
|
1436
|
+
modelDescription: "OpenAI's advanced reasoning model with 128K context window focusing on logical problem-solving and analytical thinking. Features exceptional performance on quantitative tasks, step-by-step deduction, and complex technical problems. Maintains 95%+ of o1-preview capabilities with production-ready stability. Ideal for scientific computing, financial analysis, and professional applications.",
|
|
1437
|
+
pricing: {
|
|
1438
|
+
prompt: pricing(`$15.00 / 1M tokens`),
|
|
1439
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1440
|
+
},
|
|
1441
|
+
},
|
|
1442
|
+
/**/
|
|
1443
|
+
/**/
|
|
1444
|
+
{
|
|
1445
|
+
modelVariant: 'CHAT',
|
|
1446
|
+
modelTitle: 'o3-mini',
|
|
1447
|
+
modelName: 'o3-mini',
|
|
1448
|
+
modelDescription: 'Cost-effective reasoning model with 128K context window optimized for academic and scientific problem-solving. Features efficient performance on STEM tasks with specialized capabilities in mathematics, physics, chemistry, and computer science. Offers 80% of O1 performance on technical domains at significantly lower cost. Ideal for educational applications and research support.',
|
|
1449
|
+
pricing: {
|
|
1450
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1451
|
+
output: pricing(`$12.00 / 1M tokens`),
|
|
1452
|
+
},
|
|
1453
|
+
},
|
|
1454
|
+
/**/
|
|
1455
|
+
/**/
|
|
1456
|
+
{
|
|
1457
|
+
modelVariant: 'CHAT',
|
|
1458
|
+
modelTitle: 'o1-mini-2024-09-12',
|
|
1459
|
+
modelName: 'o1-mini-2024-09-12',
|
|
1460
|
+
modelDescription: "September 2024 version of O1-mini with 128K context window featuring balanced reasoning capabilities and cost-efficiency. Includes 25% improvement in mathematical accuracy and enhanced performance on coding tasks compared to previous versions. Maintains efficient resource utilization while delivering improved results for analytical applications that don't require the full O1 model.",
|
|
1461
|
+
pricing: {
|
|
1462
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1463
|
+
output: pricing(`$12.00 / 1M tokens`),
|
|
1464
|
+
},
|
|
1465
|
+
},
|
|
1466
|
+
/**/
|
|
1467
|
+
/**/
|
|
1468
|
+
{
|
|
1469
|
+
modelVariant: 'CHAT',
|
|
1470
|
+
modelTitle: 'gpt-3.5-turbo-16k-0613',
|
|
1471
|
+
modelName: 'gpt-3.5-turbo-16k-0613',
|
|
1472
|
+
modelDescription: "June 2023 version of GPT-3.5 Turbo with extended 16K token context window. Features good handling of longer conversations and documents with improved memory management across extended contexts. Includes knowledge cutoff from September 2021. Maintained for applications specifically designed for this version's behaviors and capabilities.",
|
|
1473
|
+
pricing: {
|
|
1474
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1475
|
+
output: pricing(`$4.00 / 1M tokens`),
|
|
1476
|
+
},
|
|
1477
|
+
},
|
|
1478
|
+
/**/
|
|
1479
|
+
// <- [🕕]
|
|
1480
|
+
],
|
|
1481
|
+
});
|
|
1482
|
+
/**
|
|
1483
|
+
* Note: [🤖] Add models of new variant
|
|
1484
|
+
* TODO: [🧠] Some mechanism to propagate unsureness
|
|
1485
|
+
* TODO: [🎰] Some mechanism to auto-update available models
|
|
1486
|
+
* TODO: [🎰][👮♀️] Make this list dynamic - dynamically can be listed modelNames but not modelVariant, legacy status, context length and pricing
|
|
1487
|
+
* TODO: [🧠][👮♀️] Put here more info like description, isVision, trainingDateCutoff, languages, strengths ( Top-level performance, intelligence, fluency, and understanding), contextWindow,...
|
|
1488
|
+
* @see https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4
|
|
1489
|
+
* @see https://openai.com/api/pricing/
|
|
1490
|
+
* @see /other/playground/playground.ts
|
|
1491
|
+
* TODO: [🍓][💩] Make better
|
|
1492
|
+
* TODO: Change model titles to human eg: "gpt-4-turbo-2024-04-09" -> "GPT-4 Turbo (2024-04-09)"
|
|
1493
|
+
* TODO: [🚸] Not all models are compatible with JSON mode, add this information here and use it
|
|
1494
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1495
|
+
*/
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* Computes the usage of the OpenAI API based on the response from OpenAI
|
|
1499
|
+
*
|
|
1500
|
+
* @param promptContent The content of the prompt
|
|
1501
|
+
* @param resultContent The content of the result (for embedding prompts or failed prompts pass empty string)
|
|
1502
|
+
* @param rawResponse The raw response from OpenAI API
|
|
1503
|
+
* @throws {PipelineExecutionError} If the usage is not defined in the response from OpenAI
|
|
1504
|
+
* @private internal utility of `OpenAiExecutionTools`
|
|
1505
|
+
*/
|
|
1506
|
+
function computeOpenAiUsage(promptContent, // <- Note: Intentionally using [] to access type properties to bring jsdoc from Prompt/PromptResult to consumer
|
|
1507
|
+
resultContent, rawResponse) {
|
|
1508
|
+
var _a, _b;
|
|
1509
|
+
if (rawResponse.usage === undefined) {
|
|
1510
|
+
throw new PipelineExecutionError('The usage is not defined in the response from OpenAI');
|
|
1511
|
+
}
|
|
1512
|
+
if (((_a = rawResponse.usage) === null || _a === void 0 ? void 0 : _a.prompt_tokens) === undefined) {
|
|
1513
|
+
throw new PipelineExecutionError('In OpenAI response `usage.prompt_tokens` not defined');
|
|
1514
|
+
}
|
|
1515
|
+
const inputTokens = rawResponse.usage.prompt_tokens;
|
|
1516
|
+
const outputTokens = ((_b = rawResponse.usage) === null || _b === void 0 ? void 0 : _b.completion_tokens) || 0;
|
|
1517
|
+
let isUncertain = false;
|
|
1518
|
+
let modelInfo = OPENAI_MODELS.find((model) => model.modelName === rawResponse.model);
|
|
1519
|
+
if (modelInfo === undefined) {
|
|
1520
|
+
// Note: Model is not in the list of known models, fallback to the family of the models and mark price as uncertain
|
|
1521
|
+
modelInfo = OPENAI_MODELS.find((model) => (rawResponse.model || SALT_NONCE).startsWith(model.modelName));
|
|
1522
|
+
if (modelInfo !== undefined) {
|
|
1523
|
+
isUncertain = true;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
let price;
|
|
1527
|
+
if (modelInfo === undefined || modelInfo.pricing === undefined) {
|
|
1528
|
+
price = uncertainNumber();
|
|
1529
|
+
}
|
|
1530
|
+
else {
|
|
1531
|
+
price = uncertainNumber(inputTokens * modelInfo.pricing.prompt + outputTokens * modelInfo.pricing.output, isUncertain);
|
|
1532
|
+
}
|
|
1533
|
+
return {
|
|
1534
|
+
price,
|
|
1535
|
+
input: {
|
|
1536
|
+
tokensCount: uncertainNumber(rawResponse.usage.prompt_tokens),
|
|
1537
|
+
...computeUsageCounts(promptContent),
|
|
1538
|
+
},
|
|
1539
|
+
output: {
|
|
1540
|
+
tokensCount: uncertainNumber(outputTokens),
|
|
1541
|
+
...computeUsageCounts(resultContent),
|
|
1542
|
+
},
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* TODO: [🤝] DRY Maybe some common abstraction between `computeOpenAiUsage` and `computeAnthropicClaudeUsage`
|
|
1547
|
+
*/
|
|
1548
|
+
|
|
1549
|
+
/**
|
|
1550
|
+
* Simple wrapper `new Date().toISOString()`
|
|
1551
|
+
*
|
|
1552
|
+
* Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
|
|
1553
|
+
*
|
|
1554
|
+
* @returns string_date branded type
|
|
1555
|
+
* @public exported from `@promptbook/utils`
|
|
1556
|
+
*/
|
|
1557
|
+
function $getCurrentDate() {
|
|
1558
|
+
return new Date().toISOString();
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
/**
|
|
1562
|
+
* This error type indicates that some limit was reached
|
|
1563
|
+
*
|
|
1564
|
+
* @public exported from `@promptbook/core`
|
|
1565
|
+
*/
|
|
1566
|
+
class LimitReachedError extends Error {
|
|
1567
|
+
constructor(message) {
|
|
1568
|
+
super(message);
|
|
1569
|
+
this.name = 'LimitReachedError';
|
|
1570
|
+
Object.setPrototypeOf(this, LimitReachedError.prototype);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
/**
|
|
1575
|
+
* Format either small or big number
|
|
1576
|
+
*
|
|
1577
|
+
* @public exported from `@promptbook/utils`
|
|
1578
|
+
*/
|
|
1579
|
+
function numberToString(value) {
|
|
1580
|
+
if (value === 0) {
|
|
1581
|
+
return '0';
|
|
1582
|
+
}
|
|
1583
|
+
else if (Number.isNaN(value)) {
|
|
1584
|
+
return VALUE_STRINGS.nan;
|
|
1585
|
+
}
|
|
1586
|
+
else if (value === Infinity) {
|
|
1587
|
+
return VALUE_STRINGS.infinity;
|
|
1588
|
+
}
|
|
1589
|
+
else if (value === -Infinity) {
|
|
1590
|
+
return VALUE_STRINGS.negativeInfinity;
|
|
1591
|
+
}
|
|
1592
|
+
for (let exponent = 0; exponent < 15; exponent++) {
|
|
1593
|
+
const factor = 10 ** exponent;
|
|
1594
|
+
const valueRounded = Math.round(value * factor) / factor;
|
|
1595
|
+
if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
|
|
1596
|
+
return valueRounded.toFixed(exponent);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
return value.toString();
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
/**
|
|
1603
|
+
* Function `valueToString` will convert the given value to string
|
|
1604
|
+
* This is useful and used in the `templateParameters` function
|
|
1605
|
+
*
|
|
1606
|
+
* Note: This function is not just calling `toString` method
|
|
1607
|
+
* It's more complex and can handle this conversion specifically for LLM models
|
|
1608
|
+
* See `VALUE_STRINGS`
|
|
1609
|
+
*
|
|
1610
|
+
* Note: There are 2 similar functions
|
|
1611
|
+
* - `valueToString` converts value to string for LLM models as human-readable string
|
|
1612
|
+
* - `asSerializable` converts value to string to preserve full information to be able to convert it back
|
|
1613
|
+
*
|
|
1614
|
+
* @public exported from `@promptbook/utils`
|
|
1615
|
+
*/
|
|
1616
|
+
function valueToString(value) {
|
|
1617
|
+
try {
|
|
1618
|
+
if (value === '') {
|
|
1619
|
+
return VALUE_STRINGS.empty;
|
|
1620
|
+
}
|
|
1621
|
+
else if (value === null) {
|
|
1622
|
+
return VALUE_STRINGS.null;
|
|
1623
|
+
}
|
|
1624
|
+
else if (value === undefined) {
|
|
1625
|
+
return VALUE_STRINGS.undefined;
|
|
1626
|
+
}
|
|
1627
|
+
else if (typeof value === 'string') {
|
|
1628
|
+
return value;
|
|
1629
|
+
}
|
|
1630
|
+
else if (typeof value === 'number') {
|
|
1631
|
+
return numberToString(value);
|
|
1632
|
+
}
|
|
1633
|
+
else if (value instanceof Date) {
|
|
1634
|
+
return value.toISOString();
|
|
1635
|
+
}
|
|
1636
|
+
else {
|
|
1637
|
+
try {
|
|
1638
|
+
return JSON.stringify(value);
|
|
1639
|
+
}
|
|
1640
|
+
catch (error) {
|
|
1641
|
+
if (error instanceof TypeError && error.message.includes('circular structure')) {
|
|
1642
|
+
return VALUE_STRINGS.circular;
|
|
1643
|
+
}
|
|
1644
|
+
throw error;
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
catch (error) {
|
|
1649
|
+
assertsError(error);
|
|
1650
|
+
console.error(error);
|
|
1651
|
+
return VALUE_STRINGS.unserializable;
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
/**
|
|
1656
|
+
* Replaces parameters in template with values from parameters object
|
|
1657
|
+
*
|
|
1658
|
+
* Note: This function is not places strings into string,
|
|
1659
|
+
* It's more complex and can handle this operation specifically for LLM models
|
|
1660
|
+
*
|
|
1661
|
+
* @param template the template with parameters in {curly} braces
|
|
1662
|
+
* @param parameters the object with parameters
|
|
1663
|
+
* @returns the template with replaced parameters
|
|
1664
|
+
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
1665
|
+
* @public exported from `@promptbook/utils`
|
|
1666
|
+
*/
|
|
1667
|
+
function templateParameters(template, parameters) {
|
|
1668
|
+
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
1669
|
+
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
1670
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
1671
|
+
}
|
|
1672
|
+
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
1673
|
+
// TODO: [🍵]
|
|
1674
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
let replacedTemplates = template;
|
|
1678
|
+
let match;
|
|
1679
|
+
let loopLimit = LOOP_LIMIT;
|
|
1680
|
+
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
1681
|
+
.exec(replacedTemplates))) {
|
|
1682
|
+
if (loopLimit-- < 0) {
|
|
1683
|
+
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
1684
|
+
}
|
|
1685
|
+
const precol = match.groups.precol;
|
|
1686
|
+
const parameterName = match.groups.parameterName;
|
|
1687
|
+
if (parameterName === '') {
|
|
1688
|
+
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
1689
|
+
continue;
|
|
1690
|
+
}
|
|
1691
|
+
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
1692
|
+
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
1693
|
+
}
|
|
1694
|
+
if (parameters[parameterName] === undefined) {
|
|
1695
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
1696
|
+
}
|
|
1697
|
+
let parameterValue = parameters[parameterName];
|
|
1698
|
+
if (parameterValue === undefined) {
|
|
1699
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
1700
|
+
}
|
|
1701
|
+
parameterValue = valueToString(parameterValue);
|
|
1702
|
+
// Escape curly braces in parameter values to prevent prompt-injection
|
|
1703
|
+
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
1704
|
+
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
1705
|
+
parameterValue = parameterValue
|
|
1706
|
+
.split('\n')
|
|
1707
|
+
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
1708
|
+
.join('\n');
|
|
1709
|
+
}
|
|
1710
|
+
replacedTemplates =
|
|
1711
|
+
replacedTemplates.substring(0, match.index + precol.length) +
|
|
1712
|
+
parameterValue +
|
|
1713
|
+
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
1714
|
+
}
|
|
1715
|
+
// [💫] Check if there are parameters that are not closed properly
|
|
1716
|
+
if (/{\w+$/.test(replacedTemplates)) {
|
|
1717
|
+
throw new PipelineExecutionError('Parameter is not closed');
|
|
1718
|
+
}
|
|
1719
|
+
// [💫] Check if there are parameters that are not opened properly
|
|
1720
|
+
if (/^\w+}/.test(replacedTemplates)) {
|
|
1721
|
+
throw new PipelineExecutionError('Parameter is not opened');
|
|
1722
|
+
}
|
|
1723
|
+
return replacedTemplates;
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
/**
|
|
1727
|
+
* Execution Tools for calling OpenAI API or other OpeenAI compatible provider
|
|
1728
|
+
*
|
|
1729
|
+
* @public exported from `@promptbook/openai`
|
|
1730
|
+
*/
|
|
1731
|
+
class OpenAiCompatibleExecutionTools {
|
|
1732
|
+
/**
|
|
1733
|
+
* Creates OpenAI compatible Execution Tools.
|
|
1734
|
+
*
|
|
1735
|
+
* @param options which are relevant are directly passed to the OpenAI compatible client
|
|
1736
|
+
*/
|
|
1737
|
+
constructor(options) {
|
|
1738
|
+
this.options = options;
|
|
1739
|
+
/**
|
|
1740
|
+
* OpenAI API client.
|
|
1741
|
+
*/
|
|
1742
|
+
this.client = null;
|
|
1743
|
+
// TODO: Allow configuring rate limits via options
|
|
1744
|
+
this.limiter = new Bottleneck__default["default"]({
|
|
1745
|
+
minTime: 60000 / (this.options.maxRequestsPerMinute || DEFAULT_MAX_REQUESTS_PER_MINUTE),
|
|
1746
|
+
});
|
|
1747
|
+
}
|
|
1748
|
+
async getClient() {
|
|
1749
|
+
if (this.client === null) {
|
|
1750
|
+
// Note: Passing only OpenAI relevant options to OpenAI constructor
|
|
1751
|
+
const openAiOptions = { ...this.options };
|
|
1752
|
+
delete openAiOptions.isVerbose;
|
|
1753
|
+
delete openAiOptions.userId;
|
|
1754
|
+
this.client = new OpenAI__default["default"](openAiOptions);
|
|
1755
|
+
}
|
|
1756
|
+
return this.client;
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Check the `options` passed to `constructor`
|
|
1760
|
+
*/
|
|
1761
|
+
async checkConfiguration() {
|
|
1762
|
+
await this.getClient();
|
|
1763
|
+
// TODO: [🎍] Do here a real check that API is online, working and API key is correct
|
|
1764
|
+
}
|
|
1765
|
+
/**
|
|
1766
|
+
* List all available OpenAI compatible models that can be used
|
|
1767
|
+
*/
|
|
1768
|
+
async listModels() {
|
|
1769
|
+
const client = await this.getClient();
|
|
1770
|
+
const rawModelsList = await client.models.list();
|
|
1771
|
+
const availableModels = rawModelsList.data
|
|
1772
|
+
.sort((a, b) => (a.created > b.created ? 1 : -1))
|
|
1773
|
+
.map((modelFromApi) => {
|
|
1774
|
+
const modelFromList = this.HARDCODED_MODELS.find(({ modelName }) => modelName === modelFromApi.id ||
|
|
1775
|
+
modelName.startsWith(modelFromApi.id) ||
|
|
1776
|
+
modelFromApi.id.startsWith(modelName));
|
|
1777
|
+
if (modelFromList !== undefined) {
|
|
1778
|
+
return modelFromList;
|
|
1779
|
+
}
|
|
1780
|
+
return {
|
|
1781
|
+
modelVariant: 'CHAT',
|
|
1782
|
+
modelTitle: modelFromApi.id,
|
|
1783
|
+
modelName: modelFromApi.id,
|
|
1784
|
+
modelDescription: '',
|
|
1785
|
+
};
|
|
1786
|
+
});
|
|
1787
|
+
return availableModels;
|
|
1788
|
+
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Calls OpenAI compatible API to use a chat model.
|
|
1791
|
+
*/
|
|
1792
|
+
async callChatModel(prompt) {
|
|
1793
|
+
var _a;
|
|
1794
|
+
if (this.options.isVerbose) {
|
|
1795
|
+
console.info(`💬 ${this.title} callChatModel call`, { prompt });
|
|
1796
|
+
}
|
|
1797
|
+
const { content, parameters, modelRequirements, format } = prompt;
|
|
1798
|
+
const client = await this.getClient();
|
|
1799
|
+
// TODO: [☂] Use here more modelRequirements
|
|
1800
|
+
if (modelRequirements.modelVariant !== 'CHAT') {
|
|
1801
|
+
throw new PipelineExecutionError('Use callChatModel only for CHAT variant');
|
|
1802
|
+
}
|
|
1803
|
+
const modelName = modelRequirements.modelName || this.getDefaultChatModel().modelName;
|
|
1804
|
+
const modelSettings = {
|
|
1805
|
+
model: modelName,
|
|
1806
|
+
max_tokens: modelRequirements.maxTokens,
|
|
1807
|
+
// <- TODO: [🌾] Make some global max cap for maxTokens
|
|
1808
|
+
temperature: modelRequirements.temperature,
|
|
1809
|
+
// <- TODO: [🈁] Use `seed` here AND/OR use is `isDeterministic` for entire execution tools
|
|
1810
|
+
// <- Note: [🧆]
|
|
1811
|
+
}; // <- TODO: [💩] Guard here types better
|
|
1812
|
+
if (format === 'JSON') {
|
|
1813
|
+
modelSettings.response_format = {
|
|
1814
|
+
type: 'json_object',
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
// <- TODO: [🚸] Not all models are compatible with JSON mode
|
|
1818
|
+
// > 'response_format' of type 'json_object' is not supported with this model.
|
|
1819
|
+
const rawPromptContent = templateParameters(content, { ...parameters, modelName });
|
|
1820
|
+
const rawRequest = {
|
|
1821
|
+
...modelSettings,
|
|
1822
|
+
messages: [
|
|
1823
|
+
...(modelRequirements.systemMessage === undefined
|
|
1824
|
+
? []
|
|
1825
|
+
: [
|
|
1826
|
+
{
|
|
1827
|
+
role: 'system',
|
|
1828
|
+
content: modelRequirements.systemMessage,
|
|
1829
|
+
},
|
|
1830
|
+
]),
|
|
1831
|
+
{
|
|
1832
|
+
role: 'user',
|
|
1833
|
+
content: rawPromptContent,
|
|
1834
|
+
},
|
|
1835
|
+
],
|
|
1836
|
+
user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),
|
|
1837
|
+
};
|
|
1838
|
+
const start = $getCurrentDate();
|
|
1839
|
+
if (this.options.isVerbose) {
|
|
1840
|
+
console.info(colors__default["default"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
1841
|
+
}
|
|
1842
|
+
const rawResponse = await this.limiter
|
|
1843
|
+
.schedule(() => client.chat.completions.create(rawRequest))
|
|
1844
|
+
.catch((error) => {
|
|
1845
|
+
assertsError(error);
|
|
1846
|
+
if (this.options.isVerbose) {
|
|
1847
|
+
console.info(colors__default["default"].bgRed('error'), error);
|
|
1848
|
+
}
|
|
1849
|
+
throw error;
|
|
1850
|
+
});
|
|
1851
|
+
if (this.options.isVerbose) {
|
|
1852
|
+
console.info(colors__default["default"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
1853
|
+
}
|
|
1854
|
+
const complete = $getCurrentDate();
|
|
1855
|
+
if (!rawResponse.choices[0]) {
|
|
1856
|
+
throw new PipelineExecutionError(`No choises from ${this.title}`);
|
|
1857
|
+
}
|
|
1858
|
+
if (rawResponse.choices.length > 1) {
|
|
1859
|
+
// TODO: This should be maybe only warning
|
|
1860
|
+
throw new PipelineExecutionError(`More than one choise from ${this.title}`);
|
|
1861
|
+
}
|
|
1862
|
+
const resultContent = rawResponse.choices[0].message.content;
|
|
1863
|
+
const usage = this.computeUsage(content || '', resultContent || '', rawResponse);
|
|
1864
|
+
if (resultContent === null) {
|
|
1865
|
+
throw new PipelineExecutionError(`No response message from ${this.title}`);
|
|
1866
|
+
}
|
|
1867
|
+
return exportJson({
|
|
1868
|
+
name: 'promptResult',
|
|
1869
|
+
message: `Result of \`OpenAiCompatibleExecutionTools.callChatModel\``,
|
|
1870
|
+
order: [],
|
|
1871
|
+
value: {
|
|
1872
|
+
content: resultContent,
|
|
1873
|
+
modelName: rawResponse.model || modelName,
|
|
1874
|
+
timing: {
|
|
1875
|
+
start,
|
|
1876
|
+
complete,
|
|
1877
|
+
},
|
|
1878
|
+
usage,
|
|
1879
|
+
rawPromptContent,
|
|
1880
|
+
rawRequest,
|
|
1881
|
+
rawResponse,
|
|
1882
|
+
// <- [🗯]
|
|
1883
|
+
},
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
/**
|
|
1887
|
+
* Calls OpenAI API to use a complete model.
|
|
1888
|
+
*/
|
|
1889
|
+
async callCompletionModel(prompt) {
|
|
1890
|
+
var _a;
|
|
1891
|
+
if (this.options.isVerbose) {
|
|
1892
|
+
console.info(`🖋 ${this.title} callCompletionModel call`, { prompt });
|
|
1893
|
+
}
|
|
1894
|
+
const { content, parameters, modelRequirements } = prompt;
|
|
1895
|
+
const client = await this.getClient();
|
|
1896
|
+
// TODO: [☂] Use here more modelRequirements
|
|
1897
|
+
if (modelRequirements.modelVariant !== 'COMPLETION') {
|
|
1898
|
+
throw new PipelineExecutionError('Use callCompletionModel only for COMPLETION variant');
|
|
1899
|
+
}
|
|
1900
|
+
const modelName = modelRequirements.modelName || this.getDefaultCompletionModel().modelName;
|
|
1901
|
+
const modelSettings = {
|
|
1902
|
+
model: modelName,
|
|
1903
|
+
max_tokens: modelRequirements.maxTokens || 2000,
|
|
1904
|
+
// <- TODO: [🌾] Make some global max cap for maxTokens
|
|
1905
|
+
temperature: modelRequirements.temperature,
|
|
1906
|
+
// <- TODO: [🈁] Use `seed` here AND/OR use is `isDeterministic` for entire execution tools
|
|
1907
|
+
// <- Note: [🧆]
|
|
1908
|
+
};
|
|
1909
|
+
const rawPromptContent = templateParameters(content, { ...parameters, modelName });
|
|
1910
|
+
const rawRequest = {
|
|
1911
|
+
...modelSettings,
|
|
1912
|
+
prompt: rawPromptContent,
|
|
1913
|
+
user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),
|
|
1914
|
+
};
|
|
1915
|
+
const start = $getCurrentDate();
|
|
1916
|
+
if (this.options.isVerbose) {
|
|
1917
|
+
console.info(colors__default["default"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
1918
|
+
}
|
|
1919
|
+
const rawResponse = await this.limiter
|
|
1920
|
+
.schedule(() => client.completions.create(rawRequest))
|
|
1921
|
+
.catch((error) => {
|
|
1922
|
+
assertsError(error);
|
|
1923
|
+
if (this.options.isVerbose) {
|
|
1924
|
+
console.info(colors__default["default"].bgRed('error'), error);
|
|
1925
|
+
}
|
|
1926
|
+
throw error;
|
|
1927
|
+
});
|
|
1928
|
+
if (this.options.isVerbose) {
|
|
1929
|
+
console.info(colors__default["default"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
1930
|
+
}
|
|
1931
|
+
const complete = $getCurrentDate();
|
|
1932
|
+
if (!rawResponse.choices[0]) {
|
|
1933
|
+
throw new PipelineExecutionError(`No choises from ${this.title}`);
|
|
1934
|
+
}
|
|
1935
|
+
if (rawResponse.choices.length > 1) {
|
|
1936
|
+
// TODO: This should be maybe only warning
|
|
1937
|
+
throw new PipelineExecutionError(`More than one choise from ${this.title}`);
|
|
1938
|
+
}
|
|
1939
|
+
const resultContent = rawResponse.choices[0].text;
|
|
1940
|
+
const usage = this.computeUsage(content || '', resultContent || '', rawResponse);
|
|
1941
|
+
return exportJson({
|
|
1942
|
+
name: 'promptResult',
|
|
1943
|
+
message: `Result of \`OpenAiCompatibleExecutionTools.callCompletionModel\``,
|
|
1944
|
+
order: [],
|
|
1945
|
+
value: {
|
|
1946
|
+
content: resultContent,
|
|
1947
|
+
modelName: rawResponse.model || modelName,
|
|
1948
|
+
timing: {
|
|
1949
|
+
start,
|
|
1950
|
+
complete,
|
|
1951
|
+
},
|
|
1952
|
+
usage,
|
|
1953
|
+
rawPromptContent,
|
|
1954
|
+
rawRequest,
|
|
1955
|
+
rawResponse,
|
|
1956
|
+
// <- [🗯]
|
|
1957
|
+
},
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Calls OpenAI compatible API to use a embedding model
|
|
1962
|
+
*/
|
|
1963
|
+
async callEmbeddingModel(prompt) {
|
|
1964
|
+
if (this.options.isVerbose) {
|
|
1965
|
+
console.info(`🖋 ${this.title} embedding call`, { prompt });
|
|
1966
|
+
}
|
|
1967
|
+
const { content, parameters, modelRequirements } = prompt;
|
|
1968
|
+
const client = await this.getClient();
|
|
1969
|
+
// TODO: [☂] Use here more modelRequirements
|
|
1970
|
+
if (modelRequirements.modelVariant !== 'EMBEDDING') {
|
|
1971
|
+
throw new PipelineExecutionError('Use embed only for EMBEDDING variant');
|
|
1972
|
+
}
|
|
1973
|
+
const modelName = modelRequirements.modelName || this.getDefaultEmbeddingModel().modelName;
|
|
1974
|
+
const rawPromptContent = templateParameters(content, { ...parameters, modelName });
|
|
1975
|
+
const rawRequest = {
|
|
1976
|
+
input: rawPromptContent,
|
|
1977
|
+
model: modelName,
|
|
1978
|
+
};
|
|
1979
|
+
const start = $getCurrentDate();
|
|
1980
|
+
if (this.options.isVerbose) {
|
|
1981
|
+
console.info(colors__default["default"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));
|
|
1982
|
+
}
|
|
1983
|
+
const rawResponse = await this.limiter
|
|
1984
|
+
.schedule(() => client.embeddings.create(rawRequest))
|
|
1985
|
+
.catch((error) => {
|
|
1986
|
+
assertsError(error);
|
|
1987
|
+
if (this.options.isVerbose) {
|
|
1988
|
+
console.info(colors__default["default"].bgRed('error'), error);
|
|
1989
|
+
}
|
|
1990
|
+
throw error;
|
|
1991
|
+
});
|
|
1992
|
+
if (this.options.isVerbose) {
|
|
1993
|
+
console.info(colors__default["default"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));
|
|
1994
|
+
}
|
|
1995
|
+
const complete = $getCurrentDate();
|
|
1996
|
+
if (rawResponse.data.length !== 1) {
|
|
1997
|
+
throw new PipelineExecutionError(`Expected exactly 1 data item in response, got ${rawResponse.data.length}`);
|
|
1998
|
+
}
|
|
1999
|
+
const resultContent = rawResponse.data[0].embedding;
|
|
2000
|
+
const usage = this.computeUsage(content || '', '',
|
|
2001
|
+
// <- Note: Embedding does not have result content
|
|
2002
|
+
rawResponse);
|
|
2003
|
+
return exportJson({
|
|
2004
|
+
name: 'promptResult',
|
|
2005
|
+
message: `Result of \`OpenAiCompatibleExecutionTools.callEmbeddingModel\``,
|
|
2006
|
+
order: [],
|
|
2007
|
+
value: {
|
|
2008
|
+
content: resultContent,
|
|
2009
|
+
modelName: rawResponse.model || modelName,
|
|
2010
|
+
timing: {
|
|
2011
|
+
start,
|
|
2012
|
+
complete,
|
|
2013
|
+
},
|
|
2014
|
+
usage,
|
|
2015
|
+
rawPromptContent,
|
|
2016
|
+
rawRequest,
|
|
2017
|
+
rawResponse,
|
|
2018
|
+
// <- [🗯]
|
|
2019
|
+
},
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
// <- Note: [🤖] callXxxModel
|
|
2023
|
+
/**
|
|
2024
|
+
* Get the model that should be used as default
|
|
2025
|
+
*/
|
|
2026
|
+
getDefaultModel(defaultModelName) {
|
|
2027
|
+
// Note: Match exact or prefix for model families
|
|
2028
|
+
const model = this.HARDCODED_MODELS.find(({ modelName }) => modelName === defaultModelName || modelName.startsWith(defaultModelName));
|
|
2029
|
+
if (model === undefined) {
|
|
2030
|
+
throw new PipelineExecutionError(spaceTrim__default["default"]((block) => `
|
|
2031
|
+
Cannot find model in ${this.title} models with name "${defaultModelName}" which should be used as default.
|
|
2032
|
+
|
|
2033
|
+
Available models:
|
|
2034
|
+
${block(this.HARDCODED_MODELS.map(({ modelName }) => `- "${modelName}"`).join('\n'))}
|
|
2035
|
+
|
|
2036
|
+
Model "${defaultModelName}" is probably not available anymore, not installed, inaccessible or misconfigured.
|
|
2037
|
+
|
|
2038
|
+
`));
|
|
2039
|
+
}
|
|
2040
|
+
return model;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* TODO: [🛄] Some way how to re-wrap the errors from `OpenAiCompatibleExecutionTools`
|
|
2045
|
+
* TODO: [🛄] Maybe make custom `OpenAiCompatibleError`
|
|
2046
|
+
* TODO: [🧠][🈁] Maybe use `isDeterministic` from options
|
|
2047
|
+
* TODO: [🧠][🌰] Allow to pass `title` for tracking purposes
|
|
2048
|
+
*/
|
|
2049
|
+
|
|
2050
|
+
/**
|
|
2051
|
+
* List of available models in Ollama library
|
|
2052
|
+
*
|
|
2053
|
+
* Note: Done at 2025-05-19
|
|
2054
|
+
*
|
|
2055
|
+
* @see https://ollama.com/library
|
|
2056
|
+
* @public exported from `@promptbook/ollama`
|
|
2057
|
+
*/
|
|
2058
|
+
const OLLAMA_MODELS = exportJson({
|
|
2059
|
+
name: 'OLLAMA_MODELS',
|
|
2060
|
+
value: [
|
|
2061
|
+
{
|
|
2062
|
+
modelVariant: 'CHAT',
|
|
2063
|
+
modelTitle: 'llama3',
|
|
2064
|
+
modelName: 'llama3',
|
|
2065
|
+
modelDescription: 'Meta Llama 3 (8B-70B parameters) with 8K context window. Latest generation foundation model with enhanced reasoning, instruction following, and factual accuracy. Superior performance to Llama 2 across all benchmarks with improved multilingual capabilities.',
|
|
2066
|
+
},
|
|
2067
|
+
{
|
|
2068
|
+
modelVariant: 'CHAT',
|
|
2069
|
+
modelTitle: 'llama3-chat',
|
|
2070
|
+
modelName: 'llama3-chat',
|
|
2071
|
+
modelDescription: 'Meta Llama 3 Chat with 8K context window, fine-tuned specifically for dialogue with significantly improved instruction following. Features enhanced safety guardrails and reduced hallucinations. Recommended over Llama 2 Chat for all conversational applications.',
|
|
2072
|
+
},
|
|
2073
|
+
{
|
|
2074
|
+
modelVariant: 'CHAT',
|
|
2075
|
+
modelTitle: 'llama3-instruct',
|
|
2076
|
+
modelName: 'llama3-instruct',
|
|
2077
|
+
modelDescription: 'Meta Llama 3 Instruct with 8K context window, fine-tuned for following specific instructions with precise outputs. Features improved structured response formatting and accurate completion of complex directives.',
|
|
2078
|
+
},
|
|
2079
|
+
{
|
|
2080
|
+
modelVariant: 'CHAT',
|
|
2081
|
+
modelTitle: 'codellama:13b',
|
|
2082
|
+
modelName: 'codellama:13b',
|
|
2083
|
+
modelDescription: 'Meta CodeLlama 13B with 16K context window, specialized foundation model for code generation and understanding. Supports multiple programming languages with strong contextual code completion capabilities.',
|
|
2084
|
+
},
|
|
2085
|
+
{
|
|
2086
|
+
modelVariant: 'CHAT',
|
|
2087
|
+
modelTitle: 'codellama:34b',
|
|
2088
|
+
modelName: 'codellama:34b',
|
|
2089
|
+
modelDescription: 'Meta CodeLlama 34B with 16K context window, larger code-specialized model with improved reasoning about complex programming tasks. Enhanced documentation generation and bug detection compared to smaller variants.',
|
|
2090
|
+
},
|
|
2091
|
+
{
|
|
2092
|
+
modelVariant: 'CHAT',
|
|
2093
|
+
modelTitle: 'phi3:mini',
|
|
2094
|
+
modelName: 'phi3:mini',
|
|
2095
|
+
modelDescription: 'Microsoft Phi-3 Mini (3.8B parameters) with 4K context window, highly efficient small language model with remarkable reasoning given its size. Performs competitively with much larger models on common benchmarks. Excellent for resource-constrained environments.',
|
|
2096
|
+
},
|
|
2097
|
+
{
|
|
2098
|
+
modelVariant: 'CHAT',
|
|
2099
|
+
modelTitle: 'phi3:medium',
|
|
2100
|
+
modelName: 'phi3:medium',
|
|
2101
|
+
modelDescription: 'Microsoft Phi-3 Medium (14B parameters) with 8K context window, balanced model offering strong performance with reasonable compute requirements. Features improved reasoning and factuality compared to Mini variant while maintaining efficiency.',
|
|
2102
|
+
},
|
|
2103
|
+
{
|
|
2104
|
+
modelVariant: 'CHAT',
|
|
2105
|
+
modelTitle: 'mistral-nemo',
|
|
2106
|
+
modelName: 'mistral-nemo',
|
|
2107
|
+
modelDescription: 'Mistral NeMo with 32K context window, open-source model optimized for enterprise use cases with improved reasoning and knowledge capabilities. Features strong performance on professional and domain-specific tasks.',
|
|
2108
|
+
},
|
|
2109
|
+
{
|
|
2110
|
+
modelVariant: 'CHAT',
|
|
2111
|
+
modelTitle: 'llama2',
|
|
2112
|
+
modelName: 'llama2',
|
|
2113
|
+
modelDescription: 'Meta Llama 2 (7B-70B parameters) with 4K context window. General-purpose foundation model balancing performance and efficiency for text generation and reasoning tasks. Suitable for most non-specialized applications. Note: Superseded by Llama 3 models which offer better performance.',
|
|
2114
|
+
},
|
|
2115
|
+
{
|
|
2116
|
+
modelVariant: 'CHAT',
|
|
2117
|
+
modelTitle: 'llama2-chat',
|
|
2118
|
+
modelName: 'llama2-chat',
|
|
2119
|
+
modelDescription: 'Meta Llama 2 Chat with 4K context window, fine-tuned specifically for conversational AI. Enhanced instruction following and safer responses compared to base model. Ideal for chatbots and interactive applications. Note: Consider using newer Llama 3 Chat for improved performance.',
|
|
2120
|
+
},
|
|
2121
|
+
{
|
|
2122
|
+
modelVariant: 'CHAT',
|
|
2123
|
+
modelTitle: 'alpaca-7b',
|
|
2124
|
+
modelName: 'alpaca-7b',
|
|
2125
|
+
modelDescription: 'Stanford Alpaca 7B with 2K context window, instruction-tuned LLaMA model focused on following specific directions. Optimized for resource efficiency while maintaining good response quality. Suitable for lightweight applications.',
|
|
2126
|
+
},
|
|
2127
|
+
{
|
|
2128
|
+
modelVariant: 'CHAT',
|
|
2129
|
+
modelTitle: 'alpaca-30b',
|
|
2130
|
+
modelName: 'alpaca-30b',
|
|
2131
|
+
modelDescription: 'Stanford Alpaca 30B with 2K context window. Larger instruction-tuned LLaMA model with improved reasoning and content generation capabilities. Better performance than 7B variant but requires more computational resources.',
|
|
2132
|
+
},
|
|
2133
|
+
{
|
|
2134
|
+
modelVariant: 'CHAT',
|
|
2135
|
+
modelTitle: 'vicuna-13b',
|
|
2136
|
+
modelName: 'vicuna-13b',
|
|
2137
|
+
modelDescription: 'Vicuna 13B with 2K context window, fine-tuned from LLaMA for chat and instruction following. Known for balanced performance, good conversational abilities, and improved helpfulness over base models. Popular for diverse conversational applications.',
|
|
2138
|
+
},
|
|
2139
|
+
{
|
|
2140
|
+
modelVariant: 'CHAT',
|
|
2141
|
+
modelTitle: 'falcon-7b',
|
|
2142
|
+
modelName: 'falcon-7b',
|
|
2143
|
+
modelDescription: 'Falcon 7B with 2K context window, performant open large language model trained on 1.5 trillion tokens. Strong on general knowledge tasks with smaller computational requirements. Good balance of performance and efficiency.',
|
|
2144
|
+
},
|
|
2145
|
+
{
|
|
2146
|
+
modelVariant: 'CHAT',
|
|
2147
|
+
modelTitle: 'falcon-40b',
|
|
2148
|
+
modelName: 'falcon-40b',
|
|
2149
|
+
modelDescription: 'Falcon 40B with 2K context window, larger open large language model with enhanced reasoning and knowledge capabilities. Significantly better performance than 7B version but requires substantially more resources. Suitable for complex generation tasks.',
|
|
2150
|
+
},
|
|
2151
|
+
{
|
|
2152
|
+
modelVariant: 'CHAT',
|
|
2153
|
+
modelTitle: 'bloom-7b',
|
|
2154
|
+
modelName: 'bloom-7b',
|
|
2155
|
+
modelDescription: 'BLOOM 7B with 2K context window, multilingual large language model supporting 46+ languages. Trained for diverse linguistic capabilities across languages. Especially useful for non-English or multilingual applications.',
|
|
2156
|
+
},
|
|
2157
|
+
{
|
|
2158
|
+
modelVariant: 'CHAT',
|
|
2159
|
+
modelTitle: 'mistral-7b',
|
|
2160
|
+
modelName: 'mistral-7b',
|
|
2161
|
+
modelDescription: 'Mistral 7B with 8K context window, efficient and fast open LLM with performance rivaling much larger models. Features Grouped-Query Attention for faster inference. Excellent balance of quality and speed for various applications.',
|
|
2162
|
+
},
|
|
2163
|
+
{
|
|
2164
|
+
modelVariant: 'CHAT',
|
|
2165
|
+
modelTitle: 'gorilla',
|
|
2166
|
+
modelName: 'gorilla',
|
|
2167
|
+
modelDescription: 'Gorilla with 4K context window, specialized open-source LLM for tool use and API interaction. Fine-tuned to understand and generate API calls accurately. Optimal for agent applications that interact with external tools and services.',
|
|
2168
|
+
},
|
|
2169
|
+
{
|
|
2170
|
+
modelVariant: 'CHAT',
|
|
2171
|
+
modelTitle: 'cerebras-13b',
|
|
2172
|
+
modelName: 'cerebras-13b',
|
|
2173
|
+
modelDescription: 'Cerebras-GPT 13B with 2K context window, trained on diverse high-quality datasets. Good general-purpose capabilities with particular strengths in factual response accuracy. Well-suited for applications requiring reliable information.',
|
|
2174
|
+
},
|
|
2175
|
+
{
|
|
2176
|
+
modelVariant: 'CHAT',
|
|
2177
|
+
modelTitle: 'openchat-7b',
|
|
2178
|
+
modelName: 'openchat-7b',
|
|
2179
|
+
modelDescription: 'OpenChat 7B with 4K context window, optimized for conversational abilities and instruction following. Outperforms many larger models on benchmark tasks while maintaining efficiency. Ideal for interactive applications with limited resources.',
|
|
2180
|
+
},
|
|
2181
|
+
{
|
|
2182
|
+
modelVariant: 'CHAT',
|
|
2183
|
+
modelTitle: 'openchat-13b',
|
|
2184
|
+
modelName: 'openchat-13b',
|
|
2185
|
+
modelDescription: 'OpenChat 13B with 4K context window, larger conversational LLM with enhanced reasoning, helpfulness, and knowledge. Significant improvement over 7B variant in complex tasks and nuanced conversations. Well-balanced for most conversational applications.',
|
|
2186
|
+
},
|
|
2187
|
+
{
|
|
2188
|
+
modelVariant: 'CHAT',
|
|
2189
|
+
modelTitle: 'mpt-7b-chat',
|
|
2190
|
+
modelName: 'mpt-7b-chat',
|
|
2191
|
+
modelDescription: 'MPT-7B Chat with 4K context window (extendable to 65K+), optimized for dialogue using high-quality conversation data. Features enhanced conversational abilities with strong safety alignments. Good for deployment in public-facing chat applications.',
|
|
2192
|
+
},
|
|
2193
|
+
{
|
|
2194
|
+
modelVariant: 'CHAT',
|
|
2195
|
+
modelTitle: 'mpt-7b-instruct',
|
|
2196
|
+
modelName: 'mpt-7b-instruct',
|
|
2197
|
+
modelDescription: 'MPT-7B Instruct with 4K context window (extendable to 65K+), instruction-tuned variant optimized for following specific directives. Better than chat variant for single-turn instruction tasks. Well-suited for content generation and task completion.',
|
|
2198
|
+
},
|
|
2199
|
+
{
|
|
2200
|
+
modelVariant: 'CHAT',
|
|
2201
|
+
modelTitle: 'command-7b',
|
|
2202
|
+
modelName: 'command-7b',
|
|
2203
|
+
modelDescription: 'Command 7B with 4K context window, instruction-following LLM tuned specifically for direct command execution and helpful responses. Optimized for clarity of outputs and following explicit directions. Good for practical task-oriented applications.',
|
|
2204
|
+
},
|
|
2205
|
+
{
|
|
2206
|
+
modelVariant: 'CHAT',
|
|
2207
|
+
modelTitle: 'starcoder',
|
|
2208
|
+
modelName: 'starcoder',
|
|
2209
|
+
modelDescription: 'StarCoder with 8K context window, specialized code generation large language model trained on permissively licensed code. Supports 80+ programming languages. Optimized for code completion, generation, and understanding tasks.',
|
|
2210
|
+
},
|
|
2211
|
+
{
|
|
2212
|
+
modelVariant: 'CHAT',
|
|
2213
|
+
modelTitle: 'starcoder2',
|
|
2214
|
+
modelName: 'starcoder2',
|
|
2215
|
+
modelDescription: 'StarCoder2 with 16K context window, improved code generation model with better reasoning about code, debugging capabilities, and documentation generation. Supports 600+ programming languages. Ideal for complex software development assistance.',
|
|
2216
|
+
},
|
|
2217
|
+
{
|
|
2218
|
+
modelVariant: 'CHAT',
|
|
2219
|
+
modelTitle: 'mixtral-7b-chat',
|
|
2220
|
+
modelName: 'mixtral-7b-chat',
|
|
2221
|
+
modelDescription: 'Mixtral 7B Chat with 32K context window, Mixture-of-Experts conversational model with strong performance across diverse tasks. Efficiently routes inputs to specialized sub-networks for optimal processing. Well-balanced for most chat applications.',
|
|
2222
|
+
},
|
|
2223
|
+
{
|
|
2224
|
+
modelVariant: 'CHAT',
|
|
2225
|
+
modelTitle: 'mixtral-8x7b',
|
|
2226
|
+
modelName: 'mixtral-8x7b',
|
|
2227
|
+
modelDescription: 'Mixtral 8x7B with 32K context window, advanced Mixture-of-Experts architecture using 8 expert networks of 7B parameters each. Competitive with much larger dense models while using less computation. Excellent general-purpose capabilities.',
|
|
2228
|
+
},
|
|
2229
|
+
{
|
|
2230
|
+
modelVariant: 'CHAT',
|
|
2231
|
+
modelTitle: 'mixtral-8x7b-instruct',
|
|
2232
|
+
modelName: 'mixtral-8x7b-instruct',
|
|
2233
|
+
modelDescription: 'Mixtral 8x7B Instruct with 32K context window, instruction-tuned Mixture-of-Experts model for direct task execution. Enhanced directive following and more structured outputs compared to base model. Optimal for specific instruction-based workloads.',
|
|
2234
|
+
},
|
|
2235
|
+
{
|
|
2236
|
+
modelVariant: 'CHAT',
|
|
2237
|
+
modelTitle: 'neural-chat',
|
|
2238
|
+
modelName: 'neural-chat',
|
|
2239
|
+
modelDescription: 'Intel Neural Chat (latest) with 8K context window, optimized for Intel hardware with efficient inference. Balanced model for general-purpose conversational applications with good instruction following capabilities.',
|
|
2240
|
+
},
|
|
2241
|
+
{
|
|
2242
|
+
modelVariant: 'CHAT',
|
|
2243
|
+
modelTitle: 'qwen:7b',
|
|
2244
|
+
modelName: 'qwen:7b',
|
|
2245
|
+
modelDescription: 'Alibaba Qwen 7B with 8K context window. Versatile model with strong multilingual capabilities, particularly for Chinese and English. Features good reasoning and knowledge across diverse domains.',
|
|
2246
|
+
},
|
|
2247
|
+
{
|
|
2248
|
+
modelVariant: 'CHAT',
|
|
2249
|
+
modelTitle: 'qwen:14b',
|
|
2250
|
+
modelName: 'qwen:14b',
|
|
2251
|
+
modelDescription: 'Alibaba Qwen 14B with 8K context window. Enhanced version with improved reasoning and knowledge capabilities. Particularly strong in multilingual applications and domain-specific tasks requiring deeper understanding.',
|
|
2252
|
+
},
|
|
2253
|
+
{
|
|
2254
|
+
modelVariant: 'CHAT',
|
|
2255
|
+
modelTitle: 'gemma:2b',
|
|
2256
|
+
modelName: 'gemma:2b',
|
|
2257
|
+
modelDescription: 'Google Gemma 2B with 8K context window. Lightweight but capable model designed for efficiency. Good performance for its size on common tasks, ideal for resource-constrained environments and quick responses.',
|
|
2258
|
+
},
|
|
2259
|
+
{
|
|
2260
|
+
modelVariant: 'CHAT',
|
|
2261
|
+
modelTitle: 'gemma:7b',
|
|
2262
|
+
modelName: 'gemma:7b',
|
|
2263
|
+
modelDescription: 'Google Gemma 7B with 8K context window. Well-balanced model offering strong performance across general tasks while maintaining reasonable resource requirements. Good alternative to similar-sized models with competitive capabilities.',
|
|
2264
|
+
},
|
|
2265
|
+
{
|
|
2266
|
+
modelVariant: 'CHAT',
|
|
2267
|
+
modelTitle: 'dolphin-mixtral',
|
|
2268
|
+
modelName: 'dolphin-mixtral',
|
|
2269
|
+
modelDescription: 'Dolphin Mixtral with 32K context window. Community-tuned version of Mixtral with enhanced instruction following and creative capabilities. Maintains the MoE architecture while improving conversational abilities and reducing hallucinations.',
|
|
2270
|
+
},
|
|
2271
|
+
{
|
|
2272
|
+
modelVariant: 'CHAT',
|
|
2273
|
+
modelTitle: 'yi:34b-chat',
|
|
2274
|
+
modelName: 'yi:34b-chat',
|
|
2275
|
+
modelDescription: 'Yi 34B Chat with 4K context window. Large bilingual model with exceptional English and Chinese capabilities. Strong performance on reasoning, knowledge, and instruction following tasks that competes with much larger commercial models.',
|
|
2276
|
+
},
|
|
2277
|
+
// <- [🕕]
|
|
2278
|
+
],
|
|
2279
|
+
});
|
|
2280
|
+
/**
|
|
2281
|
+
* TODO: [🚸] Not all models are compatible with JSON mode, add this information here and use it
|
|
2282
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2283
|
+
*/
|
|
2284
|
+
|
|
2285
|
+
/**
|
|
2286
|
+
* Default base URL for Ollama API
|
|
2287
|
+
*
|
|
2288
|
+
* @public exported from `@promptbook/ollama`
|
|
2289
|
+
*/
|
|
2290
|
+
const DEFAULT_OLLAMA_BASE_URL = 'http://localhost:11434/v1';
|
|
2291
|
+
|
|
2292
|
+
/**
|
|
2293
|
+
* Execution Tools for calling Ollama API
|
|
2294
|
+
*
|
|
2295
|
+
* @public exported from `@promptbook/ollama`
|
|
2296
|
+
*/
|
|
2297
|
+
class OllamaExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
2298
|
+
/* <- TODO: [🍚] `, Destroyable` */
|
|
2299
|
+
constructor(ollamaOptions) {
|
|
2300
|
+
const openAiCompatibleOptions = {
|
|
2301
|
+
baseURL: DEFAULT_OLLAMA_BASE_URL,
|
|
2302
|
+
...ollamaOptions,
|
|
2303
|
+
userId: 'ollama',
|
|
2304
|
+
};
|
|
2305
|
+
super(openAiCompatibleOptions);
|
|
2306
|
+
}
|
|
2307
|
+
get title() {
|
|
2308
|
+
return 'Ollama';
|
|
2309
|
+
}
|
|
2310
|
+
get description() {
|
|
2311
|
+
return 'Use all models provided by Ollama';
|
|
2312
|
+
}
|
|
2313
|
+
/**
|
|
2314
|
+
* List all available models (non dynamically)
|
|
2315
|
+
*
|
|
2316
|
+
* Note: Purpose of this is to provide more information about models than standard listing from API
|
|
2317
|
+
*/
|
|
2318
|
+
get HARDCODED_MODELS() {
|
|
2319
|
+
return OLLAMA_MODELS;
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Computes the usage of the Ollama API based on the response from Ollama
|
|
2323
|
+
*/
|
|
2324
|
+
computeUsage(...args) {
|
|
2325
|
+
return {
|
|
2326
|
+
...computeOpenAiUsage(...args),
|
|
2327
|
+
price: ZERO_VALUE, // <- Note: Running on local model, so no price, maybe in the future we can add a way to calculate price based on electricity usage
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
/**
|
|
2331
|
+
* Default model for chat variant.
|
|
2332
|
+
*/
|
|
2333
|
+
getDefaultChatModel() {
|
|
2334
|
+
return this.getDefaultModel('llama2'); // <- TODO: [🧠] Pick the best default model
|
|
2335
|
+
// <- TODO: [🛄] When 'llama2' not installed, maybe better error message
|
|
2336
|
+
}
|
|
2337
|
+
/**
|
|
2338
|
+
* Default model for completion variant.
|
|
2339
|
+
*/
|
|
2340
|
+
getDefaultCompletionModel() {
|
|
2341
|
+
return this.getDefaultModel('llama2'); // <- TODO: [🧠] Pick the best default model
|
|
2342
|
+
// <- TODO: [🛄] When 'llama2' not installed, maybe better error message
|
|
2343
|
+
}
|
|
2344
|
+
/**
|
|
2345
|
+
* Default model for completion variant.
|
|
2346
|
+
*/
|
|
2347
|
+
getDefaultEmbeddingModel() {
|
|
2348
|
+
return this.getDefaultModel('text-embedding-3-large'); // <- TODO: [🧠] Pick the best default model
|
|
2349
|
+
// <- TODO: [🛄]
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
/**
|
|
2353
|
+
* TODO: [🛄] Some way how to re-wrap the errors from `OpenAiCompatibleExecutionTools`
|
|
2354
|
+
*/
|
|
558
2355
|
|
|
559
2356
|
/**
|
|
560
2357
|
* Execution Tools for calling Ollama API
|
|
561
2358
|
*
|
|
562
2359
|
* @public exported from `@promptbook/ollama`
|
|
563
2360
|
*/
|
|
564
|
-
const createOllamaExecutionTools = Object.assign((options) =>
|
|
2361
|
+
const createOllamaExecutionTools = Object.assign((options) => {
|
|
2362
|
+
return new OllamaExecutionTools(options);
|
|
2363
|
+
}, {
|
|
565
2364
|
packageName: '@promptbook/ollama',
|
|
566
2365
|
className: 'OllamaExecutionTools',
|
|
567
2366
|
});
|
|
@@ -745,6 +2544,8 @@
|
|
|
745
2544
|
*/
|
|
746
2545
|
|
|
747
2546
|
exports.BOOK_LANGUAGE_VERSION = BOOK_LANGUAGE_VERSION;
|
|
2547
|
+
exports.DEFAULT_OLLAMA_BASE_URL = DEFAULT_OLLAMA_BASE_URL;
|
|
2548
|
+
exports.OLLAMA_MODELS = OLLAMA_MODELS;
|
|
748
2549
|
exports.OllamaExecutionTools = OllamaExecutionTools;
|
|
749
2550
|
exports.PROMPTBOOK_ENGINE_VERSION = PROMPTBOOK_ENGINE_VERSION;
|
|
750
2551
|
exports._OllamaRegistration = _OllamaRegistration;
|