@allternit/gizzi-code 1.0.0 → 1.0.1
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/bin/gizzi +4 -0
- package/bin/gizzi-ink +5 -0
- package/package.json +137 -31
- package/src/Tool.ts +26 -0
- package/src/bootstrap/state.ts +165 -322
- package/src/commands.ts +209 -0
- package/src/context/QueuedMessageContext.tsx +63 -0
- package/src/context/fpsMetrics.tsx +30 -0
- package/src/context/mailbox.tsx +38 -0
- package/src/context/modalContext.tsx +58 -0
- package/src/context/notifications.tsx +240 -0
- package/src/context/overlayContext.tsx +151 -0
- package/src/context/promptOverlayContext.tsx +125 -0
- package/src/context/stats.tsx +220 -0
- package/src/context/voice.tsx +88 -0
- package/src/hooks/useCanUseTool.ts +11 -0
- package/src/hooks/useExitOnCtrlCD.ts +40 -187
- package/src/hooks/useExitOnCtrlCDWithKeybindings.ts +68 -0
- package/src/hooks/useKeybinding.ts +68 -209
- package/src/hooks/useTerminalSize.ts +31 -99
- package/src/hooks.ts +37 -0
- package/src/ink.ts +204 -0
- package/src/main.ts +7 -0
- package/src/types/command.ts +216 -0
- package/src/types/connectorText.ts +39 -0
- package/src/types/fileSuggestion.ts +15 -0
- package/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +865 -0
- package/src/types/generated/events_mono/common/v1/auth.ts +100 -0
- package/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +223 -0
- package/src/types/generated/google/protobuf/timestamp.ts +187 -0
- package/src/types/hooks.ts +319 -0
- package/src/types/ids.ts +44 -0
- package/src/types/logs.ts +331 -0
- package/src/types/merged/index.ts +5 -0
- package/src/types/merged/message.ts +552 -0
- package/src/types/message.ts +927 -186
- package/src/types/messageQueueTypes.ts +21 -0
- package/src/types/notebook.ts +72 -0
- package/src/types/permissions.ts +447 -0
- package/src/types/plugin.ts +363 -0
- package/src/types/statusLine.ts +15 -0
- package/src/types/textInputTypes.ts +387 -0
- package/src/types/tools.ts +149 -0
- package/src/types/utils.ts +20 -0
- package/src/utils/advisor.ts +12 -0
- package/src/utils/api.ts +29 -0
- package/src/utils/array.ts +7 -0
- package/src/utils/attachments.ts +60 -0
- package/src/utils/auth.ts +3 -0
- package/src/utils/claudeInChrome/chromeNativeHost.ts +15 -0
- package/src/utils/claudeInChrome/common.ts +12 -0
- package/src/utils/claudeInChrome/mcpServer.ts +15 -0
- package/src/utils/computerUse/common.ts +19 -0
- package/src/utils/computerUse/mcpServer.ts +15 -0
- package/src/utils/config.ts +35 -0
- package/src/utils/context.ts +19 -0
- package/src/utils/cwd.ts +3 -0
- package/src/utils/debug.ts +3 -0
- package/src/utils/earlyInput.ts +7 -0
- package/src/utils/effort.ts +13 -0
- package/src/utils/embeddedTools.ts +12 -0
- package/src/utils/envUtils.ts +3 -0
- package/src/utils/errors.ts +3 -0
- package/src/utils/execFileNoThrow.ts +24 -0
- package/src/utils/feature-flags.ts +112 -0
- package/src/utils/file.ts +3 -0
- package/src/utils/fileHistory.ts +17 -0
- package/src/utils/fingerprint.ts +7 -0
- package/src/utils/format.ts +75 -305
- package/src/utils/frontmatterParser.ts +33 -0
- package/src/utils/fsOperations.ts +31 -0
- package/src/utils/fullscreen.ts +40 -350
- package/src/utils/git.ts +15 -0
- package/src/utils/imageResizer.ts +30 -0
- package/src/utils/lazySchema.ts +9 -0
- package/src/utils/log.ts +3 -0
- package/src/utils/markdownConfigLoader.ts +12 -0
- package/src/utils/messages.ts +13 -0
- package/src/utils/migration.ts +137 -0
- package/src/utils/model/providers.ts +15 -0
- package/src/utils/path.ts +3 -0
- package/src/utils/permissions/PermissionResult.ts +14 -0
- package/src/utils/permissions/autoModeState.ts +12 -0
- package/src/utils/permissions/filesystem.ts +12 -0
- package/src/utils/plugins/loadPluginOutputStyles.ts +12 -0
- package/src/utils/plugins/schemas.ts +25 -0
- package/src/utils/process.ts +16 -0
- package/src/utils/sandbox/sandbox-adapter.ts +19 -0
- package/src/utils/sessionStorage.ts +238 -472
- package/src/utils/settings/constants.ts +10 -0
- package/src/utils/settings/settings.ts +19 -0
- package/src/utils/settings/types.ts +18 -0
- package/src/utils/shell/shellToolUtils.ts +9 -0
- package/src/utils/sinks.ts +11 -0
- package/src/utils/sleep.ts +7 -0
- package/src/utils/sliceAnsi.ts +7 -0
- package/src/utils/slowOperations.ts +3 -0
- package/src/utils/startupProfiler.ts +11 -0
- package/src/utils/stringUtils.ts +106 -0
- package/src/utils/systemPromptType.ts +9 -0
- package/src/utils/teleport/api.ts +15 -0
- package/src/utils/textHighlighting.ts +16 -0
- package/src/utils/theme.ts +17 -0
- package/src/utils/thinking.ts +58 -0
- package/src/utils/tokens.ts +11 -0
- package/src/utils/toolResultStorage.ts +17 -0
- package/src/utils/worktreeModeEnabled.ts +7 -0
- package/WORKSPACE_INTEGRATION.md +0 -290
- package/chat-sessions/sessions-index.json +0 -98
- package/package.json.original +0 -31
- package/package.json.publish +0 -47
- package/src/bootstrap/state.d.ts +0 -169
- package/src/bootstrap/state.js +0 -261
- package/src/context/pack-builder.d.ts +0 -24
- package/src/context/pack-builder.js +0 -281
- package/src/hooks/useExitOnCtrlCD.d.ts +0 -86
- package/src/hooks/useExitOnCtrlCD.js +0 -130
- package/src/hooks/useKeybinding.d.ts +0 -89
- package/src/hooks/useKeybinding.js +0 -163
- package/src/hooks/useTerminalSize.d.ts +0 -41
- package/src/hooks/useTerminalSize.js +0 -90
- package/src/index.d.ts +0 -23
- package/src/index.js +0 -24
- package/src/runtime/brand/brand.d.ts +0 -488
- package/src/runtime/brand/brand.js +0 -464
- package/src/runtime/brand/brand.ts +0 -667
- package/src/runtime/services/tokenEstimation.d.ts +0 -187
- package/src/runtime/services/tokenEstimation.js +0 -423
- package/src/runtime/services/tokenEstimation.ts +0 -547
- package/src/runtime/tools/Tool.d.ts +0 -239
- package/src/runtime/tools/Tool.js +0 -285
- package/src/runtime/tools/Tool.ts +0 -524
- package/src/scheduler/TaskScheduler.d.ts +0 -98
- package/src/scheduler/TaskScheduler.js +0 -201
- package/src/scheduler/TaskScheduler.ts +0 -259
- package/src/state/AppStateStore.d.ts +0 -347
- package/src/state/AppStateStore.js +0 -439
- package/src/state/AppStateStore.ts +0 -658
- package/src/state/WorkspaceStateStore.d.ts +0 -43
- package/src/state/WorkspaceStateStore.js +0 -224
- package/src/state/WorkspaceStateStore.ts +0 -297
- package/src/types/message.d.ts +0 -190
- package/src/types/message.js +0 -77
- package/src/utils/format.d.ts +0 -126
- package/src/utils/format.js +0 -230
- package/src/utils/fullscreen.d.ts +0 -161
- package/src/utils/fullscreen.js +0 -277
- package/src/utils/sessionStorage.d.ts +0 -210
- package/src/utils/sessionStorage.js +0 -435
- package/src/watcher/WorkspaceWatcher.d.ts +0 -70
- package/src/watcher/WorkspaceWatcher.js +0 -191
- package/src/watcher/WorkspaceWatcher.ts +0 -251
- package/src/workspace/loader.d.ts +0 -30
- package/src/workspace/loader.js +0 -117
- package/src/workspace/types.d.ts +0 -91
- package/src/workspace/types.js +0 -7
- package/threads/thread_1775361175022.json +0 -9
- package/tsconfig.json +0 -14
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Token estimation utilities for LLM interactions
|
|
3
|
-
* @module runtime/services/tokenEstimation
|
|
4
|
-
*
|
|
5
|
-
* Provides token counting and estimation functions for various LLM models.
|
|
6
|
-
* Supports both accurate encoding (when tiktoken is available) and
|
|
7
|
-
* rough estimation based on character counts.
|
|
8
|
-
*/
|
|
9
|
-
import type { Message } from '../../types/message.js';
|
|
10
|
-
/**
|
|
11
|
-
* Supported LLM models for token estimation
|
|
12
|
-
* @typedef {'gpt-4' | 'gpt-4o' | 'gpt-4-turbo' | 'gpt-3.5-turbo' | 'claude-3-opus' | 'claude-3-sonnet' | 'claude-3-haiku' | 'claude-2' | 'gemini-pro' | 'gemini-ultra' | 'default'} SupportedModel
|
|
13
|
-
*/
|
|
14
|
-
export type SupportedModel = 'gpt-4' | 'gpt-4o' | 'gpt-4-turbo' | 'gpt-3.5-turbo' | 'claude-3-opus' | 'claude-3-sonnet' | 'claude-3-haiku' | 'claude-2' | 'gemini-pro' | 'gemini-ultra' | 'default';
|
|
15
|
-
/**
|
|
16
|
-
* Token estimation configuration options
|
|
17
|
-
* @interface TokenEstimationOptions
|
|
18
|
-
*/
|
|
19
|
-
export interface TokenEstimationOptions {
|
|
20
|
-
/** Target model for estimation */
|
|
21
|
-
readonly model?: SupportedModel;
|
|
22
|
-
/** Whether to include formatting overhead in estimate */
|
|
23
|
-
readonly includeFormatting?: boolean;
|
|
24
|
-
/** Custom tokens per character ratio for rough estimation */
|
|
25
|
-
readonly customRatio?: number;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Token estimation result with metadata
|
|
29
|
-
* @interface TokenEstimationResult
|
|
30
|
-
*/
|
|
31
|
-
export interface TokenEstimationResult {
|
|
32
|
-
/** Estimated token count */
|
|
33
|
-
readonly tokens: number;
|
|
34
|
-
/** Method used for estimation */
|
|
35
|
-
readonly method: 'precise' | 'rough';
|
|
36
|
-
/** Model used for estimation */
|
|
37
|
-
readonly model: SupportedModel;
|
|
38
|
-
/** Confidence level (0-1) based on estimation method */
|
|
39
|
-
readonly confidence: number;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Model-specific token estimation ratios (characters per token)
|
|
43
|
-
* These are approximate averages and vary by language/content
|
|
44
|
-
* @constant {Readonly<Record<SupportedModel, number>>}
|
|
45
|
-
*/
|
|
46
|
-
export declare const MODEL_TOKEN_RATIOS: Readonly<Record<SupportedModel, number>>;
|
|
47
|
-
/**
|
|
48
|
-
* Message format overhead in tokens (role markers, formatting, etc.)
|
|
49
|
-
* @constant {number}
|
|
50
|
-
*/
|
|
51
|
-
export declare const MESSAGE_OVERHEAD_TOKENS = 4;
|
|
52
|
-
/**
|
|
53
|
-
* Base overhead for a conversation (system prompts, etc.)
|
|
54
|
-
* @constant {number}
|
|
55
|
-
*/
|
|
56
|
-
export declare const CONVERSATION_BASE_OVERHEAD = 3;
|
|
57
|
-
/**
|
|
58
|
-
* Estimate tokens in a single text string
|
|
59
|
-
*
|
|
60
|
-
* @param {string} text - Text to estimate tokens for
|
|
61
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
62
|
-
* @returns {TokenEstimationResult} Token estimation with metadata
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```typescript
|
|
66
|
-
* const result = estimateTokens('Hello, world!', { model: 'gpt-4' });
|
|
67
|
-
* console.log(result.tokens); // ~4 tokens
|
|
68
|
-
* ```
|
|
69
|
-
*/
|
|
70
|
-
export declare function estimateTokens(text: string, options?: TokenEstimationOptions): TokenEstimationResult;
|
|
71
|
-
/**
|
|
72
|
-
* Async version of estimateTokens that attempts to use tiktoken for precision
|
|
73
|
-
*
|
|
74
|
-
* @param {string} text - Text to estimate tokens for
|
|
75
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
76
|
-
* @returns {Promise<TokenEstimationResult>} Token estimation with metadata
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* ```typescript
|
|
80
|
-
* const result = await estimateTokensAsync('Hello, world!', { model: 'gpt-4' });
|
|
81
|
-
* console.log(result.method); // 'precise' if tiktoken available
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
export declare function estimateTokensAsync(text: string, options?: TokenEstimationOptions): Promise<TokenEstimationResult>;
|
|
85
|
-
/**
|
|
86
|
-
* Estimate tokens for an array of messages
|
|
87
|
-
*
|
|
88
|
-
* @param {readonly Message[]} messages - Messages to estimate tokens for
|
|
89
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
90
|
-
* @returns {TokenEstimationResult} Total token estimation with metadata
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```typescript
|
|
94
|
-
* const messages = [
|
|
95
|
-
* { role: 'system', content: 'You are a helpful assistant.' },
|
|
96
|
-
* { role: 'user', content: 'Hello!' }
|
|
97
|
-
* ];
|
|
98
|
-
* const result = estimateTokensForMessages(messages);
|
|
99
|
-
* console.log(result.tokens); // Total estimated tokens
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
export declare function estimateTokensForMessages(messages: readonly Message[], options?: TokenEstimationOptions): TokenEstimationResult;
|
|
103
|
-
/**
|
|
104
|
-
* Async version of estimateTokensForMessages with tiktoken support
|
|
105
|
-
*
|
|
106
|
-
* @param {readonly Message[]} messages - Messages to estimate tokens for
|
|
107
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
108
|
-
* @returns {Promise<TokenEstimationResult>} Total token estimation with metadata
|
|
109
|
-
*/
|
|
110
|
-
export declare function estimateTokensForMessagesAsync(messages: readonly Message[], options?: TokenEstimationOptions): Promise<TokenEstimationResult>;
|
|
111
|
-
/**
|
|
112
|
-
* Rough token count estimation without any dependencies
|
|
113
|
-
* Uses a simple characters-per-token heuristic
|
|
114
|
-
*
|
|
115
|
-
* @param {string | readonly Message[]} input - Text or messages to estimate
|
|
116
|
-
* @param {SupportedModel} model - Model for estimation ratios
|
|
117
|
-
* @returns {number} Estimated token count
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* ```typescript
|
|
121
|
-
* // Estimate text
|
|
122
|
-
* const textTokens = roughTokenCountEstimation('Hello, world!');
|
|
123
|
-
*
|
|
124
|
-
* // Estimate messages
|
|
125
|
-
* const messageTokens = roughTokenCountEstimation([
|
|
126
|
-
* { role: 'user', content: 'Hello!' }
|
|
127
|
-
* ]);
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
|
-
export declare function roughTokenCountEstimation(input: string | readonly Message[], model?: SupportedModel): number;
|
|
131
|
-
/**
|
|
132
|
-
* Check if text would exceed token limit
|
|
133
|
-
*
|
|
134
|
-
* @param {string} text - Text to check
|
|
135
|
-
* @param {number} limit - Token limit
|
|
136
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
137
|
-
* @returns {{ withinLimit: true } | { withinLimit: false; exceededBy: number }} Limit check result
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```typescript
|
|
141
|
-
* const result = checkTokenLimit('Long text...', 100);
|
|
142
|
-
* if (!result.withinLimit) {
|
|
143
|
-
* console.log(`Exceeded by ${result.exceededBy} tokens`);
|
|
144
|
-
* }
|
|
145
|
-
* ```
|
|
146
|
-
*/
|
|
147
|
-
export declare function checkTokenLimit(text: string, limit: number, options?: TokenEstimationOptions): {
|
|
148
|
-
withinLimit: true;
|
|
149
|
-
} | {
|
|
150
|
-
withinLimit: false;
|
|
151
|
-
exceededBy: number;
|
|
152
|
-
};
|
|
153
|
-
/**
|
|
154
|
-
* Truncate text to fit within token limit
|
|
155
|
-
*
|
|
156
|
-
* @param {string} text - Text to truncate
|
|
157
|
-
* @param {number} maxTokens - Maximum token count
|
|
158
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
159
|
-
* @returns {string} Truncated text
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* ```typescript
|
|
163
|
-
* const truncated = truncateToTokenLimit(longText, 100);
|
|
164
|
-
* ```
|
|
165
|
-
*/
|
|
166
|
-
export declare function truncateToTokenLimit(text: string, maxTokens: number, options?: TokenEstimationOptions): string;
|
|
167
|
-
/**
|
|
168
|
-
* Get model-specific context window size
|
|
169
|
-
*
|
|
170
|
-
* @param {SupportedModel} model - Model name
|
|
171
|
-
* @returns {number} Context window size in tokens
|
|
172
|
-
*/
|
|
173
|
-
export declare function getModelContextWindow(model: SupportedModel): number;
|
|
174
|
-
declare const _default: {
|
|
175
|
-
estimateTokens: typeof estimateTokens;
|
|
176
|
-
estimateTokensAsync: typeof estimateTokensAsync;
|
|
177
|
-
estimateTokensForMessages: typeof estimateTokensForMessages;
|
|
178
|
-
estimateTokensForMessagesAsync: typeof estimateTokensForMessagesAsync;
|
|
179
|
-
roughTokenCountEstimation: typeof roughTokenCountEstimation;
|
|
180
|
-
checkTokenLimit: typeof checkTokenLimit;
|
|
181
|
-
truncateToTokenLimit: typeof truncateToTokenLimit;
|
|
182
|
-
getModelContextWindow: typeof getModelContextWindow;
|
|
183
|
-
MODEL_TOKEN_RATIOS: Readonly<Record<SupportedModel, number>>;
|
|
184
|
-
MESSAGE_OVERHEAD_TOKENS: number;
|
|
185
|
-
CONVERSATION_BASE_OVERHEAD: number;
|
|
186
|
-
};
|
|
187
|
-
export default _default;
|
|
@@ -1,423 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Token estimation utilities for LLM interactions
|
|
3
|
-
* @module runtime/services/tokenEstimation
|
|
4
|
-
*
|
|
5
|
-
* Provides token counting and estimation functions for various LLM models.
|
|
6
|
-
* Supports both accurate encoding (when tiktoken is available) and
|
|
7
|
-
* rough estimation based on character counts.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Model-specific token estimation ratios (characters per token)
|
|
11
|
-
* These are approximate averages and vary by language/content
|
|
12
|
-
* @constant {Readonly<Record<SupportedModel, number>>}
|
|
13
|
-
*/
|
|
14
|
-
export const MODEL_TOKEN_RATIOS = {
|
|
15
|
-
'gpt-4': 3.5,
|
|
16
|
-
'gpt-4o': 3.5,
|
|
17
|
-
'gpt-4-turbo': 3.5,
|
|
18
|
-
'gpt-3.5-turbo': 3.5,
|
|
19
|
-
'claude-3-opus': 3.25,
|
|
20
|
-
'claude-3-sonnet': 3.25,
|
|
21
|
-
'claude-3-haiku': 3.25,
|
|
22
|
-
'claude-2': 3.25,
|
|
23
|
-
'gemini-pro': 3.5,
|
|
24
|
-
'gemini-ultra': 3.5,
|
|
25
|
-
default: 3.5,
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Message format overhead in tokens (role markers, formatting, etc.)
|
|
29
|
-
* @constant {number}
|
|
30
|
-
*/
|
|
31
|
-
export const MESSAGE_OVERHEAD_TOKENS = 4;
|
|
32
|
-
/**
|
|
33
|
-
* Base overhead for a conversation (system prompts, etc.)
|
|
34
|
-
* @constant {number}
|
|
35
|
-
*/
|
|
36
|
-
export const CONVERSATION_BASE_OVERHEAD = 3;
|
|
37
|
-
/**
|
|
38
|
-
* Cache for tiktoken encoder to avoid re-initialization
|
|
39
|
-
* @type {unknown | null}
|
|
40
|
-
*/
|
|
41
|
-
let tiktokenEncoder = null;
|
|
42
|
-
/**
|
|
43
|
-
* Try to load tiktoken for precise token counting
|
|
44
|
-
* @returns {Promise<unknown | null>} Tiktoken encoder or null if not available
|
|
45
|
-
*/
|
|
46
|
-
async function getTiktokenEncoder() {
|
|
47
|
-
if (tiktokenEncoder) {
|
|
48
|
-
return tiktokenEncoder;
|
|
49
|
-
}
|
|
50
|
-
try {
|
|
51
|
-
// Dynamic import to avoid hard dependency
|
|
52
|
-
const tiktoken = await import('tiktoken');
|
|
53
|
-
// Use cl100k_base encoding (used by GPT-4 and GPT-3.5-turbo)
|
|
54
|
-
tiktokenEncoder = tiktoken.get_encoding('cl100k_base');
|
|
55
|
-
return tiktokenEncoder;
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// tiktoken not available, fall back to rough estimation
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Estimate tokens in a single text string
|
|
64
|
-
*
|
|
65
|
-
* @param {string} text - Text to estimate tokens for
|
|
66
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
67
|
-
* @returns {TokenEstimationResult} Token estimation with metadata
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```typescript
|
|
71
|
-
* const result = estimateTokens('Hello, world!', { model: 'gpt-4' });
|
|
72
|
-
* console.log(result.tokens); // ~4 tokens
|
|
73
|
-
* ```
|
|
74
|
-
*/
|
|
75
|
-
export function estimateTokens(text, options = {}) {
|
|
76
|
-
const { model = 'default', customRatio } = options;
|
|
77
|
-
// Handle empty text
|
|
78
|
-
if (!text || text.length === 0) {
|
|
79
|
-
return {
|
|
80
|
-
tokens: 0,
|
|
81
|
-
method: 'precise',
|
|
82
|
-
model,
|
|
83
|
-
confidence: 1,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
// Try synchronous tiktoken if available (pre-loaded)
|
|
87
|
-
if (tiktokenEncoder && typeof tiktokenEncoder.encode === 'function') {
|
|
88
|
-
try {
|
|
89
|
-
const tokens = tiktokenEncoder.encode(text);
|
|
90
|
-
return {
|
|
91
|
-
tokens: tokens.length,
|
|
92
|
-
method: 'precise',
|
|
93
|
-
model,
|
|
94
|
-
confidence: 0.95,
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
// Fall through to rough estimation
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Rough estimation based on character count
|
|
102
|
-
const ratio = customRatio ?? MODEL_TOKEN_RATIOS[model] ?? MODEL_TOKEN_RATIOS.default;
|
|
103
|
-
const estimatedTokens = Math.ceil(text.length / ratio);
|
|
104
|
-
return {
|
|
105
|
-
tokens: estimatedTokens,
|
|
106
|
-
method: 'rough',
|
|
107
|
-
model,
|
|
108
|
-
confidence: 0.8,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Async version of estimateTokens that attempts to use tiktoken for precision
|
|
113
|
-
*
|
|
114
|
-
* @param {string} text - Text to estimate tokens for
|
|
115
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
116
|
-
* @returns {Promise<TokenEstimationResult>} Token estimation with metadata
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```typescript
|
|
120
|
-
* const result = await estimateTokensAsync('Hello, world!', { model: 'gpt-4' });
|
|
121
|
-
* console.log(result.method); // 'precise' if tiktoken available
|
|
122
|
-
* ```
|
|
123
|
-
*/
|
|
124
|
-
export async function estimateTokensAsync(text, options = {}) {
|
|
125
|
-
const { model = 'default', customRatio } = options;
|
|
126
|
-
// Handle empty text
|
|
127
|
-
if (!text || text.length === 0) {
|
|
128
|
-
return {
|
|
129
|
-
tokens: 0,
|
|
130
|
-
method: 'precise',
|
|
131
|
-
model,
|
|
132
|
-
confidence: 1,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
// Try to use tiktoken for precise counting
|
|
136
|
-
const encoder = await getTiktokenEncoder();
|
|
137
|
-
if (encoder && typeof encoder.encode === 'function') {
|
|
138
|
-
try {
|
|
139
|
-
const tokens = encoder.encode(text);
|
|
140
|
-
return {
|
|
141
|
-
tokens: tokens.length,
|
|
142
|
-
method: 'precise',
|
|
143
|
-
model,
|
|
144
|
-
confidence: 0.95,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
catch {
|
|
148
|
-
// Fall through to rough estimation
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
// Fall back to rough estimation
|
|
152
|
-
return estimateTokens(text, options);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Estimate tokens for an array of messages
|
|
156
|
-
*
|
|
157
|
-
* @param {readonly Message[]} messages - Messages to estimate tokens for
|
|
158
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
159
|
-
* @returns {TokenEstimationResult} Total token estimation with metadata
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* ```typescript
|
|
163
|
-
* const messages = [
|
|
164
|
-
* { role: 'system', content: 'You are a helpful assistant.' },
|
|
165
|
-
* { role: 'user', content: 'Hello!' }
|
|
166
|
-
* ];
|
|
167
|
-
* const result = estimateTokensForMessages(messages);
|
|
168
|
-
* console.log(result.tokens); // Total estimated tokens
|
|
169
|
-
* ```
|
|
170
|
-
*/
|
|
171
|
-
export function estimateTokensForMessages(messages, options = {}) {
|
|
172
|
-
const { model = 'default', includeFormatting = true } = options;
|
|
173
|
-
if (!messages || messages.length === 0) {
|
|
174
|
-
return {
|
|
175
|
-
tokens: 0,
|
|
176
|
-
method: 'precise',
|
|
177
|
-
model,
|
|
178
|
-
confidence: 1,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
let totalTokens = 0;
|
|
182
|
-
let preciseCount = 0;
|
|
183
|
-
let roughCount = 0;
|
|
184
|
-
for (const message of messages) {
|
|
185
|
-
// Estimate content tokens
|
|
186
|
-
const contentEstimate = estimateTokens(message.content, { model });
|
|
187
|
-
totalTokens += contentEstimate.tokens;
|
|
188
|
-
if (contentEstimate.method === 'precise') {
|
|
189
|
-
preciseCount++;
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
roughCount++;
|
|
193
|
-
}
|
|
194
|
-
// Add per-message overhead (formatting, role markers, etc.)
|
|
195
|
-
if (includeFormatting) {
|
|
196
|
-
totalTokens += MESSAGE_OVERHEAD_TOKENS;
|
|
197
|
-
// Add tokens for role name
|
|
198
|
-
totalTokens += estimateTokens(message.role, { model }).tokens;
|
|
199
|
-
}
|
|
200
|
-
// Add tokens for attachments if present
|
|
201
|
-
if (message.attachments && message.attachments.length > 0) {
|
|
202
|
-
for (const attachment of message.attachments) {
|
|
203
|
-
// Estimate based on attachment metadata
|
|
204
|
-
const attachmentText = `${attachment.name} ${attachment.mimeType} ${attachment.caption ?? ''}`;
|
|
205
|
-
totalTokens += estimateTokens(attachmentText, { model }).tokens;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
// Add conversation base overhead
|
|
210
|
-
if (includeFormatting) {
|
|
211
|
-
totalTokens += CONVERSATION_BASE_OVERHEAD;
|
|
212
|
-
}
|
|
213
|
-
return {
|
|
214
|
-
tokens: totalTokens,
|
|
215
|
-
method: roughCount > 0 ? 'rough' : 'precise',
|
|
216
|
-
model,
|
|
217
|
-
confidence: preciseCount > roughCount ? 0.9 : 0.75,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Async version of estimateTokensForMessages with tiktoken support
|
|
222
|
-
*
|
|
223
|
-
* @param {readonly Message[]} messages - Messages to estimate tokens for
|
|
224
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
225
|
-
* @returns {Promise<TokenEstimationResult>} Total token estimation with metadata
|
|
226
|
-
*/
|
|
227
|
-
export async function estimateTokensForMessagesAsync(messages, options = {}) {
|
|
228
|
-
const { model = 'default', includeFormatting = true } = options;
|
|
229
|
-
if (!messages || messages.length === 0) {
|
|
230
|
-
return {
|
|
231
|
-
tokens: 0,
|
|
232
|
-
method: 'precise',
|
|
233
|
-
model,
|
|
234
|
-
confidence: 1,
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
// Try to initialize tiktoken
|
|
238
|
-
const encoder = await getTiktokenEncoder();
|
|
239
|
-
const usePrecise = encoder !== null;
|
|
240
|
-
let totalTokens = 0;
|
|
241
|
-
for (const message of messages) {
|
|
242
|
-
// Use precise or rough estimation based on availability
|
|
243
|
-
if (usePrecise) {
|
|
244
|
-
const contentResult = await estimateTokensAsync(message.content, { model });
|
|
245
|
-
totalTokens += contentResult.tokens;
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
const contentResult = estimateTokens(message.content, { model });
|
|
249
|
-
totalTokens += contentResult.tokens;
|
|
250
|
-
}
|
|
251
|
-
// Add per-message overhead
|
|
252
|
-
if (includeFormatting) {
|
|
253
|
-
totalTokens += MESSAGE_OVERHEAD_TOKENS;
|
|
254
|
-
const roleResult = usePrecise
|
|
255
|
-
? await estimateTokensAsync(message.role, { model })
|
|
256
|
-
: estimateTokens(message.role, { model });
|
|
257
|
-
totalTokens += roleResult.tokens;
|
|
258
|
-
}
|
|
259
|
-
// Add attachment estimates
|
|
260
|
-
if (message.attachments && message.attachments.length > 0) {
|
|
261
|
-
for (const attachment of message.attachments) {
|
|
262
|
-
const attachmentText = `${attachment.name} ${attachment.mimeType} ${attachment.caption ?? ''}`;
|
|
263
|
-
const attachResult = usePrecise
|
|
264
|
-
? await estimateTokensAsync(attachmentText, { model })
|
|
265
|
-
: estimateTokens(attachmentText, { model });
|
|
266
|
-
totalTokens += attachResult.tokens;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
if (includeFormatting) {
|
|
271
|
-
totalTokens += CONVERSATION_BASE_OVERHEAD;
|
|
272
|
-
}
|
|
273
|
-
return {
|
|
274
|
-
tokens: totalTokens,
|
|
275
|
-
method: usePrecise ? 'precise' : 'rough',
|
|
276
|
-
model,
|
|
277
|
-
confidence: usePrecise ? 0.95 : 0.75,
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Rough token count estimation without any dependencies
|
|
282
|
-
* Uses a simple characters-per-token heuristic
|
|
283
|
-
*
|
|
284
|
-
* @param {string | readonly Message[]} input - Text or messages to estimate
|
|
285
|
-
* @param {SupportedModel} model - Model for estimation ratios
|
|
286
|
-
* @returns {number} Estimated token count
|
|
287
|
-
*
|
|
288
|
-
* @example
|
|
289
|
-
* ```typescript
|
|
290
|
-
* // Estimate text
|
|
291
|
-
* const textTokens = roughTokenCountEstimation('Hello, world!');
|
|
292
|
-
*
|
|
293
|
-
* // Estimate messages
|
|
294
|
-
* const messageTokens = roughTokenCountEstimation([
|
|
295
|
-
* { role: 'user', content: 'Hello!' }
|
|
296
|
-
* ]);
|
|
297
|
-
* ```
|
|
298
|
-
*/
|
|
299
|
-
export function roughTokenCountEstimation(input, model = 'default') {
|
|
300
|
-
const ratio = MODEL_TOKEN_RATIOS[model] ?? MODEL_TOKEN_RATIOS.default;
|
|
301
|
-
// Handle string input
|
|
302
|
-
if (typeof input === 'string') {
|
|
303
|
-
if (!input)
|
|
304
|
-
return 0;
|
|
305
|
-
return Math.ceil(input.length / ratio);
|
|
306
|
-
}
|
|
307
|
-
// Handle message array input
|
|
308
|
-
if (!Array.isArray(input) || input.length === 0) {
|
|
309
|
-
return 0;
|
|
310
|
-
}
|
|
311
|
-
let totalChars = 0;
|
|
312
|
-
for (const message of input) {
|
|
313
|
-
// Add content length
|
|
314
|
-
if (message.content) {
|
|
315
|
-
totalChars += message.content.length;
|
|
316
|
-
}
|
|
317
|
-
// Add role length
|
|
318
|
-
if (message.role) {
|
|
319
|
-
totalChars += message.role.length;
|
|
320
|
-
}
|
|
321
|
-
// Add overhead
|
|
322
|
-
totalChars += MESSAGE_OVERHEAD_TOKENS * ratio;
|
|
323
|
-
// Add attachment metadata
|
|
324
|
-
if (message.attachments) {
|
|
325
|
-
for (const attachment of message.attachments) {
|
|
326
|
-
totalChars += (attachment.name?.length ?? 0);
|
|
327
|
-
totalChars += (attachment.mimeType?.length ?? 0);
|
|
328
|
-
totalChars += (attachment.caption?.length ?? 0);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
// Add conversation overhead
|
|
333
|
-
totalChars += CONVERSATION_BASE_OVERHEAD * ratio;
|
|
334
|
-
return Math.ceil(totalChars / ratio);
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Check if text would exceed token limit
|
|
338
|
-
*
|
|
339
|
-
* @param {string} text - Text to check
|
|
340
|
-
* @param {number} limit - Token limit
|
|
341
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
342
|
-
* @returns {{ withinLimit: true } | { withinLimit: false; exceededBy: number }} Limit check result
|
|
343
|
-
*
|
|
344
|
-
* @example
|
|
345
|
-
* ```typescript
|
|
346
|
-
* const result = checkTokenLimit('Long text...', 100);
|
|
347
|
-
* if (!result.withinLimit) {
|
|
348
|
-
* console.log(`Exceeded by ${result.exceededBy} tokens`);
|
|
349
|
-
* }
|
|
350
|
-
* ```
|
|
351
|
-
*/
|
|
352
|
-
export function checkTokenLimit(text, limit, options = {}) {
|
|
353
|
-
const estimate = estimateTokens(text, options);
|
|
354
|
-
if (estimate.tokens <= limit) {
|
|
355
|
-
return { withinLimit: true };
|
|
356
|
-
}
|
|
357
|
-
return {
|
|
358
|
-
withinLimit: false,
|
|
359
|
-
exceededBy: estimate.tokens - limit,
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Truncate text to fit within token limit
|
|
364
|
-
*
|
|
365
|
-
* @param {string} text - Text to truncate
|
|
366
|
-
* @param {number} maxTokens - Maximum token count
|
|
367
|
-
* @param {TokenEstimationOptions} options - Estimation options
|
|
368
|
-
* @returns {string} Truncated text
|
|
369
|
-
*
|
|
370
|
-
* @example
|
|
371
|
-
* ```typescript
|
|
372
|
-
* const truncated = truncateToTokenLimit(longText, 100);
|
|
373
|
-
* ```
|
|
374
|
-
*/
|
|
375
|
-
export function truncateToTokenLimit(text, maxTokens, options = {}) {
|
|
376
|
-
const estimate = estimateTokens(text, options);
|
|
377
|
-
if (estimate.tokens <= maxTokens) {
|
|
378
|
-
return text;
|
|
379
|
-
}
|
|
380
|
-
const ratio = options.customRatio ??
|
|
381
|
-
MODEL_TOKEN_RATIOS[options.model ?? 'default'] ??
|
|
382
|
-
MODEL_TOKEN_RATIOS.default;
|
|
383
|
-
// Calculate approximate character limit
|
|
384
|
-
const targetChars = Math.floor(maxTokens * ratio);
|
|
385
|
-
// Simple truncation (could be improved to respect word boundaries)
|
|
386
|
-
return text.substring(0, targetChars) + '...';
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Get model-specific context window size
|
|
390
|
-
*
|
|
391
|
-
* @param {SupportedModel} model - Model name
|
|
392
|
-
* @returns {number} Context window size in tokens
|
|
393
|
-
*/
|
|
394
|
-
export function getModelContextWindow(model) {
|
|
395
|
-
const contextWindows = {
|
|
396
|
-
'gpt-4': 8192,
|
|
397
|
-
'gpt-4o': 128000,
|
|
398
|
-
'gpt-4-turbo': 128000,
|
|
399
|
-
'gpt-3.5-turbo': 16385,
|
|
400
|
-
'claude-3-opus': 200000,
|
|
401
|
-
'claude-3-sonnet': 200000,
|
|
402
|
-
'claude-3-haiku': 200000,
|
|
403
|
-
'claude-2': 100000,
|
|
404
|
-
'gemini-pro': 1000000,
|
|
405
|
-
'gemini-ultra': 1000000,
|
|
406
|
-
default: 4096,
|
|
407
|
-
};
|
|
408
|
-
return contextWindows[model] ?? contextWindows.default;
|
|
409
|
-
}
|
|
410
|
-
// Default export
|
|
411
|
-
export default {
|
|
412
|
-
estimateTokens,
|
|
413
|
-
estimateTokensAsync,
|
|
414
|
-
estimateTokensForMessages,
|
|
415
|
-
estimateTokensForMessagesAsync,
|
|
416
|
-
roughTokenCountEstimation,
|
|
417
|
-
checkTokenLimit,
|
|
418
|
-
truncateToTokenLimit,
|
|
419
|
-
getModelContextWindow,
|
|
420
|
-
MODEL_TOKEN_RATIOS,
|
|
421
|
-
MESSAGE_OVERHEAD_TOKENS,
|
|
422
|
-
CONVERSATION_BASE_OVERHEAD,
|
|
423
|
-
};
|