modelfusion 0.23.0 → 0.24.0
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 +2 -0
- package/model-provider/cohere/CohereTokenizer.d.ts +1 -1
- package/model-provider/openai/OpenAITextGenerationModel.cjs +38 -6
- package/model-provider/openai/OpenAITextGenerationModel.d.ts +20 -9
- package/model-provider/openai/OpenAITextGenerationModel.js +36 -5
- package/model-provider/openai/TikTokenTokenizer.d.ts +4 -2
- package/model-provider/openai/chat/OpenAIChatModel.cjs +48 -9
- package/model-provider/openai/chat/OpenAIChatModel.d.ts +23 -9
- package/model-provider/openai/chat/OpenAIChatModel.js +46 -8
- package/model-provider/openai/chat/countOpenAIChatMessageTokens.cjs +5 -2
- package/model-provider/openai/chat/countOpenAIChatMessageTokens.js +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
@@ -35,6 +35,8 @@ You need to install `zod` and a matching version of `zod-to-json-schema` (peer d
|
|
35
35
|
npm install zod zod-to-json-schema
|
36
36
|
```
|
37
37
|
|
38
|
+
Or use a template: [ModelFusion terminal app starter](https://github.com/lgrammel/modelfusion-terminal-app-starter)
|
39
|
+
|
38
40
|
## Usage Examples
|
39
41
|
|
40
42
|
You can provide API keys for the different [integrations](https://modelfusion.dev/integration/model-provider/) using environment variables (e.g., `OPENAI_API_KEY`) or pass them into the model constructors as options.
|
@@ -4,7 +4,7 @@ import { Run } from "../../core/Run.js";
|
|
4
4
|
import { RetryFunction } from "../../util/api/RetryFunction.js";
|
5
5
|
import { ThrottleFunction } from "../../util/api/ThrottleFunction.js";
|
6
6
|
import { CohereTextGenerationModelType } from "./CohereTextGenerationModel.js";
|
7
|
-
import { CohereTextEmbeddingModelType } from "./
|
7
|
+
import { CohereTextEmbeddingModelType } from "./CohereTextEmbeddingModel.js";
|
8
8
|
export type CohereTokenizerModelType = CohereTextGenerationModelType | CohereTextEmbeddingModelType;
|
9
9
|
export interface CohereTokenizerSettings {
|
10
10
|
model: CohereTokenizerModelType;
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.OpenAITextResponseFormat = exports.OpenAITextGenerationModel = exports.calculateOpenAITextGenerationCostInMillicents = exports.isOpenAITextGenerationModel = exports.OPENAI_TEXT_GENERATION_MODELS = void 0;
|
6
|
+
exports.OpenAITextResponseFormat = exports.OpenAITextGenerationModel = exports.calculateOpenAITextGenerationCostInMillicents = exports.isOpenAITextGenerationModel = exports.getOpenAITextGenerationModelInformation = exports.OPENAI_TEXT_GENERATION_MODELS = void 0;
|
7
7
|
const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
|
8
8
|
const zod_1 = __importDefault(require("zod"));
|
9
9
|
const AbstractModel_js_1 = require("../../model-function/AbstractModel.cjs");
|
@@ -23,10 +23,12 @@ exports.OPENAI_TEXT_GENERATION_MODELS = {
|
|
23
23
|
"davinci-002": {
|
24
24
|
contextWindowSize: 16384,
|
25
25
|
tokenCostInMillicents: 0.2,
|
26
|
+
fineTunedTokenCostInMillicents: 1.2,
|
26
27
|
},
|
27
28
|
"babbage-002": {
|
28
29
|
contextWindowSize: 16384,
|
29
30
|
tokenCostInMillicents: 0.04,
|
31
|
+
fineTunedTokenCostInMillicents: 0.16,
|
30
32
|
},
|
31
33
|
"text-davinci-003": {
|
32
34
|
contextWindowSize: 4096,
|
@@ -69,10 +71,38 @@ exports.OPENAI_TEXT_GENERATION_MODELS = {
|
|
69
71
|
tokenCostInMillicents: 0.04,
|
70
72
|
},
|
71
73
|
};
|
72
|
-
|
74
|
+
function getOpenAITextGenerationModelInformation(model) {
|
75
|
+
// Model is already a base model:
|
76
|
+
if (model in exports.OPENAI_TEXT_GENERATION_MODELS) {
|
77
|
+
const baseModelInformation = exports.OPENAI_TEXT_GENERATION_MODELS[model];
|
78
|
+
return {
|
79
|
+
baseModel: model,
|
80
|
+
isFineTuned: false,
|
81
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
82
|
+
tokenCostInMillicents: baseModelInformation.tokenCostInMillicents,
|
83
|
+
};
|
84
|
+
}
|
85
|
+
// Extract the base model from the fine-tuned model:
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
87
|
+
const [_, baseModel, ___, ____, _____] = model.split(":");
|
88
|
+
if (["davinci-002", "babbage-002"].includes(baseModel)) {
|
89
|
+
const baseModelInformation = exports.OPENAI_TEXT_GENERATION_MODELS[baseModel];
|
90
|
+
return {
|
91
|
+
baseModel: baseModel,
|
92
|
+
isFineTuned: true,
|
93
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
94
|
+
tokenCostInMillicents: baseModelInformation.fineTunedTokenCostInMillicents,
|
95
|
+
};
|
96
|
+
}
|
97
|
+
throw new Error(`Unknown OpenAI chat base model ${baseModel}.`);
|
98
|
+
}
|
99
|
+
exports.getOpenAITextGenerationModelInformation = getOpenAITextGenerationModelInformation;
|
100
|
+
const isOpenAITextGenerationModel = (model) => model in exports.OPENAI_TEXT_GENERATION_MODELS ||
|
101
|
+
model.startsWith("ft:davinci-002:") ||
|
102
|
+
model.startsWith("ft:babbage-002:");
|
73
103
|
exports.isOpenAITextGenerationModel = isOpenAITextGenerationModel;
|
74
104
|
const calculateOpenAITextGenerationCostInMillicents = ({ model, response, }) => response.usage.total_tokens *
|
75
|
-
|
105
|
+
getOpenAITextGenerationModelInformation(model).tokenCostInMillicents;
|
76
106
|
exports.calculateOpenAITextGenerationCostInMillicents = calculateOpenAITextGenerationCostInMillicents;
|
77
107
|
/**
|
78
108
|
* Create a text generation model that calls the OpenAI text completion API.
|
@@ -113,9 +143,11 @@ class OpenAITextGenerationModel extends AbstractModel_js_1.AbstractModel {
|
|
113
143
|
writable: true,
|
114
144
|
value: void 0
|
115
145
|
});
|
116
|
-
|
117
|
-
this.
|
118
|
-
|
146
|
+
const modelInformation = getOpenAITextGenerationModelInformation(this.settings.model);
|
147
|
+
this.tokenizer = new TikTokenTokenizer_js_1.TikTokenTokenizer({
|
148
|
+
model: modelInformation.baseModel,
|
149
|
+
});
|
150
|
+
this.contextWindowSize = modelInformation.contextWindowSize;
|
119
151
|
}
|
120
152
|
get modelName() {
|
121
153
|
return this.settings.model;
|
@@ -19,10 +19,12 @@ export declare const OPENAI_TEXT_GENERATION_MODELS: {
|
|
19
19
|
"davinci-002": {
|
20
20
|
contextWindowSize: number;
|
21
21
|
tokenCostInMillicents: number;
|
22
|
+
fineTunedTokenCostInMillicents: number;
|
22
23
|
};
|
23
24
|
"babbage-002": {
|
24
25
|
contextWindowSize: number;
|
25
26
|
tokenCostInMillicents: number;
|
27
|
+
fineTunedTokenCostInMillicents: number;
|
26
28
|
};
|
27
29
|
"text-davinci-003": {
|
28
30
|
contextWindowSize: number;
|
@@ -65,8 +67,17 @@ export declare const OPENAI_TEXT_GENERATION_MODELS: {
|
|
65
67
|
tokenCostInMillicents: number;
|
66
68
|
};
|
67
69
|
};
|
68
|
-
export
|
69
|
-
|
70
|
+
export declare function getOpenAITextGenerationModelInformation(model: OpenAITextGenerationModelType): {
|
71
|
+
baseModel: OpenAITextGenerationBaseModelType;
|
72
|
+
isFineTuned: boolean;
|
73
|
+
contextWindowSize: number;
|
74
|
+
tokenCostInMillicents: number;
|
75
|
+
};
|
76
|
+
type FineTuneableOpenAITextGenerationModelType = "davinci-002" | "babbage-002";
|
77
|
+
type FineTunedOpenAITextGenerationModelType = `ft:${FineTuneableOpenAITextGenerationModelType}:${string}:${string}:${string}`;
|
78
|
+
export type OpenAITextGenerationBaseModelType = keyof typeof OPENAI_TEXT_GENERATION_MODELS;
|
79
|
+
export type OpenAITextGenerationModelType = OpenAITextGenerationBaseModelType | FineTunedOpenAITextGenerationModelType;
|
80
|
+
export declare const isOpenAITextGenerationModel: (model: string) => model is OpenAITextGenerationModelType;
|
70
81
|
export declare const calculateOpenAITextGenerationCostInMillicents: ({ model, response, }: {
|
71
82
|
model: OpenAITextGenerationModelType;
|
72
83
|
response: OpenAITextGenerationResponse;
|
@@ -110,7 +121,7 @@ export interface OpenAITextGenerationModelSettings extends TextGenerationModelSe
|
|
110
121
|
export declare class OpenAITextGenerationModel extends AbstractModel<OpenAITextGenerationModelSettings> implements TextGenerationModel<string, OpenAITextGenerationResponse, OpenAITextGenerationDelta, OpenAITextGenerationModelSettings> {
|
111
122
|
constructor(settings: OpenAITextGenerationModelSettings);
|
112
123
|
readonly provider: "openai";
|
113
|
-
get modelName():
|
124
|
+
get modelName(): OpenAITextGenerationModelType;
|
114
125
|
readonly contextWindowSize: number;
|
115
126
|
readonly tokenizer: TikTokenTokenizer;
|
116
127
|
private get apiKey();
|
@@ -126,8 +137,8 @@ export declare class OpenAITextGenerationModel extends AbstractModel<OpenAITextG
|
|
126
137
|
model: string;
|
127
138
|
usage: {
|
128
139
|
prompt_tokens: number;
|
129
|
-
total_tokens: number;
|
130
140
|
completion_tokens: number;
|
141
|
+
total_tokens: number;
|
131
142
|
};
|
132
143
|
id: string;
|
133
144
|
created: number;
|
@@ -176,20 +187,20 @@ declare const openAITextGenerationResponseSchema: z.ZodObject<{
|
|
176
187
|
total_tokens: z.ZodNumber;
|
177
188
|
}, "strip", z.ZodTypeAny, {
|
178
189
|
prompt_tokens: number;
|
179
|
-
total_tokens: number;
|
180
190
|
completion_tokens: number;
|
191
|
+
total_tokens: number;
|
181
192
|
}, {
|
182
193
|
prompt_tokens: number;
|
183
|
-
total_tokens: number;
|
184
194
|
completion_tokens: number;
|
195
|
+
total_tokens: number;
|
185
196
|
}>;
|
186
197
|
}, "strip", z.ZodTypeAny, {
|
187
198
|
object: "text_completion";
|
188
199
|
model: string;
|
189
200
|
usage: {
|
190
201
|
prompt_tokens: number;
|
191
|
-
total_tokens: number;
|
192
202
|
completion_tokens: number;
|
203
|
+
total_tokens: number;
|
193
204
|
};
|
194
205
|
id: string;
|
195
206
|
created: number;
|
@@ -204,8 +215,8 @@ declare const openAITextGenerationResponseSchema: z.ZodObject<{
|
|
204
215
|
model: string;
|
205
216
|
usage: {
|
206
217
|
prompt_tokens: number;
|
207
|
-
total_tokens: number;
|
208
218
|
completion_tokens: number;
|
219
|
+
total_tokens: number;
|
209
220
|
};
|
210
221
|
id: string;
|
211
222
|
created: number;
|
@@ -232,8 +243,8 @@ export declare const OpenAITextResponseFormat: {
|
|
232
243
|
model: string;
|
233
244
|
usage: {
|
234
245
|
prompt_tokens: number;
|
235
|
-
total_tokens: number;
|
236
246
|
completion_tokens: number;
|
247
|
+
total_tokens: number;
|
237
248
|
};
|
238
249
|
id: string;
|
239
250
|
created: number;
|
@@ -17,10 +17,12 @@ export const OPENAI_TEXT_GENERATION_MODELS = {
|
|
17
17
|
"davinci-002": {
|
18
18
|
contextWindowSize: 16384,
|
19
19
|
tokenCostInMillicents: 0.2,
|
20
|
+
fineTunedTokenCostInMillicents: 1.2,
|
20
21
|
},
|
21
22
|
"babbage-002": {
|
22
23
|
contextWindowSize: 16384,
|
23
24
|
tokenCostInMillicents: 0.04,
|
25
|
+
fineTunedTokenCostInMillicents: 0.16,
|
24
26
|
},
|
25
27
|
"text-davinci-003": {
|
26
28
|
contextWindowSize: 4096,
|
@@ -63,9 +65,36 @@ export const OPENAI_TEXT_GENERATION_MODELS = {
|
|
63
65
|
tokenCostInMillicents: 0.04,
|
64
66
|
},
|
65
67
|
};
|
66
|
-
export
|
68
|
+
export function getOpenAITextGenerationModelInformation(model) {
|
69
|
+
// Model is already a base model:
|
70
|
+
if (model in OPENAI_TEXT_GENERATION_MODELS) {
|
71
|
+
const baseModelInformation = OPENAI_TEXT_GENERATION_MODELS[model];
|
72
|
+
return {
|
73
|
+
baseModel: model,
|
74
|
+
isFineTuned: false,
|
75
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
76
|
+
tokenCostInMillicents: baseModelInformation.tokenCostInMillicents,
|
77
|
+
};
|
78
|
+
}
|
79
|
+
// Extract the base model from the fine-tuned model:
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
81
|
+
const [_, baseModel, ___, ____, _____] = model.split(":");
|
82
|
+
if (["davinci-002", "babbage-002"].includes(baseModel)) {
|
83
|
+
const baseModelInformation = OPENAI_TEXT_GENERATION_MODELS[baseModel];
|
84
|
+
return {
|
85
|
+
baseModel: baseModel,
|
86
|
+
isFineTuned: true,
|
87
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
88
|
+
tokenCostInMillicents: baseModelInformation.fineTunedTokenCostInMillicents,
|
89
|
+
};
|
90
|
+
}
|
91
|
+
throw new Error(`Unknown OpenAI chat base model ${baseModel}.`);
|
92
|
+
}
|
93
|
+
export const isOpenAITextGenerationModel = (model) => model in OPENAI_TEXT_GENERATION_MODELS ||
|
94
|
+
model.startsWith("ft:davinci-002:") ||
|
95
|
+
model.startsWith("ft:babbage-002:");
|
67
96
|
export const calculateOpenAITextGenerationCostInMillicents = ({ model, response, }) => response.usage.total_tokens *
|
68
|
-
|
97
|
+
getOpenAITextGenerationModelInformation(model).tokenCostInMillicents;
|
69
98
|
/**
|
70
99
|
* Create a text generation model that calls the OpenAI text completion API.
|
71
100
|
*
|
@@ -105,9 +134,11 @@ export class OpenAITextGenerationModel extends AbstractModel {
|
|
105
134
|
writable: true,
|
106
135
|
value: void 0
|
107
136
|
});
|
108
|
-
|
109
|
-
this.
|
110
|
-
|
137
|
+
const modelInformation = getOpenAITextGenerationModelInformation(this.settings.model);
|
138
|
+
this.tokenizer = new TikTokenTokenizer({
|
139
|
+
model: modelInformation.baseModel,
|
140
|
+
});
|
141
|
+
this.contextWindowSize = modelInformation.contextWindowSize;
|
111
142
|
}
|
112
143
|
get modelName() {
|
113
144
|
return this.settings.model;
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import { TiktokenEncoding } from "js-tiktoken";
|
2
2
|
import { FullTokenizer } from "../../model-function/tokenize-text/Tokenizer.js";
|
3
|
-
import {
|
3
|
+
import { OpenAITextEmbeddingModelType } from "./OpenAITextEmbeddingModel.js";
|
4
|
+
import { OpenAITextGenerationBaseModelType } from "./OpenAITextGenerationModel.js";
|
5
|
+
import { OpenAIChatBaseModelType } from "./chat/OpenAIChatModel.js";
|
4
6
|
/**
|
5
7
|
* TikToken tokenizer for OpenAI language models.
|
6
8
|
*
|
@@ -21,7 +23,7 @@ export declare class TikTokenTokenizer implements FullTokenizer {
|
|
21
23
|
* Get a TikToken tokenizer for a specific model or encoding.
|
22
24
|
*/
|
23
25
|
constructor(options: {
|
24
|
-
model:
|
26
|
+
model: OpenAIChatBaseModelType | OpenAITextGenerationBaseModelType | OpenAITextEmbeddingModelType;
|
25
27
|
} | {
|
26
28
|
encoding: TiktokenEncoding;
|
27
29
|
});
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.OpenAIChatResponseFormat = exports.OpenAIChatModel = exports.calculateOpenAIChatCostInMillicents = exports.isOpenAIChatModel = exports.OPENAI_CHAT_MODELS = void 0;
|
6
|
+
exports.OpenAIChatResponseFormat = exports.OpenAIChatModel = exports.calculateOpenAIChatCostInMillicents = exports.isOpenAIChatModel = exports.getOpenAIChatModelInformation = exports.OPENAI_CHAT_MODELS = void 0;
|
7
7
|
const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
|
8
8
|
const zod_1 = __importDefault(require("zod"));
|
9
9
|
const AbstractModel_js_1 = require("../../../model-function/AbstractModel.cjs");
|
@@ -55,6 +55,8 @@ exports.OPENAI_CHAT_MODELS = {
|
|
55
55
|
contextWindowSize: 4096,
|
56
56
|
promptTokenCostInMillicents: 0.15,
|
57
57
|
completionTokenCostInMillicents: 0.2,
|
58
|
+
fineTunedPromptTokenCostInMillicents: 1.2,
|
59
|
+
fineTunedCompletionTokenCostInMillicents: 1.6,
|
58
60
|
},
|
59
61
|
"gpt-3.5-turbo-0301": {
|
60
62
|
contextWindowSize: 4096,
|
@@ -65,6 +67,8 @@ exports.OPENAI_CHAT_MODELS = {
|
|
65
67
|
contextWindowSize: 4096,
|
66
68
|
promptTokenCostInMillicents: 0.15,
|
67
69
|
completionTokenCostInMillicents: 0.2,
|
70
|
+
fineTunedPromptTokenCostInMillicents: 1.2,
|
71
|
+
fineTunedCompletionTokenCostInMillicents: 1.6,
|
68
72
|
},
|
69
73
|
"gpt-3.5-turbo-16k": {
|
70
74
|
contextWindowSize: 16384,
|
@@ -77,12 +81,45 @@ exports.OPENAI_CHAT_MODELS = {
|
|
77
81
|
completionTokenCostInMillicents: 0.4,
|
78
82
|
},
|
79
83
|
};
|
80
|
-
|
84
|
+
function getOpenAIChatModelInformation(model) {
|
85
|
+
// Model is already a base model:
|
86
|
+
if (model in exports.OPENAI_CHAT_MODELS) {
|
87
|
+
const baseModelInformation = exports.OPENAI_CHAT_MODELS[model];
|
88
|
+
return {
|
89
|
+
baseModel: model,
|
90
|
+
isFineTuned: false,
|
91
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
92
|
+
promptTokenCostInMillicents: baseModelInformation.promptTokenCostInMillicents,
|
93
|
+
completionTokenCostInMillicents: baseModelInformation.completionTokenCostInMillicents,
|
94
|
+
};
|
95
|
+
}
|
96
|
+
// Extract the base model from the fine-tuned model:
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
98
|
+
const [_, baseModel, ___, ____, _____] = model.split(":");
|
99
|
+
if (["gpt-3.5-turbo", "gpt-3.5-turbo-0613"].includes(baseModel)) {
|
100
|
+
const baseModelInformation = exports.OPENAI_CHAT_MODELS[baseModel];
|
101
|
+
return {
|
102
|
+
baseModel: baseModel,
|
103
|
+
isFineTuned: true,
|
104
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
105
|
+
promptTokenCostInMillicents: baseModelInformation.fineTunedPromptTokenCostInMillicents,
|
106
|
+
completionTokenCostInMillicents: baseModelInformation.fineTunedCompletionTokenCostInMillicents,
|
107
|
+
};
|
108
|
+
}
|
109
|
+
throw new Error(`Unknown OpenAI chat base model ${baseModel}.`);
|
110
|
+
}
|
111
|
+
exports.getOpenAIChatModelInformation = getOpenAIChatModelInformation;
|
112
|
+
const isOpenAIChatModel = (model) => model in exports.OPENAI_CHAT_MODELS ||
|
113
|
+
model.startsWith("ft:gpt-3.5-turbo-0613:") ||
|
114
|
+
model.startsWith("ft:gpt-3.5-turbo:");
|
81
115
|
exports.isOpenAIChatModel = isOpenAIChatModel;
|
82
|
-
const calculateOpenAIChatCostInMillicents = ({ model, response, }) =>
|
83
|
-
|
84
|
-
response.usage.
|
85
|
-
|
116
|
+
const calculateOpenAIChatCostInMillicents = ({ model, response, }) => {
|
117
|
+
const modelInformation = getOpenAIChatModelInformation(model);
|
118
|
+
return (response.usage.prompt_tokens *
|
119
|
+
modelInformation.promptTokenCostInMillicents +
|
120
|
+
response.usage.completion_tokens *
|
121
|
+
modelInformation.completionTokenCostInMillicents);
|
122
|
+
};
|
86
123
|
exports.calculateOpenAIChatCostInMillicents = calculateOpenAIChatCostInMillicents;
|
87
124
|
/**
|
88
125
|
* Create a text generation model that calls the OpenAI chat completion API.
|
@@ -124,9 +161,11 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
124
161
|
writable: true,
|
125
162
|
value: void 0
|
126
163
|
});
|
127
|
-
|
128
|
-
this.
|
129
|
-
|
164
|
+
const modelInformation = getOpenAIChatModelInformation(this.settings.model);
|
165
|
+
this.tokenizer = new TikTokenTokenizer_js_1.TikTokenTokenizer({
|
166
|
+
model: modelInformation.baseModel,
|
167
|
+
});
|
168
|
+
this.contextWindowSize = modelInformation.contextWindowSize;
|
130
169
|
}
|
131
170
|
get modelName() {
|
132
171
|
return this.settings.model;
|
@@ -48,6 +48,8 @@ export declare const OPENAI_CHAT_MODELS: {
|
|
48
48
|
contextWindowSize: number;
|
49
49
|
promptTokenCostInMillicents: number;
|
50
50
|
completionTokenCostInMillicents: number;
|
51
|
+
fineTunedPromptTokenCostInMillicents: number;
|
52
|
+
fineTunedCompletionTokenCostInMillicents: number;
|
51
53
|
};
|
52
54
|
"gpt-3.5-turbo-0301": {
|
53
55
|
contextWindowSize: number;
|
@@ -58,6 +60,8 @@ export declare const OPENAI_CHAT_MODELS: {
|
|
58
60
|
contextWindowSize: number;
|
59
61
|
promptTokenCostInMillicents: number;
|
60
62
|
completionTokenCostInMillicents: number;
|
63
|
+
fineTunedPromptTokenCostInMillicents: number;
|
64
|
+
fineTunedCompletionTokenCostInMillicents: number;
|
61
65
|
};
|
62
66
|
"gpt-3.5-turbo-16k": {
|
63
67
|
contextWindowSize: number;
|
@@ -70,8 +74,18 @@ export declare const OPENAI_CHAT_MODELS: {
|
|
70
74
|
completionTokenCostInMillicents: number;
|
71
75
|
};
|
72
76
|
};
|
73
|
-
export
|
74
|
-
|
77
|
+
export declare function getOpenAIChatModelInformation(model: OpenAIChatModelType): {
|
78
|
+
baseModel: OpenAIChatBaseModelType;
|
79
|
+
isFineTuned: boolean;
|
80
|
+
contextWindowSize: number;
|
81
|
+
promptTokenCostInMillicents: number;
|
82
|
+
completionTokenCostInMillicents: number;
|
83
|
+
};
|
84
|
+
type FineTuneableOpenAIChatModelType = `gpt-3.5-turbo` | `gpt-3.5-turbo-0613`;
|
85
|
+
type FineTunedOpenAIChatModelType = `ft:${FineTuneableOpenAIChatModelType}:${string}:${string}:${string}`;
|
86
|
+
export type OpenAIChatBaseModelType = keyof typeof OPENAI_CHAT_MODELS;
|
87
|
+
export type OpenAIChatModelType = OpenAIChatBaseModelType | FineTunedOpenAIChatModelType;
|
88
|
+
export declare const isOpenAIChatModel: (model: string) => model is OpenAIChatModelType;
|
75
89
|
export declare const calculateOpenAIChatCostInMillicents: ({ model, response, }: {
|
76
90
|
model: OpenAIChatModelType;
|
77
91
|
response: OpenAIChatResponse;
|
@@ -120,7 +134,7 @@ export interface OpenAIChatSettings extends TextGenerationModelSettings, OpenAIM
|
|
120
134
|
export declare class OpenAIChatModel extends AbstractModel<OpenAIChatSettings> implements TextGenerationModel<OpenAIChatMessage[], OpenAIChatResponse, OpenAIChatDelta, OpenAIChatSettings>, JsonGenerationModel<OpenAIChatSingleFunctionPrompt<unknown>, OpenAIChatResponse, OpenAIChatSettings>, JsonOrTextGenerationModel<OpenAIChatAutoFunctionPrompt<Array<OpenAIFunctionDescription<unknown>>>, OpenAIChatResponse, OpenAIChatSettings> {
|
121
135
|
constructor(settings: OpenAIChatSettings);
|
122
136
|
readonly provider: "openai";
|
123
|
-
get modelName():
|
137
|
+
get modelName(): OpenAIChatModelType;
|
124
138
|
readonly contextWindowSize: number;
|
125
139
|
readonly tokenizer: TikTokenTokenizer;
|
126
140
|
private get apiKey();
|
@@ -140,8 +154,8 @@ export declare class OpenAIChatModel extends AbstractModel<OpenAIChatSettings> i
|
|
140
154
|
model: string;
|
141
155
|
usage: {
|
142
156
|
prompt_tokens: number;
|
143
|
-
total_tokens: number;
|
144
157
|
completion_tokens: number;
|
158
|
+
total_tokens: number;
|
145
159
|
};
|
146
160
|
id: string;
|
147
161
|
created: number;
|
@@ -247,20 +261,20 @@ declare const openAIChatResponseSchema: z.ZodObject<{
|
|
247
261
|
total_tokens: z.ZodNumber;
|
248
262
|
}, "strip", z.ZodTypeAny, {
|
249
263
|
prompt_tokens: number;
|
250
|
-
total_tokens: number;
|
251
264
|
completion_tokens: number;
|
265
|
+
total_tokens: number;
|
252
266
|
}, {
|
253
267
|
prompt_tokens: number;
|
254
|
-
total_tokens: number;
|
255
268
|
completion_tokens: number;
|
269
|
+
total_tokens: number;
|
256
270
|
}>;
|
257
271
|
}, "strip", z.ZodTypeAny, {
|
258
272
|
object: "chat.completion";
|
259
273
|
model: string;
|
260
274
|
usage: {
|
261
275
|
prompt_tokens: number;
|
262
|
-
total_tokens: number;
|
263
276
|
completion_tokens: number;
|
277
|
+
total_tokens: number;
|
264
278
|
};
|
265
279
|
id: string;
|
266
280
|
created: number;
|
@@ -282,8 +296,8 @@ declare const openAIChatResponseSchema: z.ZodObject<{
|
|
282
296
|
model: string;
|
283
297
|
usage: {
|
284
298
|
prompt_tokens: number;
|
285
|
-
total_tokens: number;
|
286
299
|
completion_tokens: number;
|
300
|
+
total_tokens: number;
|
287
301
|
};
|
288
302
|
id: string;
|
289
303
|
created: number;
|
@@ -317,8 +331,8 @@ export declare const OpenAIChatResponseFormat: {
|
|
317
331
|
model: string;
|
318
332
|
usage: {
|
319
333
|
prompt_tokens: number;
|
320
|
-
total_tokens: number;
|
321
334
|
completion_tokens: number;
|
335
|
+
total_tokens: number;
|
322
336
|
};
|
323
337
|
id: string;
|
324
338
|
created: number;
|
@@ -49,6 +49,8 @@ export const OPENAI_CHAT_MODELS = {
|
|
49
49
|
contextWindowSize: 4096,
|
50
50
|
promptTokenCostInMillicents: 0.15,
|
51
51
|
completionTokenCostInMillicents: 0.2,
|
52
|
+
fineTunedPromptTokenCostInMillicents: 1.2,
|
53
|
+
fineTunedCompletionTokenCostInMillicents: 1.6,
|
52
54
|
},
|
53
55
|
"gpt-3.5-turbo-0301": {
|
54
56
|
contextWindowSize: 4096,
|
@@ -59,6 +61,8 @@ export const OPENAI_CHAT_MODELS = {
|
|
59
61
|
contextWindowSize: 4096,
|
60
62
|
promptTokenCostInMillicents: 0.15,
|
61
63
|
completionTokenCostInMillicents: 0.2,
|
64
|
+
fineTunedPromptTokenCostInMillicents: 1.2,
|
65
|
+
fineTunedCompletionTokenCostInMillicents: 1.6,
|
62
66
|
},
|
63
67
|
"gpt-3.5-turbo-16k": {
|
64
68
|
contextWindowSize: 16384,
|
@@ -71,11 +75,43 @@ export const OPENAI_CHAT_MODELS = {
|
|
71
75
|
completionTokenCostInMillicents: 0.4,
|
72
76
|
},
|
73
77
|
};
|
74
|
-
export
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
78
|
+
export function getOpenAIChatModelInformation(model) {
|
79
|
+
// Model is already a base model:
|
80
|
+
if (model in OPENAI_CHAT_MODELS) {
|
81
|
+
const baseModelInformation = OPENAI_CHAT_MODELS[model];
|
82
|
+
return {
|
83
|
+
baseModel: model,
|
84
|
+
isFineTuned: false,
|
85
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
86
|
+
promptTokenCostInMillicents: baseModelInformation.promptTokenCostInMillicents,
|
87
|
+
completionTokenCostInMillicents: baseModelInformation.completionTokenCostInMillicents,
|
88
|
+
};
|
89
|
+
}
|
90
|
+
// Extract the base model from the fine-tuned model:
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
92
|
+
const [_, baseModel, ___, ____, _____] = model.split(":");
|
93
|
+
if (["gpt-3.5-turbo", "gpt-3.5-turbo-0613"].includes(baseModel)) {
|
94
|
+
const baseModelInformation = OPENAI_CHAT_MODELS[baseModel];
|
95
|
+
return {
|
96
|
+
baseModel: baseModel,
|
97
|
+
isFineTuned: true,
|
98
|
+
contextWindowSize: baseModelInformation.contextWindowSize,
|
99
|
+
promptTokenCostInMillicents: baseModelInformation.fineTunedPromptTokenCostInMillicents,
|
100
|
+
completionTokenCostInMillicents: baseModelInformation.fineTunedCompletionTokenCostInMillicents,
|
101
|
+
};
|
102
|
+
}
|
103
|
+
throw new Error(`Unknown OpenAI chat base model ${baseModel}.`);
|
104
|
+
}
|
105
|
+
export const isOpenAIChatModel = (model) => model in OPENAI_CHAT_MODELS ||
|
106
|
+
model.startsWith("ft:gpt-3.5-turbo-0613:") ||
|
107
|
+
model.startsWith("ft:gpt-3.5-turbo:");
|
108
|
+
export const calculateOpenAIChatCostInMillicents = ({ model, response, }) => {
|
109
|
+
const modelInformation = getOpenAIChatModelInformation(model);
|
110
|
+
return (response.usage.prompt_tokens *
|
111
|
+
modelInformation.promptTokenCostInMillicents +
|
112
|
+
response.usage.completion_tokens *
|
113
|
+
modelInformation.completionTokenCostInMillicents);
|
114
|
+
};
|
79
115
|
/**
|
80
116
|
* Create a text generation model that calls the OpenAI chat completion API.
|
81
117
|
*
|
@@ -116,9 +152,11 @@ export class OpenAIChatModel extends AbstractModel {
|
|
116
152
|
writable: true,
|
117
153
|
value: void 0
|
118
154
|
});
|
119
|
-
|
120
|
-
this.
|
121
|
-
|
155
|
+
const modelInformation = getOpenAIChatModelInformation(this.settings.model);
|
156
|
+
this.tokenizer = new TikTokenTokenizer({
|
157
|
+
model: modelInformation.baseModel,
|
158
|
+
});
|
159
|
+
this.contextWindowSize = modelInformation.contextWindowSize;
|
122
160
|
}
|
123
161
|
get modelName() {
|
124
162
|
return this.settings.model;
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.countOpenAIChatPromptTokens = exports.countOpenAIChatMessageTokens = exports.OPENAI_CHAT_MESSAGE_BASE_TOKEN_COUNT = exports.OPENAI_CHAT_PROMPT_BASE_TOKEN_COUNT = void 0;
|
4
4
|
const countTokens_js_1 = require("../../../model-function/tokenize-text/countTokens.cjs");
|
5
5
|
const TikTokenTokenizer_js_1 = require("../TikTokenTokenizer.cjs");
|
6
|
+
const OpenAIChatModel_js_1 = require("./OpenAIChatModel.cjs");
|
6
7
|
/**
|
7
8
|
* Prompt tokens that are included automatically for every full
|
8
9
|
* chat prompt (several messages) that is sent to OpenAI.
|
@@ -14,8 +15,10 @@ exports.OPENAI_CHAT_PROMPT_BASE_TOKEN_COUNT = 2;
|
|
14
15
|
*/
|
15
16
|
exports.OPENAI_CHAT_MESSAGE_BASE_TOKEN_COUNT = 5;
|
16
17
|
async function countOpenAIChatMessageTokens({ message, model, }) {
|
17
|
-
|
18
|
-
|
18
|
+
const contentTokenCount = await (0, countTokens_js_1.countTokens)(new TikTokenTokenizer_js_1.TikTokenTokenizer({
|
19
|
+
model: (0, OpenAIChatModel_js_1.getOpenAIChatModelInformation)(model).baseModel,
|
20
|
+
}), message.content ?? "");
|
21
|
+
return exports.OPENAI_CHAT_MESSAGE_BASE_TOKEN_COUNT + contentTokenCount;
|
19
22
|
}
|
20
23
|
exports.countOpenAIChatMessageTokens = countOpenAIChatMessageTokens;
|
21
24
|
async function countOpenAIChatPromptTokens({ messages, model, }) {
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { countTokens } from "../../../model-function/tokenize-text/countTokens.js";
|
2
2
|
import { TikTokenTokenizer } from "../TikTokenTokenizer.js";
|
3
|
+
import { getOpenAIChatModelInformation, } from "./OpenAIChatModel.js";
|
3
4
|
/**
|
4
5
|
* Prompt tokens that are included automatically for every full
|
5
6
|
* chat prompt (several messages) that is sent to OpenAI.
|
@@ -11,8 +12,10 @@ export const OPENAI_CHAT_PROMPT_BASE_TOKEN_COUNT = 2;
|
|
11
12
|
*/
|
12
13
|
export const OPENAI_CHAT_MESSAGE_BASE_TOKEN_COUNT = 5;
|
13
14
|
export async function countOpenAIChatMessageTokens({ message, model, }) {
|
14
|
-
|
15
|
-
|
15
|
+
const contentTokenCount = await countTokens(new TikTokenTokenizer({
|
16
|
+
model: getOpenAIChatModelInformation(model).baseModel,
|
17
|
+
}), message.content ?? "");
|
18
|
+
return OPENAI_CHAT_MESSAGE_BASE_TOKEN_COUNT + contentTokenCount;
|
16
19
|
}
|
17
20
|
export async function countOpenAIChatPromptTokens({ messages, model, }) {
|
18
21
|
let tokens = OPENAI_CHAT_PROMPT_BASE_TOKEN_COUNT;
|