@sohqureshi/tokenwise 1.0.4 → 1.0.9
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 +23 -6
- package/dist/{chunk-ZVQRYJU5.js → chunk-2TDVL6BJ.js} +22 -6
- package/dist/chunk-L3HY6AWL.js +69 -0
- package/dist/{chunk-HFMW3K22.js → chunk-QHCUNOUH.js} +3 -3
- package/dist/cli.cjs +76 -8
- package/dist/cli.js +4 -4
- package/dist/core/analyze.cjs +73 -5
- package/dist/core/analyze.d.cts +3 -0
- package/dist/core/analyze.d.ts +3 -0
- package/dist/core/analyze.js +2 -2
- package/dist/core/token.cjs +58 -1
- package/dist/core/token.d.cts +14 -14
- package/dist/core/token.d.ts +14 -14
- package/dist/core/token.js +3 -1
- package/dist/index.cjs +78 -7
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/package.json +4 -1
- package/dist/chunk-7CL7GVRF.js +0 -14
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
TokenWise is a lightweight utility for preparing JSON before sending it to AI models. It helps reduce payload noise, shrink token usage, and turn structured data into formats that are easier for LLMs to consume.
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-

|
|
7
|
-

|
|
6
|
+
[](https://www.npmjs.com/package/@sohqureshi/tokenwise)
|
|
7
|
+
[](https://www.npmjs.com/package/@sohqureshi/tokenwise)
|
|
8
8
|

|
|
9
9
|

|
|
10
10
|
[](https://sohqureshi.github.io/tokenwise/)
|
|
@@ -36,6 +36,8 @@ Raw JSON is:
|
|
|
36
36
|
npm install @sohqureshi/tokenwise
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
Available on [npm](https://www.npmjs.com/package/@sohqureshi/tokenwise).
|
|
40
|
+
|
|
39
41
|
## Quick Usage
|
|
40
42
|
|
|
41
43
|
```js
|
|
@@ -68,7 +70,7 @@ console.log(ai(product).compact().value());
|
|
|
68
70
|
Removes fields you do not want to send to the model. By default it also removes `null`, `undefined`, and empty objects.
|
|
69
71
|
|
|
70
72
|
```js
|
|
71
|
-
import { prune } from "tokenwise";
|
|
73
|
+
import { prune } from "@sohqureshi/tokenwise";
|
|
72
74
|
|
|
73
75
|
const input = {
|
|
74
76
|
user: { name: "John", age: 28 },
|
|
@@ -208,9 +210,24 @@ LLMs charge and reason over tokens. Sending raw JSON often includes repeated key
|
|
|
208
210
|
node demo.js
|
|
209
211
|
```
|
|
210
212
|
|
|
211
|
-
Use `--analyze` to compare serialized input and output with
|
|
212
|
-
|
|
213
|
-
|
|
213
|
+
Use `--analyze` to compare serialized input and output with the model's
|
|
214
|
+
`tiktoken` encoding. `estimateTokens()` and `analyze()` use exact
|
|
215
|
+
model-aware counts by default; pass `exact: false` to opt into the
|
|
216
|
+
four-characters-per-token heuristic. Use `model` to select the tokenizer
|
|
217
|
+
used by `tiktoken`.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Release Notes
|
|
222
|
+
|
|
223
|
+
### v1.0.8 — 2026-09-06
|
|
224
|
+
|
|
225
|
+
- Expose exact tokenizer metadata when available (model + encoding), and fall back to a clear, model-aware estimator in browser demos.
|
|
226
|
+
- Demo updated to show selected model and expected encoding when the exact tokenizer (tiktoken) is not available in-browser.
|
|
227
|
+
- Updated analyze() to surface tokenizer encoding in analysis output so the demo shows "Estimator: model=gpt-4 expected_encoding=cl100k_base" even when using the heuristic fallback.
|
|
228
|
+
- Misc: build artifacts updated and docs demo import bumped to v1.0.7 CDN bundle.
|
|
229
|
+
|
|
230
|
+
If you want the browser demo to display truly exact token counts, run the demo against a small Node endpoint (or local server) that has tiktoken installed and uses analyze(..., { exact: true }). The estimator will display the real tokenizer encoding when tiktoken is present.
|
|
214
231
|
|
|
215
232
|
---
|
|
216
233
|
|
|
@@ -11,12 +11,17 @@ import {
|
|
|
11
11
|
prune
|
|
12
12
|
} from "./chunk-ZD536GZF.js";
|
|
13
13
|
import {
|
|
14
|
-
|
|
14
|
+
estimateTokensWithMeta,
|
|
15
15
|
serializeForTokenEstimate
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-L3HY6AWL.js";
|
|
17
17
|
|
|
18
18
|
// src/core/analyze.ts
|
|
19
19
|
function analyze(input, options = {}) {
|
|
20
|
+
const {
|
|
21
|
+
exact = true,
|
|
22
|
+
model = "gpt-4o-mini",
|
|
23
|
+
fallbackToHeuristic = true
|
|
24
|
+
} = options;
|
|
20
25
|
if (!input || typeof input === "object" && input !== null && Object.keys(input).length === 0) {
|
|
21
26
|
return {
|
|
22
27
|
originalTokens: 0,
|
|
@@ -27,10 +32,15 @@ function analyze(input, options = {}) {
|
|
|
27
32
|
reductionRatio: 1,
|
|
28
33
|
originalCharacters: 0,
|
|
29
34
|
optimizedCharacters: 0,
|
|
30
|
-
estimator: "heuristic: 1 token \u2248 4 characters"
|
|
35
|
+
estimator: exact ? `exact tokenizer: model=${model}` : "heuristic: 1 token \u2248 4 characters"
|
|
31
36
|
};
|
|
32
37
|
}
|
|
33
|
-
const
|
|
38
|
+
const originalMeta = estimateTokensWithMeta(input, {
|
|
39
|
+
exact,
|
|
40
|
+
model,
|
|
41
|
+
fallbackToHeuristic
|
|
42
|
+
});
|
|
43
|
+
const originalTokens = originalMeta.count;
|
|
34
44
|
let optimizedData = input;
|
|
35
45
|
if (options.prune && Array.isArray(options.prune)) {
|
|
36
46
|
optimizedData = prune(optimizedData, options.prune);
|
|
@@ -44,10 +54,16 @@ function analyze(input, options = {}) {
|
|
|
44
54
|
if (options.toTOON === true || options.toon === true) {
|
|
45
55
|
optimizedData = toTOON(optimizedData);
|
|
46
56
|
}
|
|
47
|
-
const
|
|
57
|
+
const optimizedMeta = estimateTokensWithMeta(optimizedData, {
|
|
58
|
+
exact,
|
|
59
|
+
model,
|
|
60
|
+
fallbackToHeuristic
|
|
61
|
+
});
|
|
62
|
+
const optimizedTokens = optimizedMeta.count;
|
|
48
63
|
const savings = Math.max(0, originalTokens - optimizedTokens);
|
|
49
64
|
const savingsPercent = originalTokens > 0 ? Math.round(savings / originalTokens * 100) : 0;
|
|
50
65
|
const reductionRatio = originalTokens > 0 ? optimizedTokens / originalTokens : 1;
|
|
66
|
+
const estimatorLabel = originalMeta && originalMeta.estimator ? originalMeta.estimator : optimizedMeta.estimator;
|
|
51
67
|
return {
|
|
52
68
|
originalTokens,
|
|
53
69
|
optimizedTokens,
|
|
@@ -57,7 +73,7 @@ function analyze(input, options = {}) {
|
|
|
57
73
|
reductionRatio,
|
|
58
74
|
originalCharacters: serializeForTokenEstimate(input).length,
|
|
59
75
|
optimizedCharacters: serializeForTokenEstimate(optimizedData).length,
|
|
60
|
-
estimator:
|
|
76
|
+
estimator: estimatorLabel
|
|
61
77
|
};
|
|
62
78
|
}
|
|
63
79
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// src/core/token.ts
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
var require2 = createRequire(import.meta.url);
|
|
4
|
+
function serializeForTokenEstimate(value) {
|
|
5
|
+
if (typeof value === "string") return value;
|
|
6
|
+
const serialized = JSON.stringify(value);
|
|
7
|
+
return serialized ?? "";
|
|
8
|
+
}
|
|
9
|
+
function estimateTokensHeuristic(value) {
|
|
10
|
+
return Math.ceil(serializeForTokenEstimate(value).length / 4);
|
|
11
|
+
}
|
|
12
|
+
function expectedEncodingForModel(model) {
|
|
13
|
+
const normalizedModel = model.toLowerCase();
|
|
14
|
+
if (normalizedModel.includes("gpt-4o") || normalizedModel.includes("gpt-4.1") || normalizedModel.includes("o1") || normalizedModel.includes("o3") || normalizedModel.includes("o4")) {
|
|
15
|
+
return "o200k_base";
|
|
16
|
+
}
|
|
17
|
+
if (normalizedModel.includes("davinci") || normalizedModel.startsWith("text-") || normalizedModel.includes("babbage") || normalizedModel.includes("curie")) {
|
|
18
|
+
return "r50k_base";
|
|
19
|
+
}
|
|
20
|
+
return "cl100k_base";
|
|
21
|
+
}
|
|
22
|
+
function estimateTokens(value, options = {}) {
|
|
23
|
+
return estimateTokensWithMeta(value, options).count;
|
|
24
|
+
}
|
|
25
|
+
function estimateTokensWithMeta(value, options = {}) {
|
|
26
|
+
const { exact = true, model = "gpt-4o-mini", fallbackToHeuristic = true } = options;
|
|
27
|
+
const heuristic = estimateTokensHeuristic(value);
|
|
28
|
+
const heuristicEstimator = "heuristic: 1 token \u2248 4 characters";
|
|
29
|
+
if (!exact) {
|
|
30
|
+
return { count: heuristic, estimator: heuristicEstimator };
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const tiktoken = require2("tiktoken");
|
|
34
|
+
const encoder = tiktoken.encoding_for_model(model);
|
|
35
|
+
const count = encoder.encode(serializeForTokenEstimate(value)).length;
|
|
36
|
+
let encodingName = encoder.name;
|
|
37
|
+
if (!encodingName && typeof tiktoken.model_to_encoding === "function") {
|
|
38
|
+
try {
|
|
39
|
+
encodingName = tiktoken.model_to_encoding(model);
|
|
40
|
+
} catch {
|
|
41
|
+
encodingName = void 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
encodingName ?? (encodingName = expectedEncodingForModel(model));
|
|
45
|
+
encoder.free?.();
|
|
46
|
+
return {
|
|
47
|
+
count,
|
|
48
|
+
estimator: `exact tokenizer: model=${model} encoding=${encodingName}`
|
|
49
|
+
};
|
|
50
|
+
} catch {
|
|
51
|
+
const expectedEncoding = expectedEncodingForModel(model);
|
|
52
|
+
if (!fallbackToHeuristic) {
|
|
53
|
+
return {
|
|
54
|
+
count: heuristic,
|
|
55
|
+
estimator: `exact requested but tokenizer unavailable (expected encoding=${expectedEncoding} for model=${model})`
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
count: heuristic,
|
|
60
|
+
estimator: `${heuristicEstimator} (model=${model} expected_encoding=${expectedEncoding})`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export {
|
|
66
|
+
serializeForTokenEstimate,
|
|
67
|
+
estimateTokens,
|
|
68
|
+
estimateTokensWithMeta
|
|
69
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
analyze
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2TDVL6BJ.js";
|
|
4
4
|
import {
|
|
5
5
|
toTOON
|
|
6
6
|
} from "./chunk-6VRLDRJK.js";
|
|
@@ -41,8 +41,8 @@ var AIChain = class {
|
|
|
41
41
|
toNatural() {
|
|
42
42
|
return toNatural(this.data);
|
|
43
43
|
}
|
|
44
|
-
analyze() {
|
|
45
|
-
return analyze(this.data);
|
|
44
|
+
analyze(options) {
|
|
45
|
+
return analyze(this.data, options);
|
|
46
46
|
}
|
|
47
47
|
value() {
|
|
48
48
|
return this.data;
|
package/dist/cli.cjs
CHANGED
|
@@ -142,17 +142,74 @@ function isPlainObject(value) {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
// src/core/token.ts
|
|
145
|
+
var import_node_module = require("module");
|
|
146
|
+
var import_meta = {};
|
|
147
|
+
var require2 = (0, import_node_module.createRequire)(import_meta.url);
|
|
145
148
|
function serializeForTokenEstimate(value) {
|
|
146
149
|
if (typeof value === "string") return value;
|
|
147
150
|
const serialized = JSON.stringify(value);
|
|
148
151
|
return serialized ?? "";
|
|
149
152
|
}
|
|
150
|
-
function
|
|
153
|
+
function estimateTokensHeuristic(value) {
|
|
151
154
|
return Math.ceil(serializeForTokenEstimate(value).length / 4);
|
|
152
155
|
}
|
|
156
|
+
function expectedEncodingForModel(model) {
|
|
157
|
+
const normalizedModel = model.toLowerCase();
|
|
158
|
+
if (normalizedModel.includes("gpt-4o") || normalizedModel.includes("gpt-4.1") || normalizedModel.includes("o1") || normalizedModel.includes("o3") || normalizedModel.includes("o4")) {
|
|
159
|
+
return "o200k_base";
|
|
160
|
+
}
|
|
161
|
+
if (normalizedModel.includes("davinci") || normalizedModel.startsWith("text-") || normalizedModel.includes("babbage") || normalizedModel.includes("curie")) {
|
|
162
|
+
return "r50k_base";
|
|
163
|
+
}
|
|
164
|
+
return "cl100k_base";
|
|
165
|
+
}
|
|
166
|
+
function estimateTokensWithMeta(value, options = {}) {
|
|
167
|
+
const { exact = true, model = "gpt-4o-mini", fallbackToHeuristic = true } = options;
|
|
168
|
+
const heuristic = estimateTokensHeuristic(value);
|
|
169
|
+
const heuristicEstimator = "heuristic: 1 token \u2248 4 characters";
|
|
170
|
+
if (!exact) {
|
|
171
|
+
return { count: heuristic, estimator: heuristicEstimator };
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const tiktoken = require2("tiktoken");
|
|
175
|
+
const encoder = tiktoken.encoding_for_model(model);
|
|
176
|
+
const count = encoder.encode(serializeForTokenEstimate(value)).length;
|
|
177
|
+
let encodingName = encoder.name;
|
|
178
|
+
if (!encodingName && typeof tiktoken.model_to_encoding === "function") {
|
|
179
|
+
try {
|
|
180
|
+
encodingName = tiktoken.model_to_encoding(model);
|
|
181
|
+
} catch {
|
|
182
|
+
encodingName = void 0;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
encodingName ?? (encodingName = expectedEncodingForModel(model));
|
|
186
|
+
encoder.free?.();
|
|
187
|
+
return {
|
|
188
|
+
count,
|
|
189
|
+
estimator: `exact tokenizer: model=${model} encoding=${encodingName}`
|
|
190
|
+
};
|
|
191
|
+
} catch {
|
|
192
|
+
const expectedEncoding = expectedEncodingForModel(model);
|
|
193
|
+
if (!fallbackToHeuristic) {
|
|
194
|
+
return {
|
|
195
|
+
count: heuristic,
|
|
196
|
+
estimator: `exact requested but tokenizer unavailable (expected encoding=${expectedEncoding} for model=${model})`
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
count: heuristic,
|
|
201
|
+
estimator: `${heuristicEstimator} (model=${model} expected_encoding=${expectedEncoding})`
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
153
205
|
|
|
154
206
|
// src/core/analyze.ts
|
|
155
207
|
function analyze(input, options = {}) {
|
|
208
|
+
const {
|
|
209
|
+
exact = true,
|
|
210
|
+
model = "gpt-4o-mini",
|
|
211
|
+
fallbackToHeuristic = true
|
|
212
|
+
} = options;
|
|
156
213
|
if (!input || typeof input === "object" && input !== null && Object.keys(input).length === 0) {
|
|
157
214
|
return {
|
|
158
215
|
originalTokens: 0,
|
|
@@ -163,10 +220,15 @@ function analyze(input, options = {}) {
|
|
|
163
220
|
reductionRatio: 1,
|
|
164
221
|
originalCharacters: 0,
|
|
165
222
|
optimizedCharacters: 0,
|
|
166
|
-
estimator: "heuristic: 1 token \u2248 4 characters"
|
|
223
|
+
estimator: exact ? `exact tokenizer: model=${model}` : "heuristic: 1 token \u2248 4 characters"
|
|
167
224
|
};
|
|
168
225
|
}
|
|
169
|
-
const
|
|
226
|
+
const originalMeta = estimateTokensWithMeta(input, {
|
|
227
|
+
exact,
|
|
228
|
+
model,
|
|
229
|
+
fallbackToHeuristic
|
|
230
|
+
});
|
|
231
|
+
const originalTokens = originalMeta.count;
|
|
170
232
|
let optimizedData = input;
|
|
171
233
|
if (options.prune && Array.isArray(options.prune)) {
|
|
172
234
|
optimizedData = prune(optimizedData, options.prune);
|
|
@@ -180,10 +242,16 @@ function analyze(input, options = {}) {
|
|
|
180
242
|
if (options.toTOON === true || options.toon === true) {
|
|
181
243
|
optimizedData = toTOON(optimizedData);
|
|
182
244
|
}
|
|
183
|
-
const
|
|
245
|
+
const optimizedMeta = estimateTokensWithMeta(optimizedData, {
|
|
246
|
+
exact,
|
|
247
|
+
model,
|
|
248
|
+
fallbackToHeuristic
|
|
249
|
+
});
|
|
250
|
+
const optimizedTokens = optimizedMeta.count;
|
|
184
251
|
const savings = Math.max(0, originalTokens - optimizedTokens);
|
|
185
252
|
const savingsPercent = originalTokens > 0 ? Math.round(savings / originalTokens * 100) : 0;
|
|
186
253
|
const reductionRatio = originalTokens > 0 ? optimizedTokens / originalTokens : 1;
|
|
254
|
+
const estimatorLabel = originalMeta && originalMeta.estimator ? originalMeta.estimator : optimizedMeta.estimator;
|
|
187
255
|
return {
|
|
188
256
|
originalTokens,
|
|
189
257
|
optimizedTokens,
|
|
@@ -193,7 +261,7 @@ function analyze(input, options = {}) {
|
|
|
193
261
|
reductionRatio,
|
|
194
262
|
originalCharacters: serializeForTokenEstimate(input).length,
|
|
195
263
|
optimizedCharacters: serializeForTokenEstimate(optimizedData).length,
|
|
196
|
-
estimator:
|
|
264
|
+
estimator: estimatorLabel
|
|
197
265
|
};
|
|
198
266
|
}
|
|
199
267
|
|
|
@@ -323,8 +391,8 @@ var AIChain = class {
|
|
|
323
391
|
toNatural() {
|
|
324
392
|
return toNatural(this.data);
|
|
325
393
|
}
|
|
326
|
-
analyze() {
|
|
327
|
-
return analyze(this.data);
|
|
394
|
+
analyze(options) {
|
|
395
|
+
return analyze(this.data, options);
|
|
328
396
|
}
|
|
329
397
|
value() {
|
|
330
398
|
return this.data;
|
|
@@ -341,7 +409,7 @@ Usage:
|
|
|
341
409
|
Options:
|
|
342
410
|
--toon Convert JSON to TOON format
|
|
343
411
|
--compact Convert JSON to compact format
|
|
344
|
-
--analyze Show token analysis (
|
|
412
|
+
--analyze Show token analysis (tiktoken estimate)
|
|
345
413
|
`);
|
|
346
414
|
process.exit(0);
|
|
347
415
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AIChain
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-QHCUNOUH.js";
|
|
5
|
+
import "./chunk-2TDVL6BJ.js";
|
|
6
6
|
import "./chunk-6VRLDRJK.js";
|
|
7
7
|
import "./chunk-XE36GLJP.js";
|
|
8
8
|
import "./chunk-L7BC62MT.js";
|
|
9
9
|
import "./chunk-D4CFTFM3.js";
|
|
10
10
|
import "./chunk-ZD536GZF.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-L3HY6AWL.js";
|
|
12
12
|
|
|
13
13
|
// src/cli.ts
|
|
14
14
|
import fs from "fs";
|
|
@@ -22,7 +22,7 @@ Usage:
|
|
|
22
22
|
Options:
|
|
23
23
|
--toon Convert JSON to TOON format
|
|
24
24
|
--compact Convert JSON to compact format
|
|
25
|
-
--analyze Show token analysis (
|
|
25
|
+
--analyze Show token analysis (tiktoken estimate)
|
|
26
26
|
`);
|
|
27
27
|
process.exit(0);
|
|
28
28
|
}
|
package/dist/core/analyze.cjs
CHANGED
|
@@ -139,17 +139,74 @@ function isPlainObject(value) {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
// src/core/token.ts
|
|
142
|
+
var import_node_module = require("module");
|
|
143
|
+
var import_meta = {};
|
|
144
|
+
var require2 = (0, import_node_module.createRequire)(import_meta.url);
|
|
142
145
|
function serializeForTokenEstimate(value) {
|
|
143
146
|
if (typeof value === "string") return value;
|
|
144
147
|
const serialized = JSON.stringify(value);
|
|
145
148
|
return serialized ?? "";
|
|
146
149
|
}
|
|
147
|
-
function
|
|
150
|
+
function estimateTokensHeuristic(value) {
|
|
148
151
|
return Math.ceil(serializeForTokenEstimate(value).length / 4);
|
|
149
152
|
}
|
|
153
|
+
function expectedEncodingForModel(model) {
|
|
154
|
+
const normalizedModel = model.toLowerCase();
|
|
155
|
+
if (normalizedModel.includes("gpt-4o") || normalizedModel.includes("gpt-4.1") || normalizedModel.includes("o1") || normalizedModel.includes("o3") || normalizedModel.includes("o4")) {
|
|
156
|
+
return "o200k_base";
|
|
157
|
+
}
|
|
158
|
+
if (normalizedModel.includes("davinci") || normalizedModel.startsWith("text-") || normalizedModel.includes("babbage") || normalizedModel.includes("curie")) {
|
|
159
|
+
return "r50k_base";
|
|
160
|
+
}
|
|
161
|
+
return "cl100k_base";
|
|
162
|
+
}
|
|
163
|
+
function estimateTokensWithMeta(value, options = {}) {
|
|
164
|
+
const { exact = true, model = "gpt-4o-mini", fallbackToHeuristic = true } = options;
|
|
165
|
+
const heuristic = estimateTokensHeuristic(value);
|
|
166
|
+
const heuristicEstimator = "heuristic: 1 token \u2248 4 characters";
|
|
167
|
+
if (!exact) {
|
|
168
|
+
return { count: heuristic, estimator: heuristicEstimator };
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const tiktoken = require2("tiktoken");
|
|
172
|
+
const encoder = tiktoken.encoding_for_model(model);
|
|
173
|
+
const count = encoder.encode(serializeForTokenEstimate(value)).length;
|
|
174
|
+
let encodingName = encoder.name;
|
|
175
|
+
if (!encodingName && typeof tiktoken.model_to_encoding === "function") {
|
|
176
|
+
try {
|
|
177
|
+
encodingName = tiktoken.model_to_encoding(model);
|
|
178
|
+
} catch {
|
|
179
|
+
encodingName = void 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
encodingName ?? (encodingName = expectedEncodingForModel(model));
|
|
183
|
+
encoder.free?.();
|
|
184
|
+
return {
|
|
185
|
+
count,
|
|
186
|
+
estimator: `exact tokenizer: model=${model} encoding=${encodingName}`
|
|
187
|
+
};
|
|
188
|
+
} catch {
|
|
189
|
+
const expectedEncoding = expectedEncodingForModel(model);
|
|
190
|
+
if (!fallbackToHeuristic) {
|
|
191
|
+
return {
|
|
192
|
+
count: heuristic,
|
|
193
|
+
estimator: `exact requested but tokenizer unavailable (expected encoding=${expectedEncoding} for model=${model})`
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
count: heuristic,
|
|
198
|
+
estimator: `${heuristicEstimator} (model=${model} expected_encoding=${expectedEncoding})`
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
150
202
|
|
|
151
203
|
// src/core/analyze.ts
|
|
152
204
|
function analyze(input, options = {}) {
|
|
205
|
+
const {
|
|
206
|
+
exact = true,
|
|
207
|
+
model = "gpt-4o-mini",
|
|
208
|
+
fallbackToHeuristic = true
|
|
209
|
+
} = options;
|
|
153
210
|
if (!input || typeof input === "object" && input !== null && Object.keys(input).length === 0) {
|
|
154
211
|
return {
|
|
155
212
|
originalTokens: 0,
|
|
@@ -160,10 +217,15 @@ function analyze(input, options = {}) {
|
|
|
160
217
|
reductionRatio: 1,
|
|
161
218
|
originalCharacters: 0,
|
|
162
219
|
optimizedCharacters: 0,
|
|
163
|
-
estimator: "heuristic: 1 token \u2248 4 characters"
|
|
220
|
+
estimator: exact ? `exact tokenizer: model=${model}` : "heuristic: 1 token \u2248 4 characters"
|
|
164
221
|
};
|
|
165
222
|
}
|
|
166
|
-
const
|
|
223
|
+
const originalMeta = estimateTokensWithMeta(input, {
|
|
224
|
+
exact,
|
|
225
|
+
model,
|
|
226
|
+
fallbackToHeuristic
|
|
227
|
+
});
|
|
228
|
+
const originalTokens = originalMeta.count;
|
|
167
229
|
let optimizedData = input;
|
|
168
230
|
if (options.prune && Array.isArray(options.prune)) {
|
|
169
231
|
optimizedData = prune(optimizedData, options.prune);
|
|
@@ -177,10 +239,16 @@ function analyze(input, options = {}) {
|
|
|
177
239
|
if (options.toTOON === true || options.toon === true) {
|
|
178
240
|
optimizedData = toTOON(optimizedData);
|
|
179
241
|
}
|
|
180
|
-
const
|
|
242
|
+
const optimizedMeta = estimateTokensWithMeta(optimizedData, {
|
|
243
|
+
exact,
|
|
244
|
+
model,
|
|
245
|
+
fallbackToHeuristic
|
|
246
|
+
});
|
|
247
|
+
const optimizedTokens = optimizedMeta.count;
|
|
181
248
|
const savings = Math.max(0, originalTokens - optimizedTokens);
|
|
182
249
|
const savingsPercent = originalTokens > 0 ? Math.round(savings / originalTokens * 100) : 0;
|
|
183
250
|
const reductionRatio = originalTokens > 0 ? optimizedTokens / originalTokens : 1;
|
|
251
|
+
const estimatorLabel = originalMeta && originalMeta.estimator ? originalMeta.estimator : optimizedMeta.estimator;
|
|
184
252
|
return {
|
|
185
253
|
originalTokens,
|
|
186
254
|
optimizedTokens,
|
|
@@ -190,7 +258,7 @@ function analyze(input, options = {}) {
|
|
|
190
258
|
reductionRatio,
|
|
191
259
|
originalCharacters: serializeForTokenEstimate(input).length,
|
|
192
260
|
optimizedCharacters: serializeForTokenEstimate(optimizedData).length,
|
|
193
|
-
estimator:
|
|
261
|
+
estimator: estimatorLabel
|
|
194
262
|
};
|
|
195
263
|
}
|
|
196
264
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/core/analyze.d.cts
CHANGED
package/dist/core/analyze.d.ts
CHANGED
package/dist/core/analyze.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
analyze
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-2TDVL6BJ.js";
|
|
4
4
|
import "../chunk-6VRLDRJK.js";
|
|
5
5
|
import "../chunk-XE36GLJP.js";
|
|
6
6
|
import "../chunk-L7BC62MT.js";
|
|
7
7
|
import "../chunk-ZD536GZF.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-L3HY6AWL.js";
|
|
9
9
|
export {
|
|
10
10
|
analyze
|
|
11
11
|
};
|
package/dist/core/token.cjs
CHANGED
|
@@ -21,19 +21,76 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var token_exports = {};
|
|
22
22
|
__export(token_exports, {
|
|
23
23
|
estimateTokens: () => estimateTokens,
|
|
24
|
+
estimateTokensWithMeta: () => estimateTokensWithMeta,
|
|
24
25
|
serializeForTokenEstimate: () => serializeForTokenEstimate
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(token_exports);
|
|
28
|
+
var import_node_module = require("module");
|
|
29
|
+
var import_meta = {};
|
|
30
|
+
var require2 = (0, import_node_module.createRequire)(import_meta.url);
|
|
27
31
|
function serializeForTokenEstimate(value) {
|
|
28
32
|
if (typeof value === "string") return value;
|
|
29
33
|
const serialized = JSON.stringify(value);
|
|
30
34
|
return serialized ?? "";
|
|
31
35
|
}
|
|
32
|
-
function
|
|
36
|
+
function estimateTokensHeuristic(value) {
|
|
33
37
|
return Math.ceil(serializeForTokenEstimate(value).length / 4);
|
|
34
38
|
}
|
|
39
|
+
function expectedEncodingForModel(model) {
|
|
40
|
+
const normalizedModel = model.toLowerCase();
|
|
41
|
+
if (normalizedModel.includes("gpt-4o") || normalizedModel.includes("gpt-4.1") || normalizedModel.includes("o1") || normalizedModel.includes("o3") || normalizedModel.includes("o4")) {
|
|
42
|
+
return "o200k_base";
|
|
43
|
+
}
|
|
44
|
+
if (normalizedModel.includes("davinci") || normalizedModel.startsWith("text-") || normalizedModel.includes("babbage") || normalizedModel.includes("curie")) {
|
|
45
|
+
return "r50k_base";
|
|
46
|
+
}
|
|
47
|
+
return "cl100k_base";
|
|
48
|
+
}
|
|
49
|
+
function estimateTokens(value, options = {}) {
|
|
50
|
+
return estimateTokensWithMeta(value, options).count;
|
|
51
|
+
}
|
|
52
|
+
function estimateTokensWithMeta(value, options = {}) {
|
|
53
|
+
const { exact = true, model = "gpt-4o-mini", fallbackToHeuristic = true } = options;
|
|
54
|
+
const heuristic = estimateTokensHeuristic(value);
|
|
55
|
+
const heuristicEstimator = "heuristic: 1 token \u2248 4 characters";
|
|
56
|
+
if (!exact) {
|
|
57
|
+
return { count: heuristic, estimator: heuristicEstimator };
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const tiktoken = require2("tiktoken");
|
|
61
|
+
const encoder = tiktoken.encoding_for_model(model);
|
|
62
|
+
const count = encoder.encode(serializeForTokenEstimate(value)).length;
|
|
63
|
+
let encodingName = encoder.name;
|
|
64
|
+
if (!encodingName && typeof tiktoken.model_to_encoding === "function") {
|
|
65
|
+
try {
|
|
66
|
+
encodingName = tiktoken.model_to_encoding(model);
|
|
67
|
+
} catch {
|
|
68
|
+
encodingName = void 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
encodingName ?? (encodingName = expectedEncodingForModel(model));
|
|
72
|
+
encoder.free?.();
|
|
73
|
+
return {
|
|
74
|
+
count,
|
|
75
|
+
estimator: `exact tokenizer: model=${model} encoding=${encodingName}`
|
|
76
|
+
};
|
|
77
|
+
} catch {
|
|
78
|
+
const expectedEncoding = expectedEncodingForModel(model);
|
|
79
|
+
if (!fallbackToHeuristic) {
|
|
80
|
+
return {
|
|
81
|
+
count: heuristic,
|
|
82
|
+
estimator: `exact requested but tokenizer unavailable (expected encoding=${expectedEncoding} for model=${model})`
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
count: heuristic,
|
|
87
|
+
estimator: `${heuristicEstimator} (model=${model} expected_encoding=${expectedEncoding})`
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
35
91
|
// Annotate the CommonJS export names for ESM import in node:
|
|
36
92
|
0 && (module.exports = {
|
|
37
93
|
estimateTokens,
|
|
94
|
+
estimateTokensWithMeta,
|
|
38
95
|
serializeForTokenEstimate
|
|
39
96
|
});
|
package/dist/core/token.d.cts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* @param text - Input string
|
|
8
|
-
* @returns Estimated token count
|
|
9
|
-
*/
|
|
1
|
+
interface TokenEstimateOptions {
|
|
2
|
+
exact?: boolean;
|
|
3
|
+
model?: string;
|
|
4
|
+
fallbackToHeuristic?: boolean;
|
|
5
|
+
}
|
|
10
6
|
declare function serializeForTokenEstimate(value: unknown): string;
|
|
7
|
+
type TokenEstimateResult = {
|
|
8
|
+
count: number;
|
|
9
|
+
estimator: string;
|
|
10
|
+
};
|
|
11
|
+
declare function estimateTokens(value: unknown, options?: TokenEstimateOptions): number;
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* to an API. Use a model-specific tokenizer for billing-accurate counts.
|
|
13
|
+
* Returns an exact model tokenizer count by default. Set exact=false to use the
|
|
14
|
+
* lightweight four-characters-per-token fallback explicitly.
|
|
15
15
|
*/
|
|
16
|
-
declare function
|
|
16
|
+
declare function estimateTokensWithMeta(value: unknown, options?: TokenEstimateOptions): TokenEstimateResult;
|
|
17
17
|
|
|
18
|
-
export { estimateTokens, serializeForTokenEstimate };
|
|
18
|
+
export { type TokenEstimateOptions, type TokenEstimateResult, estimateTokens, estimateTokensWithMeta, serializeForTokenEstimate };
|
package/dist/core/token.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* @param text - Input string
|
|
8
|
-
* @returns Estimated token count
|
|
9
|
-
*/
|
|
1
|
+
interface TokenEstimateOptions {
|
|
2
|
+
exact?: boolean;
|
|
3
|
+
model?: string;
|
|
4
|
+
fallbackToHeuristic?: boolean;
|
|
5
|
+
}
|
|
10
6
|
declare function serializeForTokenEstimate(value: unknown): string;
|
|
7
|
+
type TokenEstimateResult = {
|
|
8
|
+
count: number;
|
|
9
|
+
estimator: string;
|
|
10
|
+
};
|
|
11
|
+
declare function estimateTokens(value: unknown, options?: TokenEstimateOptions): number;
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* to an API. Use a model-specific tokenizer for billing-accurate counts.
|
|
13
|
+
* Returns an exact model tokenizer count by default. Set exact=false to use the
|
|
14
|
+
* lightweight four-characters-per-token fallback explicitly.
|
|
15
15
|
*/
|
|
16
|
-
declare function
|
|
16
|
+
declare function estimateTokensWithMeta(value: unknown, options?: TokenEstimateOptions): TokenEstimateResult;
|
|
17
17
|
|
|
18
|
-
export { estimateTokens, serializeForTokenEstimate };
|
|
18
|
+
export { type TokenEstimateOptions, type TokenEstimateResult, estimateTokens, estimateTokensWithMeta, serializeForTokenEstimate };
|
package/dist/core/token.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -148,17 +148,77 @@ function isPlainObject(value) {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// src/core/token.ts
|
|
151
|
+
var import_node_module = require("module");
|
|
152
|
+
var import_meta = {};
|
|
153
|
+
var require2 = (0, import_node_module.createRequire)(import_meta.url);
|
|
151
154
|
function serializeForTokenEstimate(value) {
|
|
152
155
|
if (typeof value === "string") return value;
|
|
153
156
|
const serialized = JSON.stringify(value);
|
|
154
157
|
return serialized ?? "";
|
|
155
158
|
}
|
|
156
|
-
function
|
|
159
|
+
function estimateTokensHeuristic(value) {
|
|
157
160
|
return Math.ceil(serializeForTokenEstimate(value).length / 4);
|
|
158
161
|
}
|
|
162
|
+
function expectedEncodingForModel(model) {
|
|
163
|
+
const normalizedModel = model.toLowerCase();
|
|
164
|
+
if (normalizedModel.includes("gpt-4o") || normalizedModel.includes("gpt-4.1") || normalizedModel.includes("o1") || normalizedModel.includes("o3") || normalizedModel.includes("o4")) {
|
|
165
|
+
return "o200k_base";
|
|
166
|
+
}
|
|
167
|
+
if (normalizedModel.includes("davinci") || normalizedModel.startsWith("text-") || normalizedModel.includes("babbage") || normalizedModel.includes("curie")) {
|
|
168
|
+
return "r50k_base";
|
|
169
|
+
}
|
|
170
|
+
return "cl100k_base";
|
|
171
|
+
}
|
|
172
|
+
function estimateTokens(value, options = {}) {
|
|
173
|
+
return estimateTokensWithMeta(value, options).count;
|
|
174
|
+
}
|
|
175
|
+
function estimateTokensWithMeta(value, options = {}) {
|
|
176
|
+
const { exact = true, model = "gpt-4o-mini", fallbackToHeuristic = true } = options;
|
|
177
|
+
const heuristic = estimateTokensHeuristic(value);
|
|
178
|
+
const heuristicEstimator = "heuristic: 1 token \u2248 4 characters";
|
|
179
|
+
if (!exact) {
|
|
180
|
+
return { count: heuristic, estimator: heuristicEstimator };
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const tiktoken = require2("tiktoken");
|
|
184
|
+
const encoder = tiktoken.encoding_for_model(model);
|
|
185
|
+
const count = encoder.encode(serializeForTokenEstimate(value)).length;
|
|
186
|
+
let encodingName = encoder.name;
|
|
187
|
+
if (!encodingName && typeof tiktoken.model_to_encoding === "function") {
|
|
188
|
+
try {
|
|
189
|
+
encodingName = tiktoken.model_to_encoding(model);
|
|
190
|
+
} catch {
|
|
191
|
+
encodingName = void 0;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
encodingName ?? (encodingName = expectedEncodingForModel(model));
|
|
195
|
+
encoder.free?.();
|
|
196
|
+
return {
|
|
197
|
+
count,
|
|
198
|
+
estimator: `exact tokenizer: model=${model} encoding=${encodingName}`
|
|
199
|
+
};
|
|
200
|
+
} catch {
|
|
201
|
+
const expectedEncoding = expectedEncodingForModel(model);
|
|
202
|
+
if (!fallbackToHeuristic) {
|
|
203
|
+
return {
|
|
204
|
+
count: heuristic,
|
|
205
|
+
estimator: `exact requested but tokenizer unavailable (expected encoding=${expectedEncoding} for model=${model})`
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
count: heuristic,
|
|
210
|
+
estimator: `${heuristicEstimator} (model=${model} expected_encoding=${expectedEncoding})`
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
159
214
|
|
|
160
215
|
// src/core/analyze.ts
|
|
161
216
|
function analyze(input, options = {}) {
|
|
217
|
+
const {
|
|
218
|
+
exact = true,
|
|
219
|
+
model = "gpt-4o-mini",
|
|
220
|
+
fallbackToHeuristic = true
|
|
221
|
+
} = options;
|
|
162
222
|
if (!input || typeof input === "object" && input !== null && Object.keys(input).length === 0) {
|
|
163
223
|
return {
|
|
164
224
|
originalTokens: 0,
|
|
@@ -169,10 +229,15 @@ function analyze(input, options = {}) {
|
|
|
169
229
|
reductionRatio: 1,
|
|
170
230
|
originalCharacters: 0,
|
|
171
231
|
optimizedCharacters: 0,
|
|
172
|
-
estimator: "heuristic: 1 token \u2248 4 characters"
|
|
232
|
+
estimator: exact ? `exact tokenizer: model=${model}` : "heuristic: 1 token \u2248 4 characters"
|
|
173
233
|
};
|
|
174
234
|
}
|
|
175
|
-
const
|
|
235
|
+
const originalMeta = estimateTokensWithMeta(input, {
|
|
236
|
+
exact,
|
|
237
|
+
model,
|
|
238
|
+
fallbackToHeuristic
|
|
239
|
+
});
|
|
240
|
+
const originalTokens = originalMeta.count;
|
|
176
241
|
let optimizedData = input;
|
|
177
242
|
if (options.prune && Array.isArray(options.prune)) {
|
|
178
243
|
optimizedData = prune(optimizedData, options.prune);
|
|
@@ -186,10 +251,16 @@ function analyze(input, options = {}) {
|
|
|
186
251
|
if (options.toTOON === true || options.toon === true) {
|
|
187
252
|
optimizedData = toTOON(optimizedData);
|
|
188
253
|
}
|
|
189
|
-
const
|
|
254
|
+
const optimizedMeta = estimateTokensWithMeta(optimizedData, {
|
|
255
|
+
exact,
|
|
256
|
+
model,
|
|
257
|
+
fallbackToHeuristic
|
|
258
|
+
});
|
|
259
|
+
const optimizedTokens = optimizedMeta.count;
|
|
190
260
|
const savings = Math.max(0, originalTokens - optimizedTokens);
|
|
191
261
|
const savingsPercent = originalTokens > 0 ? Math.round(savings / originalTokens * 100) : 0;
|
|
192
262
|
const reductionRatio = originalTokens > 0 ? optimizedTokens / originalTokens : 1;
|
|
263
|
+
const estimatorLabel = originalMeta && originalMeta.estimator ? originalMeta.estimator : optimizedMeta.estimator;
|
|
193
264
|
return {
|
|
194
265
|
originalTokens,
|
|
195
266
|
optimizedTokens,
|
|
@@ -199,7 +270,7 @@ function analyze(input, options = {}) {
|
|
|
199
270
|
reductionRatio,
|
|
200
271
|
originalCharacters: serializeForTokenEstimate(input).length,
|
|
201
272
|
optimizedCharacters: serializeForTokenEstimate(optimizedData).length,
|
|
202
|
-
estimator:
|
|
273
|
+
estimator: estimatorLabel
|
|
203
274
|
};
|
|
204
275
|
}
|
|
205
276
|
|
|
@@ -329,8 +400,8 @@ var AIChain = class {
|
|
|
329
400
|
toNatural() {
|
|
330
401
|
return toNatural(this.data);
|
|
331
402
|
}
|
|
332
|
-
analyze() {
|
|
333
|
-
return analyze(this.data);
|
|
403
|
+
analyze(options) {
|
|
404
|
+
return analyze(this.data, options);
|
|
334
405
|
}
|
|
335
406
|
value() {
|
|
336
407
|
return this.data;
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AIChain
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QHCUNOUH.js";
|
|
4
4
|
import {
|
|
5
5
|
analyze
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2TDVL6BJ.js";
|
|
7
7
|
import {
|
|
8
8
|
toTOON
|
|
9
9
|
} from "./chunk-6VRLDRJK.js";
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import {
|
|
23
23
|
estimateTokens,
|
|
24
24
|
serializeForTokenEstimate
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-L3HY6AWL.js";
|
|
26
26
|
|
|
27
27
|
// src/index.ts
|
|
28
28
|
function ai(data) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sohqureshi/tokenwise",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Optimize JSON data for AI by reducing token usage",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -75,6 +75,9 @@
|
|
|
75
75
|
],
|
|
76
76
|
"author": "Mohammad Sohail",
|
|
77
77
|
"license": "MIT",
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"tiktoken": "^1.0.22"
|
|
80
|
+
},
|
|
78
81
|
"devDependencies": {
|
|
79
82
|
"@types/node": "^25.6.0",
|
|
80
83
|
"tsup": "^8.0.0",
|
package/dist/chunk-7CL7GVRF.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// src/core/token.ts
|
|
2
|
-
function serializeForTokenEstimate(value) {
|
|
3
|
-
if (typeof value === "string") return value;
|
|
4
|
-
const serialized = JSON.stringify(value);
|
|
5
|
-
return serialized ?? "";
|
|
6
|
-
}
|
|
7
|
-
function estimateTokens(value) {
|
|
8
|
-
return Math.ceil(serializeForTokenEstimate(value).length / 4);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
serializeForTokenEstimate,
|
|
13
|
-
estimateTokens
|
|
14
|
-
};
|