Skip to content

Commit 1f5206c

Browse files
authored
Merge pull request #1526 from QwenLM/chore/no-tiktoken
chore: remove tiktoken dependency and use API-reported token counts
2 parents 19bbd22 + c14ddab commit 1f5206c

24 files changed

+481
-595
lines changed

docs/developers/development/npm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ This is the most critical stage where files are moved and transformed into their
202202
- Copies README.md and LICENSE to dist/
203203
- Copies locales folder for internationalization
204204
- Creates a clean package.json for distribution with only necessary dependencies
205-
- Includes runtime dependencies like tiktoken
205+
- Keeps distribution dependencies minimal (no bundled runtime deps)
206206
- Maintains optional dependencies for node-pty
207207

208208
2. The JavaScript Bundle is Created:

esbuild.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ const external = [
3333
'@lydell/node-pty-linux-x64',
3434
'@lydell/node-pty-win32-arm64',
3535
'@lydell/node-pty-win32-x64',
36-
'tiktoken',
3736
];
3837

3938
esbuild

package-lock.json

Lines changed: 0 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cli/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@
3838
"dependencies": {
3939
"@google/genai": "1.30.0",
4040
"@iarna/toml": "^2.2.5",
41-
"@qwen-code/qwen-code-core": "file:../core",
4241
"@modelcontextprotocol/sdk": "^1.25.1",
42+
"@qwen-code/qwen-code-core": "file:../core",
4343
"@types/update-notifier": "^6.0.8",
4444
"ansi-regex": "^6.2.2",
4545
"command-exists": "^1.2.9",
4646
"comment-json": "^4.2.5",
4747
"diff": "^7.0.0",
4848
"dotenv": "^17.1.0",
49+
"extract-zip": "^2.0.1",
4950
"fzf": "^0.5.2",
5051
"glob": "^10.5.0",
5152
"highlight.js": "^11.11.1",
@@ -65,7 +66,6 @@
6566
"strip-json-comments": "^3.1.1",
6667
"tar": "^7.5.2",
6768
"undici": "^6.22.0",
68-
"extract-zip": "^2.0.1",
6969
"update-notifier": "^7.3.1",
7070
"wrap-ansi": "9.0.2",
7171
"yargs": "^17.7.2",
@@ -74,6 +74,7 @@
7474
"devDependencies": {
7575
"@babel/runtime": "^7.27.6",
7676
"@google/gemini-cli-test-utils": "file:../test-utils",
77+
"@qwen-code/qwen-code-test-utils": "file:../test-utils",
7778
"@testing-library/react": "^16.3.0",
7879
"@types/archiver": "^6.0.3",
7980
"@types/command-exists": "^1.2.3",
@@ -92,8 +93,7 @@
9293
"pretty-format": "^30.0.2",
9394
"react-dom": "^19.1.0",
9495
"typescript": "^5.3.3",
95-
"vitest": "^3.1.1",
96-
"@qwen-code/qwen-code-test-utils": "file:../test-utils"
96+
"vitest": "^3.1.1"
9797
},
9898
"engines": {
9999
"node": ">=20"

packages/core/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
"shell-quote": "^1.8.3",
6464
"simple-git": "^3.28.0",
6565
"strip-ansi": "^7.1.0",
66-
"tiktoken": "^1.0.21",
6766
"undici": "^6.22.0",
6867
"uuid": "^9.0.1",
6968
"ws": "^8.18.0"

packages/core/src/core/anthropicContentGenerator/anthropicContentGenerator.test.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ const mockTokenizer = {
1919
};
2020

2121
vi.mock('../../utils/request-tokenizer/index.js', () => ({
22-
getDefaultTokenizer: vi.fn(() => mockTokenizer),
23-
DefaultRequestTokenizer: vi.fn(() => mockTokenizer),
24-
disposeDefaultTokenizer: vi.fn(),
22+
RequestTokenEstimator: vi.fn(() => mockTokenizer),
2523
}));
2624

2725
type AnthropicCreateArgs = [unknown, { signal?: AbortSignal }?];
@@ -352,9 +350,7 @@ describe('AnthropicContentGenerator', () => {
352350
};
353351

354352
const result = await generator.countTokens(request);
355-
expect(mockTokenizer.calculateTokens).toHaveBeenCalledWith(request, {
356-
textEncoding: 'cl100k_base',
357-
});
353+
expect(mockTokenizer.calculateTokens).toHaveBeenCalledWith(request);
358354
expect(result.totalTokens).toBe(50);
359355
});
360356

packages/core/src/core/anthropicContentGenerator/anthropicContentGenerator.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type MessageCreateParamsNonStreaming =
2525
Anthropic.MessageCreateParamsNonStreaming;
2626
type MessageCreateParamsStreaming = Anthropic.MessageCreateParamsStreaming;
2727
type RawMessageStreamEvent = Anthropic.RawMessageStreamEvent;
28-
import { getDefaultTokenizer } from '../../utils/request-tokenizer/index.js';
28+
import { RequestTokenEstimator } from '../../utils/request-tokenizer/index.js';
2929
import { safeJsonParse } from '../../utils/safeJsonParse.js';
3030
import { AnthropicContentConverter } from './converter.js';
3131

@@ -105,10 +105,8 @@ export class AnthropicContentGenerator implements ContentGenerator {
105105
request: CountTokensParameters,
106106
): Promise<CountTokensResponse> {
107107
try {
108-
const tokenizer = getDefaultTokenizer();
109-
const result = await tokenizer.calculateTokens(request, {
110-
textEncoding: 'cl100k_base',
111-
});
108+
const estimator = new RequestTokenEstimator();
109+
const result = await estimator.calculateTokens(request);
112110

113111
return {
114112
totalTokens: result.totalTokens,

0 commit comments

Comments
 (0)