@promptbook/ollama 0.94.0-3 → 0.94.0-5
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 +3 -1
- package/esm/index.es.js +618 -521
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/ollama.index.d.ts +4 -0
- package/esm/typings/src/_packages/openai.index.d.ts +2 -0
- package/esm/typings/src/llm-providers/{openai/computeUsage.d.ts → _common/utils/pricing.d.ts} +2 -2
- package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +44 -0
- package/esm/typings/src/llm-providers/ollama/OllamaExecutionToolsOptions.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/createOllamaExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/ollama-models.d.ts +14 -0
- 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/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +625 -526
- 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,15 +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 spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
|
|
9
10
|
var Bottleneck__default = /*#__PURE__*/_interopDefaultLegacy(Bottleneck);
|
|
10
11
|
var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
|
|
11
12
|
var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);
|
|
12
|
-
var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim);
|
|
13
13
|
|
|
14
14
|
// ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
|
|
15
15
|
/**
|
|
@@ -25,51 +25,121 @@
|
|
|
25
25
|
* @generated
|
|
26
26
|
* @see https://github.com/webgptorg/promptbook
|
|
27
27
|
*/
|
|
28
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.94.0-
|
|
28
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.94.0-5';
|
|
29
29
|
/**
|
|
30
30
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
31
31
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
35
|
+
* Freezes the given object and all its nested objects recursively
|
|
36
36
|
*
|
|
37
|
-
* Note: `$` is used to indicate that this function is not a pure function - it
|
|
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
|
|
38
39
|
*
|
|
40
|
+
* @returns The same object as the input, but deeply frozen
|
|
39
41
|
* @public exported from `@promptbook/utils`
|
|
40
42
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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;
|
|
46
56
|
}
|
|
47
|
-
`);
|
|
48
57
|
/**
|
|
49
|
-
* TODO: [
|
|
58
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
50
59
|
*/
|
|
51
60
|
|
|
52
61
|
/**
|
|
53
|
-
*
|
|
62
|
+
* Represents the uncertain value
|
|
54
63
|
*
|
|
55
|
-
*
|
|
64
|
+
* @public exported from `@promptbook/core`
|
|
65
|
+
*/
|
|
66
|
+
const ZERO_VALUE = $deepFreeze({ value: 0 });
|
|
67
|
+
/**
|
|
68
|
+
* Represents the uncertain value
|
|
56
69
|
*
|
|
57
|
-
* @public exported from `@promptbook/
|
|
70
|
+
* @public exported from `@promptbook/core`
|
|
58
71
|
*/
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
+
|
|
70
129
|
/**
|
|
71
|
-
*
|
|
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`
|
|
72
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
|
+
}
|
|
73
143
|
|
|
74
144
|
/**
|
|
75
145
|
* Name for the Promptbook
|
|
@@ -260,94 +330,6 @@
|
|
|
260
330
|
throw new WrappedError(whatWasThrown);
|
|
261
331
|
}
|
|
262
332
|
|
|
263
|
-
/**
|
|
264
|
-
* Generates random token
|
|
265
|
-
*
|
|
266
|
-
* Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
|
|
267
|
-
*
|
|
268
|
-
* @private internal helper function
|
|
269
|
-
* @returns secure random token
|
|
270
|
-
*/
|
|
271
|
-
function $randomToken(randomness) {
|
|
272
|
-
return crypto.randomBytes(randomness).toString('hex');
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* TODO: Maybe use nanoid instead https://github.com/ai/nanoid
|
|
276
|
-
*/
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* This error indicates errors during the execution of the pipeline
|
|
280
|
-
*
|
|
281
|
-
* @public exported from `@promptbook/core`
|
|
282
|
-
*/
|
|
283
|
-
class PipelineExecutionError extends Error {
|
|
284
|
-
constructor(message) {
|
|
285
|
-
// Added id parameter
|
|
286
|
-
super(message);
|
|
287
|
-
this.name = 'PipelineExecutionError';
|
|
288
|
-
// TODO: [🐙] DRY - Maybe $randomId
|
|
289
|
-
this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts */)}`;
|
|
290
|
-
Object.setPrototypeOf(this, PipelineExecutionError.prototype);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* TODO: [🧠][🌂] Add id to all errors
|
|
295
|
-
*/
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Simple wrapper `new Date().toISOString()`
|
|
299
|
-
*
|
|
300
|
-
* Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
|
|
301
|
-
*
|
|
302
|
-
* @returns string_date branded type
|
|
303
|
-
* @public exported from `@promptbook/utils`
|
|
304
|
-
*/
|
|
305
|
-
function $getCurrentDate() {
|
|
306
|
-
return new Date().toISOString();
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Orders JSON object by keys
|
|
311
|
-
*
|
|
312
|
-
* @returns The same type of object as the input re-ordered
|
|
313
|
-
* @public exported from `@promptbook/utils`
|
|
314
|
-
*/
|
|
315
|
-
function orderJson(options) {
|
|
316
|
-
const { value, order } = options;
|
|
317
|
-
const orderedValue = {
|
|
318
|
-
...(order === undefined ? {} : Object.fromEntries(order.map((key) => [key, undefined]))),
|
|
319
|
-
...value,
|
|
320
|
-
};
|
|
321
|
-
return orderedValue;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Freezes the given object and all its nested objects recursively
|
|
326
|
-
*
|
|
327
|
-
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
328
|
-
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
329
|
-
*
|
|
330
|
-
* @returns The same object as the input, but deeply frozen
|
|
331
|
-
* @public exported from `@promptbook/utils`
|
|
332
|
-
*/
|
|
333
|
-
function $deepFreeze(objectValue) {
|
|
334
|
-
if (Array.isArray(objectValue)) {
|
|
335
|
-
return Object.freeze(objectValue.map((item) => $deepFreeze(item)));
|
|
336
|
-
}
|
|
337
|
-
const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
338
|
-
for (const propertyName of propertyNames) {
|
|
339
|
-
const value = objectValue[propertyName];
|
|
340
|
-
if (value && typeof value === 'object') {
|
|
341
|
-
$deepFreeze(value);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
Object.freeze(objectValue);
|
|
345
|
-
return objectValue;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
349
|
-
*/
|
|
350
|
-
|
|
351
333
|
/**
|
|
352
334
|
* Checks if the value is [🚉] serializable as JSON
|
|
353
335
|
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
@@ -596,190 +578,59 @@
|
|
|
596
578
|
*/
|
|
597
579
|
|
|
598
580
|
/**
|
|
599
|
-
*
|
|
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
|
|
600
597
|
*
|
|
601
598
|
* @public exported from `@promptbook/core`
|
|
602
599
|
*/
|
|
603
|
-
class
|
|
600
|
+
class PipelineExecutionError extends Error {
|
|
604
601
|
constructor(message) {
|
|
602
|
+
// Added id parameter
|
|
605
603
|
super(message);
|
|
606
|
-
this.name = '
|
|
607
|
-
|
|
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);
|
|
608
608
|
}
|
|
609
609
|
}
|
|
610
|
+
/**
|
|
611
|
+
* TODO: [🧠][🌂] Add id to all errors
|
|
612
|
+
*/
|
|
610
613
|
|
|
611
614
|
/**
|
|
612
|
-
*
|
|
615
|
+
* Counts number of characters in the text
|
|
613
616
|
*
|
|
614
617
|
* @public exported from `@promptbook/utils`
|
|
615
618
|
*/
|
|
616
|
-
function
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
return VALUE_STRINGS.infinity;
|
|
625
|
-
}
|
|
626
|
-
else if (value === -Infinity) {
|
|
627
|
-
return VALUE_STRINGS.negativeInfinity;
|
|
628
|
-
}
|
|
629
|
-
for (let exponent = 0; exponent < 15; exponent++) {
|
|
630
|
-
const factor = 10 ** exponent;
|
|
631
|
-
const valueRounded = Math.round(value * factor) / factor;
|
|
632
|
-
if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
|
|
633
|
-
return valueRounded.toFixed(exponent);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
return value.toString();
|
|
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;
|
|
637
627
|
}
|
|
628
|
+
/**
|
|
629
|
+
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
630
|
+
*/
|
|
638
631
|
|
|
639
632
|
/**
|
|
640
|
-
*
|
|
641
|
-
* This is useful and used in the `templateParameters` function
|
|
642
|
-
*
|
|
643
|
-
* Note: This function is not just calling `toString` method
|
|
644
|
-
* It's more complex and can handle this conversion specifically for LLM models
|
|
645
|
-
* See `VALUE_STRINGS`
|
|
646
|
-
*
|
|
647
|
-
* Note: There are 2 similar functions
|
|
648
|
-
* - `valueToString` converts value to string for LLM models as human-readable string
|
|
649
|
-
* - `asSerializable` converts value to string to preserve full information to be able to convert it back
|
|
650
|
-
*
|
|
651
|
-
* @public exported from `@promptbook/utils`
|
|
652
|
-
*/
|
|
653
|
-
function valueToString(value) {
|
|
654
|
-
try {
|
|
655
|
-
if (value === '') {
|
|
656
|
-
return VALUE_STRINGS.empty;
|
|
657
|
-
}
|
|
658
|
-
else if (value === null) {
|
|
659
|
-
return VALUE_STRINGS.null;
|
|
660
|
-
}
|
|
661
|
-
else if (value === undefined) {
|
|
662
|
-
return VALUE_STRINGS.undefined;
|
|
663
|
-
}
|
|
664
|
-
else if (typeof value === 'string') {
|
|
665
|
-
return value;
|
|
666
|
-
}
|
|
667
|
-
else if (typeof value === 'number') {
|
|
668
|
-
return numberToString(value);
|
|
669
|
-
}
|
|
670
|
-
else if (value instanceof Date) {
|
|
671
|
-
return value.toISOString();
|
|
672
|
-
}
|
|
673
|
-
else {
|
|
674
|
-
try {
|
|
675
|
-
return JSON.stringify(value);
|
|
676
|
-
}
|
|
677
|
-
catch (error) {
|
|
678
|
-
if (error instanceof TypeError && error.message.includes('circular structure')) {
|
|
679
|
-
return VALUE_STRINGS.circular;
|
|
680
|
-
}
|
|
681
|
-
throw error;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
catch (error) {
|
|
686
|
-
assertsError(error);
|
|
687
|
-
console.error(error);
|
|
688
|
-
return VALUE_STRINGS.unserializable;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
/**
|
|
693
|
-
* Replaces parameters in template with values from parameters object
|
|
694
|
-
*
|
|
695
|
-
* Note: This function is not places strings into string,
|
|
696
|
-
* It's more complex and can handle this operation specifically for LLM models
|
|
697
|
-
*
|
|
698
|
-
* @param template the template with parameters in {curly} braces
|
|
699
|
-
* @param parameters the object with parameters
|
|
700
|
-
* @returns the template with replaced parameters
|
|
701
|
-
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
702
|
-
* @public exported from `@promptbook/utils`
|
|
703
|
-
*/
|
|
704
|
-
function templateParameters(template, parameters) {
|
|
705
|
-
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
706
|
-
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
707
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
708
|
-
}
|
|
709
|
-
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
710
|
-
// TODO: [🍵]
|
|
711
|
-
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
let replacedTemplates = template;
|
|
715
|
-
let match;
|
|
716
|
-
let loopLimit = LOOP_LIMIT;
|
|
717
|
-
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
718
|
-
.exec(replacedTemplates))) {
|
|
719
|
-
if (loopLimit-- < 0) {
|
|
720
|
-
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
721
|
-
}
|
|
722
|
-
const precol = match.groups.precol;
|
|
723
|
-
const parameterName = match.groups.parameterName;
|
|
724
|
-
if (parameterName === '') {
|
|
725
|
-
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
726
|
-
continue;
|
|
727
|
-
}
|
|
728
|
-
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
729
|
-
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
730
|
-
}
|
|
731
|
-
if (parameters[parameterName] === undefined) {
|
|
732
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
733
|
-
}
|
|
734
|
-
let parameterValue = parameters[parameterName];
|
|
735
|
-
if (parameterValue === undefined) {
|
|
736
|
-
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
737
|
-
}
|
|
738
|
-
parameterValue = valueToString(parameterValue);
|
|
739
|
-
// Escape curly braces in parameter values to prevent prompt-injection
|
|
740
|
-
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
741
|
-
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
742
|
-
parameterValue = parameterValue
|
|
743
|
-
.split('\n')
|
|
744
|
-
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
745
|
-
.join('\n');
|
|
746
|
-
}
|
|
747
|
-
replacedTemplates =
|
|
748
|
-
replacedTemplates.substring(0, match.index + precol.length) +
|
|
749
|
-
parameterValue +
|
|
750
|
-
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
751
|
-
}
|
|
752
|
-
// [💫] Check if there are parameters that are not closed properly
|
|
753
|
-
if (/{\w+$/.test(replacedTemplates)) {
|
|
754
|
-
throw new PipelineExecutionError('Parameter is not closed');
|
|
755
|
-
}
|
|
756
|
-
// [💫] Check if there are parameters that are not opened properly
|
|
757
|
-
if (/^\w+}/.test(replacedTemplates)) {
|
|
758
|
-
throw new PipelineExecutionError('Parameter is not opened');
|
|
759
|
-
}
|
|
760
|
-
return replacedTemplates;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
* Counts number of characters in the text
|
|
765
|
-
*
|
|
766
|
-
* @public exported from `@promptbook/utils`
|
|
767
|
-
*/
|
|
768
|
-
function countCharacters(text) {
|
|
769
|
-
// Remove null characters
|
|
770
|
-
text = text.replace(/\0/g, '');
|
|
771
|
-
// Replace emojis (and also ZWJ sequence) with hyphens
|
|
772
|
-
text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
|
|
773
|
-
text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
|
|
774
|
-
text = text.replace(/\p{Extended_Pictographic}(\u{200D}\p{Extended_Pictographic})*/gu, '-');
|
|
775
|
-
return text.length;
|
|
776
|
-
}
|
|
777
|
-
/**
|
|
778
|
-
* TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
|
|
779
|
-
*/
|
|
780
|
-
|
|
781
|
-
/**
|
|
782
|
-
* Number of characters per standard line with 11pt Arial font size.
|
|
633
|
+
* Number of characters per standard line with 11pt Arial font size.
|
|
783
634
|
*
|
|
784
635
|
* @public exported from `@promptbook/utils`
|
|
785
636
|
*/
|
|
@@ -1154,74 +1005,6 @@
|
|
|
1154
1005
|
};
|
|
1155
1006
|
}
|
|
1156
1007
|
|
|
1157
|
-
/**
|
|
1158
|
-
* Represents the uncertain value
|
|
1159
|
-
*
|
|
1160
|
-
* @public exported from `@promptbook/core`
|
|
1161
|
-
*/
|
|
1162
|
-
const ZERO_VALUE = $deepFreeze({ value: 0 });
|
|
1163
|
-
/**
|
|
1164
|
-
* Represents the uncertain value
|
|
1165
|
-
*
|
|
1166
|
-
* @public exported from `@promptbook/core`
|
|
1167
|
-
*/
|
|
1168
|
-
const UNCERTAIN_ZERO_VALUE = $deepFreeze({ value: 0, isUncertain: true });
|
|
1169
|
-
/**
|
|
1170
|
-
* Represents the usage with no resources consumed
|
|
1171
|
-
*
|
|
1172
|
-
* @public exported from `@promptbook/core`
|
|
1173
|
-
*/
|
|
1174
|
-
$deepFreeze({
|
|
1175
|
-
price: ZERO_VALUE,
|
|
1176
|
-
input: {
|
|
1177
|
-
tokensCount: ZERO_VALUE,
|
|
1178
|
-
charactersCount: ZERO_VALUE,
|
|
1179
|
-
wordsCount: ZERO_VALUE,
|
|
1180
|
-
sentencesCount: ZERO_VALUE,
|
|
1181
|
-
linesCount: ZERO_VALUE,
|
|
1182
|
-
paragraphsCount: ZERO_VALUE,
|
|
1183
|
-
pagesCount: ZERO_VALUE,
|
|
1184
|
-
},
|
|
1185
|
-
output: {
|
|
1186
|
-
tokensCount: ZERO_VALUE,
|
|
1187
|
-
charactersCount: ZERO_VALUE,
|
|
1188
|
-
wordsCount: ZERO_VALUE,
|
|
1189
|
-
sentencesCount: ZERO_VALUE,
|
|
1190
|
-
linesCount: ZERO_VALUE,
|
|
1191
|
-
paragraphsCount: ZERO_VALUE,
|
|
1192
|
-
pagesCount: ZERO_VALUE,
|
|
1193
|
-
},
|
|
1194
|
-
});
|
|
1195
|
-
/**
|
|
1196
|
-
* Represents the usage with unknown resources consumed
|
|
1197
|
-
*
|
|
1198
|
-
* @public exported from `@promptbook/core`
|
|
1199
|
-
*/
|
|
1200
|
-
$deepFreeze({
|
|
1201
|
-
price: UNCERTAIN_ZERO_VALUE,
|
|
1202
|
-
input: {
|
|
1203
|
-
tokensCount: UNCERTAIN_ZERO_VALUE,
|
|
1204
|
-
charactersCount: UNCERTAIN_ZERO_VALUE,
|
|
1205
|
-
wordsCount: UNCERTAIN_ZERO_VALUE,
|
|
1206
|
-
sentencesCount: UNCERTAIN_ZERO_VALUE,
|
|
1207
|
-
linesCount: UNCERTAIN_ZERO_VALUE,
|
|
1208
|
-
paragraphsCount: UNCERTAIN_ZERO_VALUE,
|
|
1209
|
-
pagesCount: UNCERTAIN_ZERO_VALUE,
|
|
1210
|
-
},
|
|
1211
|
-
output: {
|
|
1212
|
-
tokensCount: UNCERTAIN_ZERO_VALUE,
|
|
1213
|
-
charactersCount: UNCERTAIN_ZERO_VALUE,
|
|
1214
|
-
wordsCount: UNCERTAIN_ZERO_VALUE,
|
|
1215
|
-
sentencesCount: UNCERTAIN_ZERO_VALUE,
|
|
1216
|
-
linesCount: UNCERTAIN_ZERO_VALUE,
|
|
1217
|
-
paragraphsCount: UNCERTAIN_ZERO_VALUE,
|
|
1218
|
-
pagesCount: UNCERTAIN_ZERO_VALUE,
|
|
1219
|
-
},
|
|
1220
|
-
});
|
|
1221
|
-
/**
|
|
1222
|
-
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1223
|
-
*/
|
|
1224
|
-
|
|
1225
1008
|
/**
|
|
1226
1009
|
* Make UncertainNumber
|
|
1227
1010
|
*
|
|
@@ -1241,11 +1024,11 @@
|
|
|
1241
1024
|
}
|
|
1242
1025
|
|
|
1243
1026
|
/**
|
|
1244
|
-
*
|
|
1027
|
+
* Create price per one token based on the string value found on openai page
|
|
1245
1028
|
*
|
|
1246
1029
|
* @private within the repository, used only as internal helper for `OPENAI_MODELS`
|
|
1247
1030
|
*/
|
|
1248
|
-
function
|
|
1031
|
+
function pricing(value) {
|
|
1249
1032
|
const [price, tokens] = value.split(' / ');
|
|
1250
1033
|
return parseFloat(price.replace('$', '')) / parseFloat(tokens.replace('M tokens', '')) / 1000000;
|
|
1251
1034
|
}
|
|
@@ -1281,8 +1064,8 @@
|
|
|
1281
1064
|
modelName: 'davinci-002',
|
|
1282
1065
|
modelDescription: 'Legacy completion model with strong performance on text generation tasks. Optimized for complex instructions and longer outputs.',
|
|
1283
1066
|
pricing: {
|
|
1284
|
-
prompt:
|
|
1285
|
-
output:
|
|
1067
|
+
prompt: pricing(`$2.00 / 1M tokens`),
|
|
1068
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1286
1069
|
},
|
|
1287
1070
|
},
|
|
1288
1071
|
/**/
|
|
@@ -1299,8 +1082,8 @@
|
|
|
1299
1082
|
modelName: 'gpt-3.5-turbo-16k',
|
|
1300
1083
|
modelDescription: 'GPT-3.5 Turbo with extended 16k token context length for handling longer conversations and documents.',
|
|
1301
1084
|
pricing: {
|
|
1302
|
-
prompt:
|
|
1303
|
-
output:
|
|
1085
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1086
|
+
output: pricing(`$4.00 / 1M tokens`),
|
|
1304
1087
|
},
|
|
1305
1088
|
},
|
|
1306
1089
|
/**/
|
|
@@ -1323,8 +1106,8 @@
|
|
|
1323
1106
|
modelName: 'gpt-4',
|
|
1324
1107
|
modelDescription: 'GPT-4 is a powerful language model with enhanced reasoning, instruction-following capabilities, and 8K context window. Optimized for complex tasks requiring deep understanding.',
|
|
1325
1108
|
pricing: {
|
|
1326
|
-
prompt:
|
|
1327
|
-
output:
|
|
1109
|
+
prompt: pricing(`$30.00 / 1M tokens`),
|
|
1110
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1328
1111
|
},
|
|
1329
1112
|
},
|
|
1330
1113
|
/**/
|
|
@@ -1335,8 +1118,8 @@
|
|
|
1335
1118
|
modelName: 'gpt-4-32k',
|
|
1336
1119
|
modelDescription: 'Extended context version of GPT-4 with a 32K token window for processing very long inputs and generating comprehensive responses for complex tasks.',
|
|
1337
1120
|
pricing: {
|
|
1338
|
-
prompt:
|
|
1339
|
-
output:
|
|
1121
|
+
prompt: pricing(`$60.00 / 1M tokens`),
|
|
1122
|
+
output: pricing(`$120.00 / 1M tokens`),
|
|
1340
1123
|
},
|
|
1341
1124
|
},
|
|
1342
1125
|
/**/
|
|
@@ -1358,8 +1141,8 @@
|
|
|
1358
1141
|
modelName: 'gpt-4-turbo-2024-04-09',
|
|
1359
1142
|
modelDescription: 'Latest stable GPT-4 Turbo model from April 2024 with enhanced reasoning and context handling capabilities. Offers 128K context window and improved performance.',
|
|
1360
1143
|
pricing: {
|
|
1361
|
-
prompt:
|
|
1362
|
-
output:
|
|
1144
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1145
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1363
1146
|
},
|
|
1364
1147
|
},
|
|
1365
1148
|
/**/
|
|
@@ -1370,8 +1153,8 @@
|
|
|
1370
1153
|
modelName: 'gpt-3.5-turbo-1106',
|
|
1371
1154
|
modelDescription: 'November 2023 version of GPT-3.5 Turbo with improved instruction following and a 16K token context window.',
|
|
1372
1155
|
pricing: {
|
|
1373
|
-
prompt:
|
|
1374
|
-
output:
|
|
1156
|
+
prompt: pricing(`$1.00 / 1M tokens`),
|
|
1157
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1375
1158
|
},
|
|
1376
1159
|
},
|
|
1377
1160
|
/**/
|
|
@@ -1382,8 +1165,8 @@
|
|
|
1382
1165
|
modelName: 'gpt-4-turbo',
|
|
1383
1166
|
modelDescription: 'More capable model than GPT-4 with improved instruction following, function calling and a 128K token context window for handling very large documents.',
|
|
1384
1167
|
pricing: {
|
|
1385
|
-
prompt:
|
|
1386
|
-
output:
|
|
1168
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1169
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1387
1170
|
},
|
|
1388
1171
|
},
|
|
1389
1172
|
/**/
|
|
@@ -1394,8 +1177,8 @@
|
|
|
1394
1177
|
modelName: 'gpt-3.5-turbo-instruct-0914',
|
|
1395
1178
|
modelDescription: 'September 2023 version of GPT-3.5 Turbo optimized for completion-style instruction following with a 4K context window.',
|
|
1396
1179
|
pricing: {
|
|
1397
|
-
prompt:
|
|
1398
|
-
output:
|
|
1180
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1181
|
+
output: pricing(`$2.00 / 1M tokens`), // <- For gpt-3.5-turbo-instruct
|
|
1399
1182
|
},
|
|
1400
1183
|
},
|
|
1401
1184
|
/**/
|
|
@@ -1406,8 +1189,8 @@
|
|
|
1406
1189
|
modelName: 'gpt-3.5-turbo-instruct',
|
|
1407
1190
|
modelDescription: 'Optimized version of GPT-3.5 for completion-style API with good instruction following and a 4K token context window.',
|
|
1408
1191
|
pricing: {
|
|
1409
|
-
prompt:
|
|
1410
|
-
output:
|
|
1192
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1193
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1411
1194
|
},
|
|
1412
1195
|
},
|
|
1413
1196
|
/**/
|
|
@@ -1424,8 +1207,8 @@
|
|
|
1424
1207
|
modelName: 'gpt-3.5-turbo',
|
|
1425
1208
|
modelDescription: 'Latest version of GPT-3.5 Turbo with improved performance and instruction following capabilities. Default 4K context window with options for 16K.',
|
|
1426
1209
|
pricing: {
|
|
1427
|
-
prompt:
|
|
1428
|
-
output:
|
|
1210
|
+
prompt: pricing(`$0.50 / 1M tokens`),
|
|
1211
|
+
output: pricing(`$1.50 / 1M tokens`),
|
|
1429
1212
|
},
|
|
1430
1213
|
},
|
|
1431
1214
|
/**/
|
|
@@ -1436,8 +1219,8 @@
|
|
|
1436
1219
|
modelName: 'gpt-3.5-turbo-0301',
|
|
1437
1220
|
modelDescription: 'March 2023 version of GPT-3.5 Turbo with a 4K token context window. Legacy model maintained for backward compatibility.',
|
|
1438
1221
|
pricing: {
|
|
1439
|
-
prompt:
|
|
1440
|
-
output:
|
|
1222
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1223
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1441
1224
|
},
|
|
1442
1225
|
},
|
|
1443
1226
|
/**/
|
|
@@ -1448,8 +1231,8 @@
|
|
|
1448
1231
|
modelName: 'babbage-002',
|
|
1449
1232
|
modelDescription: 'Efficient legacy completion model with a good balance of performance and speed. Suitable for straightforward text generation tasks.',
|
|
1450
1233
|
pricing: {
|
|
1451
|
-
prompt:
|
|
1452
|
-
output:
|
|
1234
|
+
prompt: pricing(`$0.40 / 1M tokens`),
|
|
1235
|
+
output: pricing(`$0.40 / 1M tokens`),
|
|
1453
1236
|
},
|
|
1454
1237
|
},
|
|
1455
1238
|
/**/
|
|
@@ -1460,8 +1243,8 @@
|
|
|
1460
1243
|
modelName: 'gpt-4-1106-preview',
|
|
1461
1244
|
modelDescription: 'November 2023 preview version of GPT-4 Turbo with improved instruction following and a 128K token context window.',
|
|
1462
1245
|
pricing: {
|
|
1463
|
-
prompt:
|
|
1464
|
-
output:
|
|
1246
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1247
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1465
1248
|
},
|
|
1466
1249
|
},
|
|
1467
1250
|
/**/
|
|
@@ -1472,8 +1255,8 @@
|
|
|
1472
1255
|
modelName: 'gpt-4-0125-preview',
|
|
1473
1256
|
modelDescription: 'January 2024 preview version of GPT-4 Turbo with improved reasoning capabilities and a 128K token context window.',
|
|
1474
1257
|
pricing: {
|
|
1475
|
-
prompt:
|
|
1476
|
-
output:
|
|
1258
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1259
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1477
1260
|
},
|
|
1478
1261
|
},
|
|
1479
1262
|
/**/
|
|
@@ -1490,8 +1273,8 @@
|
|
|
1490
1273
|
modelName: 'gpt-3.5-turbo-0125',
|
|
1491
1274
|
modelDescription: 'January 2024 version of GPT-3.5 Turbo with improved reasoning capabilities and a 16K token context window.',
|
|
1492
1275
|
pricing: {
|
|
1493
|
-
prompt:
|
|
1494
|
-
output:
|
|
1276
|
+
prompt: pricing(`$0.50 / 1M tokens`),
|
|
1277
|
+
output: pricing(`$1.50 / 1M tokens`),
|
|
1495
1278
|
},
|
|
1496
1279
|
},
|
|
1497
1280
|
/**/
|
|
@@ -1502,8 +1285,8 @@
|
|
|
1502
1285
|
modelName: 'gpt-4-turbo-preview',
|
|
1503
1286
|
modelDescription: 'Preview version of GPT-4 Turbo that points to the latest model version. Features improved instruction following, 128K token context window and lower latency.',
|
|
1504
1287
|
pricing: {
|
|
1505
|
-
prompt:
|
|
1506
|
-
output:
|
|
1288
|
+
prompt: pricing(`$10.00 / 1M tokens`),
|
|
1289
|
+
output: pricing(`$30.00 / 1M tokens`),
|
|
1507
1290
|
},
|
|
1508
1291
|
},
|
|
1509
1292
|
/**/
|
|
@@ -1514,7 +1297,7 @@
|
|
|
1514
1297
|
modelName: 'text-embedding-3-large',
|
|
1515
1298
|
modelDescription: "OpenAI's most capable text embedding model designed for high-quality embeddings for complex similarity tasks and information retrieval.",
|
|
1516
1299
|
pricing: {
|
|
1517
|
-
prompt:
|
|
1300
|
+
prompt: pricing(`$0.13 / 1M tokens`),
|
|
1518
1301
|
// TODO: [🏏] Leverage the batch API @see https://platform.openai.com/docs/guides/batch
|
|
1519
1302
|
output: 0, // <- Note: [🆖] In Embedding models you dont pay for output
|
|
1520
1303
|
},
|
|
@@ -1527,7 +1310,7 @@
|
|
|
1527
1310
|
modelName: 'text-embedding-3-small',
|
|
1528
1311
|
modelDescription: 'Cost-effective embedding model with good performance for simpler tasks like text similarity and retrieval. Good balance of quality and efficiency.',
|
|
1529
1312
|
pricing: {
|
|
1530
|
-
prompt:
|
|
1313
|
+
prompt: pricing(`$0.02 / 1M tokens`),
|
|
1531
1314
|
// TODO: [🏏] Leverage the batch API @see https://platform.openai.com/docs/guides/batch
|
|
1532
1315
|
output: 0, // <- Note: [🆖] In Embedding models you dont pay for output
|
|
1533
1316
|
},
|
|
@@ -1540,8 +1323,8 @@
|
|
|
1540
1323
|
modelName: 'gpt-3.5-turbo-0613',
|
|
1541
1324
|
modelDescription: 'June 2023 version of GPT-3.5 Turbo with function calling capabilities and a 4K token context window.',
|
|
1542
1325
|
pricing: {
|
|
1543
|
-
prompt:
|
|
1544
|
-
output:
|
|
1326
|
+
prompt: pricing(`$1.50 / 1M tokens`),
|
|
1327
|
+
output: pricing(`$2.00 / 1M tokens`),
|
|
1545
1328
|
},
|
|
1546
1329
|
},
|
|
1547
1330
|
/**/
|
|
@@ -1552,7 +1335,7 @@
|
|
|
1552
1335
|
modelName: 'text-embedding-ada-002',
|
|
1553
1336
|
modelDescription: 'Legacy text embedding model suitable for text similarity and retrieval augmented generation use cases. Replaced by newer embedding-3 models.',
|
|
1554
1337
|
pricing: {
|
|
1555
|
-
prompt:
|
|
1338
|
+
prompt: pricing(`$0.1 / 1M tokens`),
|
|
1556
1339
|
// TODO: [🏏] Leverage the batch API @see https://platform.openai.com/docs/guides/batch
|
|
1557
1340
|
output: 0, // <- Note: [🆖] In Embedding models you dont pay for output
|
|
1558
1341
|
},
|
|
@@ -1583,8 +1366,8 @@
|
|
|
1583
1366
|
modelName: 'gpt-4o-2024-05-13',
|
|
1584
1367
|
modelDescription: 'May 2024 version of GPT-4o with enhanced multimodal capabilities, improved reasoning, and optimized for vision, audio and chat at lower latencies.',
|
|
1585
1368
|
pricing: {
|
|
1586
|
-
prompt:
|
|
1587
|
-
output:
|
|
1369
|
+
prompt: pricing(`$5.00 / 1M tokens`),
|
|
1370
|
+
output: pricing(`$15.00 / 1M tokens`),
|
|
1588
1371
|
},
|
|
1589
1372
|
},
|
|
1590
1373
|
/**/
|
|
@@ -1595,8 +1378,8 @@
|
|
|
1595
1378
|
modelName: 'gpt-4o',
|
|
1596
1379
|
modelDescription: "OpenAI's most advanced multimodal model optimized for performance, speed, and cost. Capable of vision, reasoning, and high quality text generation.",
|
|
1597
1380
|
pricing: {
|
|
1598
|
-
prompt:
|
|
1599
|
-
output:
|
|
1381
|
+
prompt: pricing(`$5.00 / 1M tokens`),
|
|
1382
|
+
output: pricing(`$15.00 / 1M tokens`),
|
|
1600
1383
|
},
|
|
1601
1384
|
},
|
|
1602
1385
|
/**/
|
|
@@ -1607,8 +1390,8 @@
|
|
|
1607
1390
|
modelName: 'gpt-4o-mini',
|
|
1608
1391
|
modelDescription: 'Smaller, more cost-effective version of GPT-4o with good performance across text, vision, and audio tasks at reduced complexity.',
|
|
1609
1392
|
pricing: {
|
|
1610
|
-
prompt:
|
|
1611
|
-
output:
|
|
1393
|
+
prompt: pricing(`$0.15 / 1M tokens`),
|
|
1394
|
+
output: pricing(`$0.60 / 1M tokens`),
|
|
1612
1395
|
},
|
|
1613
1396
|
},
|
|
1614
1397
|
/**/
|
|
@@ -1619,8 +1402,8 @@
|
|
|
1619
1402
|
modelName: 'o1-preview',
|
|
1620
1403
|
modelDescription: 'Advanced reasoning model with exceptional performance on complex logical, mathematical, and analytical tasks. Built for deep reasoning and specialized professional tasks.',
|
|
1621
1404
|
pricing: {
|
|
1622
|
-
prompt:
|
|
1623
|
-
output:
|
|
1405
|
+
prompt: pricing(`$15.00 / 1M tokens`),
|
|
1406
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1624
1407
|
},
|
|
1625
1408
|
},
|
|
1626
1409
|
/**/
|
|
@@ -1632,8 +1415,8 @@
|
|
|
1632
1415
|
modelDescription: 'September 2024 version of O1 preview with specialized reasoning capabilities for complex tasks requiring precise analytical thinking.',
|
|
1633
1416
|
// <- TODO: [💩] Some better system to organize these date suffixes and versions
|
|
1634
1417
|
pricing: {
|
|
1635
|
-
prompt:
|
|
1636
|
-
output:
|
|
1418
|
+
prompt: pricing(`$15.00 / 1M tokens`),
|
|
1419
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1637
1420
|
},
|
|
1638
1421
|
},
|
|
1639
1422
|
/**/
|
|
@@ -1644,8 +1427,8 @@
|
|
|
1644
1427
|
modelName: 'o1-mini',
|
|
1645
1428
|
modelDescription: 'Smaller, cost-effective version of the O1 model with good performance on reasoning tasks while maintaining efficiency for everyday analytical use.',
|
|
1646
1429
|
pricing: {
|
|
1647
|
-
prompt:
|
|
1648
|
-
output:
|
|
1430
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1431
|
+
output: pricing(`$12.00 / 1M tokens`),
|
|
1649
1432
|
},
|
|
1650
1433
|
},
|
|
1651
1434
|
/**/
|
|
@@ -1656,8 +1439,8 @@
|
|
|
1656
1439
|
modelName: 'o1',
|
|
1657
1440
|
modelDescription: "OpenAI's advanced reasoning model focused on logic and problem-solving. Designed for complex analytical tasks with rigorous step-by-step reasoning. 128K context window.",
|
|
1658
1441
|
pricing: {
|
|
1659
|
-
prompt:
|
|
1660
|
-
output:
|
|
1442
|
+
prompt: pricing(`$15.00 / 1M tokens`),
|
|
1443
|
+
output: pricing(`$60.00 / 1M tokens`),
|
|
1661
1444
|
},
|
|
1662
1445
|
},
|
|
1663
1446
|
/**/
|
|
@@ -1668,8 +1451,8 @@
|
|
|
1668
1451
|
modelName: 'o3-mini',
|
|
1669
1452
|
modelDescription: 'Cost-effective reasoning model optimized for academic and scientific problem-solving. Efficient performance on STEM tasks with deep mathematical and scientific knowledge. 128K context window.',
|
|
1670
1453
|
pricing: {
|
|
1671
|
-
prompt:
|
|
1672
|
-
output:
|
|
1454
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1455
|
+
output: pricing(`$12.00 / 1M tokens`),
|
|
1673
1456
|
// <- TODO: !! Unsure, check the pricing
|
|
1674
1457
|
},
|
|
1675
1458
|
},
|
|
@@ -1681,8 +1464,8 @@
|
|
|
1681
1464
|
modelName: 'o1-mini-2024-09-12',
|
|
1682
1465
|
modelDescription: "September 2024 version of O1-mini with balanced reasoning capabilities and cost-efficiency. Good for analytical tasks that don't require the full O1 model.",
|
|
1683
1466
|
pricing: {
|
|
1684
|
-
prompt:
|
|
1685
|
-
output:
|
|
1467
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1468
|
+
output: pricing(`$12.00 / 1M tokens`),
|
|
1686
1469
|
},
|
|
1687
1470
|
},
|
|
1688
1471
|
/**/
|
|
@@ -1693,8 +1476,8 @@
|
|
|
1693
1476
|
modelName: 'gpt-3.5-turbo-16k-0613',
|
|
1694
1477
|
modelDescription: 'June 2023 version of GPT-3.5 Turbo with extended 16k token context window for processing longer conversations and documents.',
|
|
1695
1478
|
pricing: {
|
|
1696
|
-
prompt:
|
|
1697
|
-
output:
|
|
1479
|
+
prompt: pricing(`$3.00 / 1M tokens`),
|
|
1480
|
+
output: pricing(`$4.00 / 1M tokens`),
|
|
1698
1481
|
},
|
|
1699
1482
|
},
|
|
1700
1483
|
/**/
|
|
@@ -1769,36 +1552,207 @@
|
|
|
1769
1552
|
*/
|
|
1770
1553
|
|
|
1771
1554
|
/**
|
|
1772
|
-
*
|
|
1555
|
+
* Simple wrapper `new Date().toISOString()`
|
|
1773
1556
|
*
|
|
1774
|
-
*
|
|
1557
|
+
* Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time
|
|
1558
|
+
*
|
|
1559
|
+
* @returns string_date branded type
|
|
1560
|
+
* @public exported from `@promptbook/utils`
|
|
1775
1561
|
*/
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
this.
|
|
1790
|
-
minTime: 60000 / (this.options.maxRequestsPerMinute || DEFAULT_MAX_REQUESTS_PER_MINUTE),
|
|
1791
|
-
});
|
|
1562
|
+
function $getCurrentDate() {
|
|
1563
|
+
return new Date().toISOString();
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
/**
|
|
1567
|
+
* This error type indicates that some limit was reached
|
|
1568
|
+
*
|
|
1569
|
+
* @public exported from `@promptbook/core`
|
|
1570
|
+
*/
|
|
1571
|
+
class LimitReachedError extends Error {
|
|
1572
|
+
constructor(message) {
|
|
1573
|
+
super(message);
|
|
1574
|
+
this.name = 'LimitReachedError';
|
|
1575
|
+
Object.setPrototypeOf(this, LimitReachedError.prototype);
|
|
1792
1576
|
}
|
|
1793
|
-
|
|
1794
|
-
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
/**
|
|
1580
|
+
* Format either small or big number
|
|
1581
|
+
*
|
|
1582
|
+
* @public exported from `@promptbook/utils`
|
|
1583
|
+
*/
|
|
1584
|
+
function numberToString(value) {
|
|
1585
|
+
if (value === 0) {
|
|
1586
|
+
return '0';
|
|
1795
1587
|
}
|
|
1796
|
-
|
|
1797
|
-
return
|
|
1588
|
+
else if (Number.isNaN(value)) {
|
|
1589
|
+
return VALUE_STRINGS.nan;
|
|
1798
1590
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1591
|
+
else if (value === Infinity) {
|
|
1592
|
+
return VALUE_STRINGS.infinity;
|
|
1593
|
+
}
|
|
1594
|
+
else if (value === -Infinity) {
|
|
1595
|
+
return VALUE_STRINGS.negativeInfinity;
|
|
1596
|
+
}
|
|
1597
|
+
for (let exponent = 0; exponent < 15; exponent++) {
|
|
1598
|
+
const factor = 10 ** exponent;
|
|
1599
|
+
const valueRounded = Math.round(value * factor) / factor;
|
|
1600
|
+
if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {
|
|
1601
|
+
return valueRounded.toFixed(exponent);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
return value.toString();
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
/**
|
|
1608
|
+
* Function `valueToString` will convert the given value to string
|
|
1609
|
+
* This is useful and used in the `templateParameters` function
|
|
1610
|
+
*
|
|
1611
|
+
* Note: This function is not just calling `toString` method
|
|
1612
|
+
* It's more complex and can handle this conversion specifically for LLM models
|
|
1613
|
+
* See `VALUE_STRINGS`
|
|
1614
|
+
*
|
|
1615
|
+
* Note: There are 2 similar functions
|
|
1616
|
+
* - `valueToString` converts value to string for LLM models as human-readable string
|
|
1617
|
+
* - `asSerializable` converts value to string to preserve full information to be able to convert it back
|
|
1618
|
+
*
|
|
1619
|
+
* @public exported from `@promptbook/utils`
|
|
1620
|
+
*/
|
|
1621
|
+
function valueToString(value) {
|
|
1622
|
+
try {
|
|
1623
|
+
if (value === '') {
|
|
1624
|
+
return VALUE_STRINGS.empty;
|
|
1625
|
+
}
|
|
1626
|
+
else if (value === null) {
|
|
1627
|
+
return VALUE_STRINGS.null;
|
|
1628
|
+
}
|
|
1629
|
+
else if (value === undefined) {
|
|
1630
|
+
return VALUE_STRINGS.undefined;
|
|
1631
|
+
}
|
|
1632
|
+
else if (typeof value === 'string') {
|
|
1633
|
+
return value;
|
|
1634
|
+
}
|
|
1635
|
+
else if (typeof value === 'number') {
|
|
1636
|
+
return numberToString(value);
|
|
1637
|
+
}
|
|
1638
|
+
else if (value instanceof Date) {
|
|
1639
|
+
return value.toISOString();
|
|
1640
|
+
}
|
|
1641
|
+
else {
|
|
1642
|
+
try {
|
|
1643
|
+
return JSON.stringify(value);
|
|
1644
|
+
}
|
|
1645
|
+
catch (error) {
|
|
1646
|
+
if (error instanceof TypeError && error.message.includes('circular structure')) {
|
|
1647
|
+
return VALUE_STRINGS.circular;
|
|
1648
|
+
}
|
|
1649
|
+
throw error;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
catch (error) {
|
|
1654
|
+
assertsError(error);
|
|
1655
|
+
console.error(error);
|
|
1656
|
+
return VALUE_STRINGS.unserializable;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
/**
|
|
1661
|
+
* Replaces parameters in template with values from parameters object
|
|
1662
|
+
*
|
|
1663
|
+
* Note: This function is not places strings into string,
|
|
1664
|
+
* It's more complex and can handle this operation specifically for LLM models
|
|
1665
|
+
*
|
|
1666
|
+
* @param template the template with parameters in {curly} braces
|
|
1667
|
+
* @param parameters the object with parameters
|
|
1668
|
+
* @returns the template with replaced parameters
|
|
1669
|
+
* @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
|
|
1670
|
+
* @public exported from `@promptbook/utils`
|
|
1671
|
+
*/
|
|
1672
|
+
function templateParameters(template, parameters) {
|
|
1673
|
+
for (const [parameterName, parameterValue] of Object.entries(parameters)) {
|
|
1674
|
+
if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
|
|
1675
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` has missing value`);
|
|
1676
|
+
}
|
|
1677
|
+
else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
|
|
1678
|
+
// TODO: [🍵]
|
|
1679
|
+
throw new UnexpectedError(`Parameter \`{${parameterName}}\` is restricted to use`);
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
let replacedTemplates = template;
|
|
1683
|
+
let match;
|
|
1684
|
+
let loopLimit = LOOP_LIMIT;
|
|
1685
|
+
while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
|
|
1686
|
+
.exec(replacedTemplates))) {
|
|
1687
|
+
if (loopLimit-- < 0) {
|
|
1688
|
+
throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');
|
|
1689
|
+
}
|
|
1690
|
+
const precol = match.groups.precol;
|
|
1691
|
+
const parameterName = match.groups.parameterName;
|
|
1692
|
+
if (parameterName === '') {
|
|
1693
|
+
// Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1696
|
+
if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
|
|
1697
|
+
throw new PipelineExecutionError('Parameter is already opened or not closed');
|
|
1698
|
+
}
|
|
1699
|
+
if (parameters[parameterName] === undefined) {
|
|
1700
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
1701
|
+
}
|
|
1702
|
+
let parameterValue = parameters[parameterName];
|
|
1703
|
+
if (parameterValue === undefined) {
|
|
1704
|
+
throw new PipelineExecutionError(`Parameter \`{${parameterName}}\` is not defined`);
|
|
1705
|
+
}
|
|
1706
|
+
parameterValue = valueToString(parameterValue);
|
|
1707
|
+
// Escape curly braces in parameter values to prevent prompt-injection
|
|
1708
|
+
parameterValue = parameterValue.replace(/[{}]/g, '\\$&');
|
|
1709
|
+
if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
|
|
1710
|
+
parameterValue = parameterValue
|
|
1711
|
+
.split('\n')
|
|
1712
|
+
.map((line, index) => (index === 0 ? line : `${precol}${line}`))
|
|
1713
|
+
.join('\n');
|
|
1714
|
+
}
|
|
1715
|
+
replacedTemplates =
|
|
1716
|
+
replacedTemplates.substring(0, match.index + precol.length) +
|
|
1717
|
+
parameterValue +
|
|
1718
|
+
replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);
|
|
1719
|
+
}
|
|
1720
|
+
// [💫] Check if there are parameters that are not closed properly
|
|
1721
|
+
if (/{\w+$/.test(replacedTemplates)) {
|
|
1722
|
+
throw new PipelineExecutionError('Parameter is not closed');
|
|
1723
|
+
}
|
|
1724
|
+
// [💫] Check if there are parameters that are not opened properly
|
|
1725
|
+
if (/^\w+}/.test(replacedTemplates)) {
|
|
1726
|
+
throw new PipelineExecutionError('Parameter is not opened');
|
|
1727
|
+
}
|
|
1728
|
+
return replacedTemplates;
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
/**
|
|
1732
|
+
* Execution Tools for calling OpenAI API or other OpeenAI compatible provider
|
|
1733
|
+
*
|
|
1734
|
+
* @public exported from `@promptbook/openai`
|
|
1735
|
+
*/
|
|
1736
|
+
class OpenAiCompatibleExecutionTools {
|
|
1737
|
+
/**
|
|
1738
|
+
* Creates OpenAI compatible Execution Tools.
|
|
1739
|
+
*
|
|
1740
|
+
* @param options which are relevant are directly passed to the OpenAI compatible client
|
|
1741
|
+
*/
|
|
1742
|
+
constructor(options) {
|
|
1743
|
+
this.options = options;
|
|
1744
|
+
/**
|
|
1745
|
+
* OpenAI API client.
|
|
1746
|
+
*/
|
|
1747
|
+
this.client = null;
|
|
1748
|
+
// TODO: Allow configuring rate limits via options
|
|
1749
|
+
this.limiter = new Bottleneck__default["default"]({
|
|
1750
|
+
minTime: 60000 / (this.options.maxRequestsPerMinute || DEFAULT_MAX_REQUESTS_PER_MINUTE),
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
async getClient() {
|
|
1754
|
+
if (this.client === null) {
|
|
1755
|
+
// Note: Passing only OpenAI relevant options to OpenAI constructor
|
|
1802
1756
|
const openAiOptions = { ...this.options };
|
|
1803
1757
|
delete openAiOptions.isVerbose;
|
|
1804
1758
|
delete openAiOptions.userId;
|
|
@@ -1806,18 +1760,6 @@
|
|
|
1806
1760
|
}
|
|
1807
1761
|
return this.client;
|
|
1808
1762
|
}
|
|
1809
|
-
/*
|
|
1810
|
-
Note: Commenting this out to avoid circular dependency
|
|
1811
|
-
/**
|
|
1812
|
-
* Create (sub)tools for calling OpenAI API Assistants
|
|
1813
|
-
*
|
|
1814
|
-
* @param assistantId Which assistant to use
|
|
1815
|
-
* @returns Tools for calling OpenAI API Assistants with same token
|
|
1816
|
-
* /
|
|
1817
|
-
public createAssistantSubtools(assistantId: string_token): OpenAiAssistantExecutionTools {
|
|
1818
|
-
return new OpenAiAssistantExecutionTools({ ...this.options, assistantId });
|
|
1819
|
-
}
|
|
1820
|
-
*/
|
|
1821
1763
|
/**
|
|
1822
1764
|
* Check the `options` passed to `constructor`
|
|
1823
1765
|
*/
|
|
@@ -1826,23 +1768,15 @@
|
|
|
1826
1768
|
// TODO: [🎍] Do here a real check that API is online, working and API key is correct
|
|
1827
1769
|
}
|
|
1828
1770
|
/**
|
|
1829
|
-
* List all available OpenAI models that can be used
|
|
1771
|
+
* List all available OpenAI compatible models that can be used
|
|
1830
1772
|
*/
|
|
1831
1773
|
async listModels() {
|
|
1832
|
-
/*
|
|
1833
|
-
Note: Dynamic lising of the models
|
|
1834
|
-
const models = await this.openai.models.list({});
|
|
1835
|
-
|
|
1836
|
-
console.log({ models });
|
|
1837
|
-
console.log(models.data);
|
|
1838
|
-
*/
|
|
1839
1774
|
const client = await this.getClient();
|
|
1840
1775
|
const rawModelsList = await client.models.list();
|
|
1841
1776
|
const availableModels = rawModelsList.data
|
|
1842
1777
|
.sort((a, b) => (a.created > b.created ? 1 : -1))
|
|
1843
1778
|
.map((modelFromApi) => {
|
|
1844
|
-
|
|
1845
|
-
const modelFromList = OPENAI_MODELS.find(({ modelName }) => modelName === modelFromApi.id ||
|
|
1779
|
+
const modelFromList = this.HARDCODED_MODELS.find(({ modelName }) => modelName === modelFromApi.id ||
|
|
1846
1780
|
modelName.startsWith(modelFromApi.id) ||
|
|
1847
1781
|
modelFromApi.id.startsWith(modelName));
|
|
1848
1782
|
if (modelFromList !== undefined) {
|
|
@@ -1858,12 +1792,12 @@
|
|
|
1858
1792
|
return availableModels;
|
|
1859
1793
|
}
|
|
1860
1794
|
/**
|
|
1861
|
-
* Calls OpenAI API to use a chat model.
|
|
1795
|
+
* Calls OpenAI compatible API to use a chat model.
|
|
1862
1796
|
*/
|
|
1863
1797
|
async callChatModel(prompt) {
|
|
1864
1798
|
var _a;
|
|
1865
1799
|
if (this.options.isVerbose) {
|
|
1866
|
-
console.info(
|
|
1800
|
+
console.info(`💬 ${this.title} callChatModel call`, { prompt });
|
|
1867
1801
|
}
|
|
1868
1802
|
const { content, parameters, modelRequirements, format } = prompt;
|
|
1869
1803
|
const client = await this.getClient();
|
|
@@ -1924,20 +1858,20 @@
|
|
|
1924
1858
|
}
|
|
1925
1859
|
const complete = $getCurrentDate();
|
|
1926
1860
|
if (!rawResponse.choices[0]) {
|
|
1927
|
-
throw new PipelineExecutionError(
|
|
1861
|
+
throw new PipelineExecutionError(`No choises from ${this.title}`);
|
|
1928
1862
|
}
|
|
1929
1863
|
if (rawResponse.choices.length > 1) {
|
|
1930
1864
|
// TODO: This should be maybe only warning
|
|
1931
|
-
throw new PipelineExecutionError(
|
|
1865
|
+
throw new PipelineExecutionError(`More than one choise from ${this.title}`);
|
|
1932
1866
|
}
|
|
1933
1867
|
const resultContent = rawResponse.choices[0].message.content;
|
|
1934
|
-
const usage =
|
|
1868
|
+
const usage = this.computeUsage(content || '', resultContent || '', rawResponse);
|
|
1935
1869
|
if (resultContent === null) {
|
|
1936
|
-
throw new PipelineExecutionError(
|
|
1870
|
+
throw new PipelineExecutionError(`No response message from ${this.title}`);
|
|
1937
1871
|
}
|
|
1938
1872
|
return exportJson({
|
|
1939
1873
|
name: 'promptResult',
|
|
1940
|
-
message: `Result of \`
|
|
1874
|
+
message: `Result of \`OpenAiCompatibleExecutionTools.callChatModel\``,
|
|
1941
1875
|
order: [],
|
|
1942
1876
|
value: {
|
|
1943
1877
|
content: resultContent,
|
|
@@ -1960,7 +1894,7 @@
|
|
|
1960
1894
|
async callCompletionModel(prompt) {
|
|
1961
1895
|
var _a;
|
|
1962
1896
|
if (this.options.isVerbose) {
|
|
1963
|
-
console.info(
|
|
1897
|
+
console.info(`🖋 ${this.title} callCompletionModel call`, { prompt });
|
|
1964
1898
|
}
|
|
1965
1899
|
const { content, parameters, modelRequirements } = prompt;
|
|
1966
1900
|
const client = await this.getClient();
|
|
@@ -2001,17 +1935,17 @@
|
|
|
2001
1935
|
}
|
|
2002
1936
|
const complete = $getCurrentDate();
|
|
2003
1937
|
if (!rawResponse.choices[0]) {
|
|
2004
|
-
throw new PipelineExecutionError(
|
|
1938
|
+
throw new PipelineExecutionError(`No choises from ${this.title}`);
|
|
2005
1939
|
}
|
|
2006
1940
|
if (rawResponse.choices.length > 1) {
|
|
2007
1941
|
// TODO: This should be maybe only warning
|
|
2008
|
-
throw new PipelineExecutionError(
|
|
1942
|
+
throw new PipelineExecutionError(`More than one choise from ${this.title}`);
|
|
2009
1943
|
}
|
|
2010
1944
|
const resultContent = rawResponse.choices[0].text;
|
|
2011
|
-
const usage =
|
|
1945
|
+
const usage = this.computeUsage(content || '', resultContent || '', rawResponse);
|
|
2012
1946
|
return exportJson({
|
|
2013
1947
|
name: 'promptResult',
|
|
2014
|
-
message: `Result of \`
|
|
1948
|
+
message: `Result of \`OpenAiCompatibleExecutionTools.callCompletionModel\``,
|
|
2015
1949
|
order: [],
|
|
2016
1950
|
value: {
|
|
2017
1951
|
content: resultContent,
|
|
@@ -2029,11 +1963,11 @@
|
|
|
2029
1963
|
});
|
|
2030
1964
|
}
|
|
2031
1965
|
/**
|
|
2032
|
-
* Calls OpenAI API to use a embedding model
|
|
1966
|
+
* Calls OpenAI compatible API to use a embedding model
|
|
2033
1967
|
*/
|
|
2034
1968
|
async callEmbeddingModel(prompt) {
|
|
2035
1969
|
if (this.options.isVerbose) {
|
|
2036
|
-
console.info(
|
|
1970
|
+
console.info(`🖋 ${this.title} embedding call`, { prompt });
|
|
2037
1971
|
}
|
|
2038
1972
|
const { content, parameters, modelRequirements } = prompt;
|
|
2039
1973
|
const client = await this.getClient();
|
|
@@ -2068,12 +2002,12 @@
|
|
|
2068
2002
|
throw new PipelineExecutionError(`Expected exactly 1 data item in response, got ${rawResponse.data.length}`);
|
|
2069
2003
|
}
|
|
2070
2004
|
const resultContent = rawResponse.data[0].embedding;
|
|
2071
|
-
const usage =
|
|
2005
|
+
const usage = this.computeUsage(content || '', '',
|
|
2072
2006
|
// <- Note: Embedding does not have result content
|
|
2073
2007
|
rawResponse);
|
|
2074
2008
|
return exportJson({
|
|
2075
2009
|
name: 'promptResult',
|
|
2076
|
-
message: `Result of \`
|
|
2010
|
+
message: `Result of \`OpenAiCompatibleExecutionTools.callEmbeddingModel\``,
|
|
2077
2011
|
order: [],
|
|
2078
2012
|
value: {
|
|
2079
2013
|
content: resultContent,
|
|
@@ -2096,65 +2030,171 @@
|
|
|
2096
2030
|
*/
|
|
2097
2031
|
getDefaultModel(defaultModelName) {
|
|
2098
2032
|
// Note: Match exact or prefix for model families
|
|
2099
|
-
const model =
|
|
2033
|
+
const model = this.HARDCODED_MODELS.find(({ modelName }) => modelName === defaultModelName || modelName.startsWith(defaultModelName));
|
|
2100
2034
|
if (model === undefined) {
|
|
2101
|
-
throw new
|
|
2102
|
-
Cannot find model in
|
|
2035
|
+
throw new PipelineExecutionError(spaceTrim__default["default"]((block) => `
|
|
2036
|
+
Cannot find model in ${this.title} models with name "${defaultModelName}" which should be used as default.
|
|
2103
2037
|
|
|
2104
2038
|
Available models:
|
|
2105
|
-
${block(
|
|
2039
|
+
${block(this.HARDCODED_MODELS.map(({ modelName }) => `- "${modelName}"`).join('\n'))}
|
|
2040
|
+
|
|
2041
|
+
Model "${defaultModelName}" is probably not available anymore, not installed, inaccessible or misconfigured.
|
|
2106
2042
|
|
|
2107
2043
|
`));
|
|
2108
2044
|
}
|
|
2109
2045
|
return model;
|
|
2110
2046
|
}
|
|
2111
|
-
/**
|
|
2112
|
-
* Default model for chat variant.
|
|
2113
|
-
*/
|
|
2114
|
-
getDefaultChatModel() {
|
|
2115
|
-
return this.getDefaultModel('gpt-4o');
|
|
2116
|
-
}
|
|
2117
|
-
/**
|
|
2118
|
-
* Default model for completion variant.
|
|
2119
|
-
*/
|
|
2120
|
-
getDefaultCompletionModel() {
|
|
2121
|
-
return this.getDefaultModel('gpt-3.5-turbo-instruct');
|
|
2122
|
-
}
|
|
2123
|
-
/**
|
|
2124
|
-
* Default model for completion variant.
|
|
2125
|
-
*/
|
|
2126
|
-
getDefaultEmbeddingModel() {
|
|
2127
|
-
return this.getDefaultModel('text-embedding-3-large');
|
|
2128
|
-
}
|
|
2129
2047
|
}
|
|
2130
2048
|
/**
|
|
2131
|
-
* TODO: [
|
|
2132
|
-
* TODO: Maybe
|
|
2133
|
-
* TODO: Maybe make custom OpenAiError
|
|
2049
|
+
* TODO: [🛄] Some way how to re-wrap the errors from `OpenAiCompatibleExecutionTools`
|
|
2050
|
+
* TODO: [🛄] Maybe make custom `OpenAiCompatibleError`
|
|
2134
2051
|
* TODO: [🧠][🈁] Maybe use `isDeterministic` from options
|
|
2135
2052
|
* TODO: [🧠][🌰] Allow to pass `title` for tracking purposes
|
|
2136
2053
|
*/
|
|
2137
2054
|
|
|
2138
2055
|
/**
|
|
2139
|
-
*
|
|
2056
|
+
* List of available models in Ollama library
|
|
2140
2057
|
*
|
|
2141
|
-
* Note:
|
|
2058
|
+
* Note: Done at 2025-05-19
|
|
2142
2059
|
*
|
|
2143
|
-
* @
|
|
2060
|
+
* @see https://ollama.com/library
|
|
2061
|
+
* @public exported from `@promptbook/ollama`
|
|
2144
2062
|
*/
|
|
2145
|
-
const
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2063
|
+
const OLLAMA_MODELS = exportJson({
|
|
2064
|
+
name: 'OLLAMA_MODELS',
|
|
2065
|
+
value: [
|
|
2066
|
+
{
|
|
2067
|
+
modelVariant: 'CHAT',
|
|
2068
|
+
modelTitle: 'llama2',
|
|
2069
|
+
modelName: 'llama2',
|
|
2070
|
+
modelDescription: 'Meta Llama 2, a general-purpose large language model.',
|
|
2071
|
+
},
|
|
2072
|
+
{
|
|
2073
|
+
modelVariant: 'CHAT',
|
|
2074
|
+
modelTitle: 'llama2-chat',
|
|
2075
|
+
modelName: 'llama2-chat',
|
|
2076
|
+
modelDescription: 'Meta Llama 2 Chat, optimized for conversational tasks.',
|
|
2077
|
+
},
|
|
2078
|
+
{
|
|
2079
|
+
modelVariant: 'CHAT',
|
|
2080
|
+
modelTitle: 'alpaca-7b',
|
|
2081
|
+
modelName: 'alpaca-7b',
|
|
2082
|
+
modelDescription: 'Stanford Alpaca 7B, instruction-tuned LLaMA model.',
|
|
2083
|
+
},
|
|
2084
|
+
{
|
|
2085
|
+
modelVariant: 'CHAT',
|
|
2086
|
+
modelTitle: 'alpaca-30b',
|
|
2087
|
+
modelName: 'alpaca-30b',
|
|
2088
|
+
modelDescription: 'Stanford Alpaca 30B, larger instruction-tuned LLaMA model.',
|
|
2089
|
+
},
|
|
2090
|
+
{
|
|
2091
|
+
modelVariant: 'CHAT',
|
|
2092
|
+
modelTitle: 'vicuna-13b',
|
|
2093
|
+
modelName: 'vicuna-13b',
|
|
2094
|
+
modelDescription: 'Vicuna 13B, fine-tuned LLaMA for chat and instruction.',
|
|
2095
|
+
},
|
|
2096
|
+
{
|
|
2097
|
+
modelVariant: 'CHAT',
|
|
2098
|
+
modelTitle: 'falcon-7b',
|
|
2099
|
+
modelName: 'falcon-7b',
|
|
2100
|
+
modelDescription: 'Falcon 7B, a performant open large language model.',
|
|
2101
|
+
},
|
|
2102
|
+
{
|
|
2103
|
+
modelVariant: 'CHAT',
|
|
2104
|
+
modelTitle: 'falcon-40b',
|
|
2105
|
+
modelName: 'falcon-40b',
|
|
2106
|
+
modelDescription: 'Falcon 40B, a larger open large language model.',
|
|
2107
|
+
},
|
|
2108
|
+
{
|
|
2109
|
+
modelVariant: 'CHAT',
|
|
2110
|
+
modelTitle: 'bloom-7b',
|
|
2111
|
+
modelName: 'bloom-7b',
|
|
2112
|
+
modelDescription: 'BLOOM 7B, multilingual large language model.',
|
|
2113
|
+
},
|
|
2114
|
+
{
|
|
2115
|
+
modelVariant: 'CHAT',
|
|
2116
|
+
modelTitle: 'mistral-7b',
|
|
2117
|
+
modelName: 'mistral-7b',
|
|
2118
|
+
modelDescription: 'Mistral 7B, efficient and fast open LLM.',
|
|
2119
|
+
},
|
|
2120
|
+
{
|
|
2121
|
+
modelVariant: 'CHAT',
|
|
2122
|
+
modelTitle: 'gorilla',
|
|
2123
|
+
modelName: 'gorilla',
|
|
2124
|
+
modelDescription: 'Gorilla, open-source LLM for tool use and APIs.',
|
|
2125
|
+
},
|
|
2126
|
+
{
|
|
2127
|
+
modelVariant: 'CHAT',
|
|
2128
|
+
modelTitle: 'cerebras-13b',
|
|
2129
|
+
modelName: 'cerebras-13b',
|
|
2130
|
+
modelDescription: 'Cerebras-GPT 13B, open large language model.',
|
|
2131
|
+
},
|
|
2132
|
+
{
|
|
2133
|
+
modelVariant: 'CHAT',
|
|
2134
|
+
modelTitle: 'openchat-7b',
|
|
2135
|
+
modelName: 'openchat-7b',
|
|
2136
|
+
modelDescription: 'OpenChat 7B, fine-tuned for conversational tasks.',
|
|
2137
|
+
},
|
|
2138
|
+
{
|
|
2139
|
+
modelVariant: 'CHAT',
|
|
2140
|
+
modelTitle: 'openchat-13b',
|
|
2141
|
+
modelName: 'openchat-13b',
|
|
2142
|
+
modelDescription: 'OpenChat 13B, larger conversational LLM.',
|
|
2143
|
+
},
|
|
2144
|
+
{
|
|
2145
|
+
modelVariant: 'CHAT',
|
|
2146
|
+
modelTitle: 'mpt-7b-chat',
|
|
2147
|
+
modelName: 'mpt-7b-chat',
|
|
2148
|
+
modelDescription: 'MPT-7B Chat, optimized for dialogue and chat.',
|
|
2149
|
+
},
|
|
2150
|
+
{
|
|
2151
|
+
modelVariant: 'CHAT',
|
|
2152
|
+
modelTitle: 'mpt-7b-instruct',
|
|
2153
|
+
modelName: 'mpt-7b-instruct',
|
|
2154
|
+
modelDescription: 'MPT-7B Instruct, instruction-tuned variant.',
|
|
2155
|
+
},
|
|
2156
|
+
{
|
|
2157
|
+
modelVariant: 'CHAT',
|
|
2158
|
+
modelTitle: 'command-7b',
|
|
2159
|
+
modelName: 'command-7b',
|
|
2160
|
+
modelDescription: 'Command 7B, instruction-following LLM.',
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
modelVariant: 'CHAT',
|
|
2164
|
+
modelTitle: 'starcoder',
|
|
2165
|
+
modelName: 'starcoder',
|
|
2166
|
+
modelDescription: 'StarCoder, code generation large language model.',
|
|
2167
|
+
},
|
|
2168
|
+
{
|
|
2169
|
+
modelVariant: 'CHAT',
|
|
2170
|
+
modelTitle: 'starcoder2',
|
|
2171
|
+
modelName: 'starcoder2',
|
|
2172
|
+
modelDescription: 'StarCoder2, improved code generation model.',
|
|
2173
|
+
},
|
|
2174
|
+
{
|
|
2175
|
+
modelVariant: 'CHAT',
|
|
2176
|
+
modelTitle: 'mixtral-7b-chat',
|
|
2177
|
+
modelName: 'mixtral-7b-chat',
|
|
2178
|
+
modelDescription: 'Mixtral 7B Chat, Mixture-of-Experts conversational model.',
|
|
2179
|
+
},
|
|
2180
|
+
{
|
|
2181
|
+
modelVariant: 'CHAT',
|
|
2182
|
+
modelTitle: 'mixtral-8x7b',
|
|
2183
|
+
modelName: 'mixtral-8x7b',
|
|
2184
|
+
modelDescription: 'Mixtral 8x7B, Mixture-of-Experts large language model.',
|
|
2185
|
+
},
|
|
2186
|
+
{
|
|
2187
|
+
modelVariant: 'CHAT',
|
|
2188
|
+
modelTitle: 'mixtral-8x7b-instruct',
|
|
2189
|
+
modelName: 'mixtral-8x7b-instruct',
|
|
2190
|
+
modelDescription: 'Mixtral 8x7B Instruct, instruction-tuned Mixture-of-Experts model.',
|
|
2191
|
+
},
|
|
2192
|
+
// <- [🕕]
|
|
2193
|
+
],
|
|
2154
2194
|
});
|
|
2155
2195
|
/**
|
|
2156
|
-
* TODO: [
|
|
2157
|
-
*
|
|
2196
|
+
* TODO: [🚸] Not all models are compatible with JSON mode, add this information here and use it
|
|
2197
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
2158
2198
|
*/
|
|
2159
2199
|
|
|
2160
2200
|
/**
|
|
@@ -2162,22 +2202,79 @@
|
|
|
2162
2202
|
*
|
|
2163
2203
|
* @public exported from `@promptbook/ollama`
|
|
2164
2204
|
*/
|
|
2165
|
-
const DEFAULT_OLLAMA_BASE_URL = 'http://localhost:11434';
|
|
2205
|
+
const DEFAULT_OLLAMA_BASE_URL = 'http://localhost:11434/v1';
|
|
2166
2206
|
|
|
2167
2207
|
/**
|
|
2168
2208
|
* Execution Tools for calling Ollama API
|
|
2169
2209
|
*
|
|
2170
2210
|
* @public exported from `@promptbook/ollama`
|
|
2171
2211
|
*/
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2212
|
+
class OllamaExecutionTools extends OpenAiCompatibleExecutionTools {
|
|
2213
|
+
/* <- TODO: [🍚] `, Destroyable` */
|
|
2214
|
+
constructor(ollamaOptions) {
|
|
2215
|
+
const openAiCompatibleOptions = {
|
|
2216
|
+
baseURL: DEFAULT_OLLAMA_BASE_URL,
|
|
2217
|
+
...ollamaOptions,
|
|
2218
|
+
userId: 'ollama',
|
|
2219
|
+
};
|
|
2220
|
+
super(openAiCompatibleOptions);
|
|
2221
|
+
}
|
|
2222
|
+
get title() {
|
|
2223
|
+
return 'Ollama';
|
|
2224
|
+
}
|
|
2225
|
+
get description() {
|
|
2226
|
+
return 'Use all models provided by Ollama';
|
|
2227
|
+
}
|
|
2228
|
+
/**
|
|
2229
|
+
* List all available models (non dynamically)
|
|
2230
|
+
*
|
|
2231
|
+
* Note: Purpose of this is to provide more information about models than standard listing from API
|
|
2232
|
+
*/
|
|
2233
|
+
get HARDCODED_MODELS() {
|
|
2234
|
+
return OLLAMA_MODELS;
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Computes the usage of the Ollama API based on the response from Ollama
|
|
2238
|
+
*/
|
|
2239
|
+
computeUsage(...args) {
|
|
2240
|
+
return {
|
|
2241
|
+
...computeOpenAiUsage(...args),
|
|
2242
|
+
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
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
/**
|
|
2246
|
+
* Default model for chat variant.
|
|
2247
|
+
*/
|
|
2248
|
+
getDefaultChatModel() {
|
|
2249
|
+
return this.getDefaultModel('llama2'); // <- TODO: [🧠] Pick the best default model
|
|
2250
|
+
// <- TODO: [🛄] When 'llama2' not installed, maybe better error message
|
|
2251
|
+
}
|
|
2252
|
+
/**
|
|
2253
|
+
* Default model for completion variant.
|
|
2254
|
+
*/
|
|
2255
|
+
getDefaultCompletionModel() {
|
|
2256
|
+
return this.getDefaultModel('llama2'); // <- TODO: [🧠] Pick the best default model
|
|
2257
|
+
// <- TODO: [🛄] When 'llama2' not installed, maybe better error message
|
|
2258
|
+
}
|
|
2259
|
+
/**
|
|
2260
|
+
* Default model for completion variant.
|
|
2261
|
+
*/
|
|
2262
|
+
getDefaultEmbeddingModel() {
|
|
2263
|
+
return this.getDefaultModel('text-embedding-3-large'); // <- TODO: [🧠] Pick the best default model
|
|
2264
|
+
// <- TODO: [🛄]
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
/**
|
|
2268
|
+
* TODO: [🛄] Some way how to re-wrap the errors from `OpenAiCompatibleExecutionTools`
|
|
2269
|
+
*/
|
|
2270
|
+
|
|
2271
|
+
/**
|
|
2272
|
+
* Execution Tools for calling Ollama API
|
|
2273
|
+
*
|
|
2274
|
+
* @public exported from `@promptbook/ollama`
|
|
2275
|
+
*/
|
|
2276
|
+
const createOllamaExecutionTools = Object.assign((options) => {
|
|
2277
|
+
return new OllamaExecutionTools(options);
|
|
2181
2278
|
}, {
|
|
2182
2279
|
packageName: '@promptbook/ollama',
|
|
2183
2280
|
className: 'OllamaExecutionTools',
|
|
@@ -2363,6 +2460,8 @@
|
|
|
2363
2460
|
|
|
2364
2461
|
exports.BOOK_LANGUAGE_VERSION = BOOK_LANGUAGE_VERSION;
|
|
2365
2462
|
exports.DEFAULT_OLLAMA_BASE_URL = DEFAULT_OLLAMA_BASE_URL;
|
|
2463
|
+
exports.OLLAMA_MODELS = OLLAMA_MODELS;
|
|
2464
|
+
exports.OllamaExecutionTools = OllamaExecutionTools;
|
|
2366
2465
|
exports.PROMPTBOOK_ENGINE_VERSION = PROMPTBOOK_ENGINE_VERSION;
|
|
2367
2466
|
exports._OllamaRegistration = _OllamaRegistration;
|
|
2368
2467
|
exports.createOllamaExecutionTools = createOllamaExecutionTools;
|