Skip to content

Commit d92712e

Browse files
committed
Optimize: lazy load gpt-tokenizer to fix OpenCode v1.0.104+ crash
- Make gpt-tokenizer import dynamic to avoid loading 53MB package during initialization - Update estimateTokensBatch to async with lazy import - Update calculateTokensSaved and all callers to handle async tokenization - Plugin now loads instantly, only downloads tokenizer when first needed - Fixes crash in OpenCode v1.0.104+ caused by large eager imports - Bump version to 0.3.2
1 parent 50fe090 commit d92712e

File tree

4 files changed

+17
-11
lines changed

4 files changed

+17
-11
lines changed

lib/janitor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ export class Janitor {
528528
/**
529529
* Helper function to calculate token savings from tool outputs
530530
*/
531-
private calculateTokensSaved(prunedIds: string[], toolOutputs: Map<string, string>): number {
531+
private async calculateTokensSaved(prunedIds: string[], toolOutputs: Map<string, string>): Promise<number> {
532532
const outputsToTokenize: string[] = []
533533

534534
for (const prunedId of prunedIds) {
@@ -539,8 +539,8 @@ export class Janitor {
539539
}
540540

541541
if (outputsToTokenize.length > 0) {
542-
// Use batch tokenization for efficiency
543-
const tokenCounts = estimateTokensBatch(outputsToTokenize, this.logger)
542+
// Use batch tokenization for efficiency (lazy loads gpt-tokenizer)
543+
const tokenCounts = await estimateTokensBatch(outputsToTokenize, this.logger)
544544
return tokenCounts.reduce((sum, count) => sum + count, 0)
545545
}
546546

@@ -593,7 +593,7 @@ export class Janitor {
593593
if (deduplicatedIds.length === 0) return
594594

595595
// Calculate token savings
596-
const tokensSaved = this.calculateTokensSaved(deduplicatedIds, toolOutputs)
596+
const tokensSaved = await this.calculateTokensSaved(deduplicatedIds, toolOutputs)
597597
const tokensFormatted = formatTokenCount(tokensSaved)
598598

599599
const toolText = deduplicatedIds.length === 1 ? 'tool' : 'tools'
@@ -647,7 +647,7 @@ export class Janitor {
647647

648648
// Calculate token savings
649649
const allPrunedIds = [...deduplicatedIds, ...llmPrunedIds]
650-
const tokensSaved = this.calculateTokensSaved(allPrunedIds, toolOutputs)
650+
const tokensSaved = await this.calculateTokensSaved(allPrunedIds, toolOutputs)
651651
const tokensFormatted = formatTokenCount(tokensSaved)
652652

653653
let message = `🧹 DCP: Saved ~${tokensFormatted} tokens (${totalPruned} tool${totalPruned > 1 ? 's' : ''} pruned)\n`

lib/tokenizer.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
* Uses gpt-tokenizer to provide token counts for text content.
55
* Works with any LLM provider - provides accurate counts for OpenAI models
66
* and reasonable approximations for other providers.
7+
*
8+
* NOTE: gpt-tokenizer is lazily imported to avoid loading the 53MB package
9+
* during plugin initialization. The package is only loaded when tokenization
10+
* is actually needed.
711
*/
812

9-
import { encode } from 'gpt-tokenizer'
1013
import type { Logger } from './logger'
1114

1215
/**
@@ -16,11 +19,14 @@ import type { Logger } from './logger'
1619
* @param logger - Optional logger instance
1720
* @returns Array of token counts
1821
*/
19-
export function estimateTokensBatch(
22+
export async function estimateTokensBatch(
2023
texts: string[],
2124
logger?: Logger
22-
): number[] {
25+
): Promise<number[]> {
2326
try {
27+
// Lazy import - only load the 53MB gpt-tokenizer package when actually needed
28+
const { encode } = await import('gpt-tokenizer')
29+
2430
const results = texts.map(text => {
2531
const tokens = encode(text)
2632
return tokens.length

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
33
"name": "@tarquinen/opencode-dcp",
4-
"version": "0.3.1",
4+
"version": "0.3.2",
55
"type": "module",
66
"description": "OpenCode plugin that optimizes token usage by pruning obsolete tool outputs from conversation context",
77
"main": "./dist/index.js",

0 commit comments

Comments
 (0)