Skip to content

Commit bd751c0

Browse files
committed
Move token counts into the prompt field footer and header
- change the flow of information: "[x] 5K in selected files, 3K in prompt, totalling 8K tokens" - in `packages/ui/src/components/editor/prompt/TokenCounts/TokenCounts.tsx`, a line above, place heading 'Context window' - restore showing token count in `packages/ui/src/components/editor/common/prompts/PromptField/PromptField.tsx` [Commit] - in prompt field, the 'tokens in context' should be clickable, trigger on_toggle_include_selected_files - when off, should apply line-through text decoration. - [Fragment] should not be optional - prompt field should have renamed prop [Fragment] to selected files token count - prompt field should accept prop 'prompt_token_count' and display it to the left of 'clear button', when larger than 1K - 'prompt token count' should be rendered together with 'clear' so that it properly wraps text. Name the wrapping container 'top right' - do [Fragment] - remove 'token coutns' ui component - 'prompt token count' should not include tokens of eventual edit format instructions ├── apps │ └── editor │ └── src │ └── views │ └── prompt │ ├── backend │ │ └── prompt-view-provider.ts │ └── frontend │ ├── Main │ │ └── MainView │ │ └── MainView.tsx │ └── i18n │ └── translations │ ├── main.ts │ └── prompt-field.ts └── packages └── ui └── src └── components └── editor ├── common │ └── prompts │ └── PromptField │ ├── PromptField.module.scss │ ├── PromptField.stories.tsx │ ├── PromptField.tsx │ ├── components │ │ ├── Tooltip.module.scss │ │ ├── Tooltip.tsx │ │ └── index.ts │ ├── hooks │ │ ├── use-drag-drop.ts │ │ ├── use-dropdown.ts │ │ ├── use-ghost-text.ts │ │ ├── use-handlers │ │ │ ├── handle-copy.ts │ │ │ ├── handle-cut.ts │ │ │ ├── handle-input-change.ts │ │ │ ├── handle-input-click.ts │ │ │ ├── handle-key-down.ts │ │ │ ├── handle-paste.ts │ │ │ ├── handle-submit.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── use-handlers.ts │ │ │ └── utils.ts │ │ └── use-keyboard-shortcuts.ts │ └── index.ts └── prompt └── TokenCounts ├── TokenCounts.module.scss ├── TokenCounts.tsx └── index.ts
1 parent 11d4a7f commit bd751c0

9 files changed

Lines changed: 299 additions & 189 deletions

File tree

‎apps/editor/src/views/prompt/frontend/Main/MainView/MainView.tsx‎

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import styles from './MainView.module.scss'
22
import { Configurations as UiConfigurations } from '@ui/components/editor/prompt/Configurations'
3-
import { TokenCounts as UiTokenCounts } from '@ui/components/editor/prompt/TokenCounts'
43
import { PromptField as UiPromptField } from '@ui/components/editor/common/prompts/PromptField'
54
import { Separator as UiSeparator } from '@ui/components/editor/prompt/Separator'
65
import { WebConfiguration } from '@shared/types/web-configuration'
@@ -18,13 +17,6 @@ import { SelectionState } from '@/views/prompt/types/messages'
1817
import { use_translation } from '../../i18n/use-translation'
1918
import { Icon } from '@ui/components/editor/common/Icon'
2019
import { CHATBOTS } from '@shared/constants/chatbots'
21-
import { display_token_count } from '@/utils/display-token-count'
22-
import {
23-
EDIT_FORMAT_INSTRUCTIONS_WHOLE,
24-
EDIT_FORMAT_INSTRUCTIONS_TRUNCATED,
25-
EDIT_FORMAT_INSTRUCTIONS_DIFF,
26-
EDIT_FORMAT_INSTRUCTIONS_SEARCH_REPLACE
27-
} from '@/constants/edit-format-instructions'
2820

2921
type Props = {
3022
scroll_reset_key: number
@@ -243,24 +235,6 @@ export const MainView: React.FC<Props> = (props) => {
243235
}
244236
})
245237

246-
const get_edit_format_token_count = (format: EditFormat) => {
247-
switch (format) {
248-
case 'whole':
249-
return Math.ceil(EDIT_FORMAT_INSTRUCTIONS_WHOLE.length / 4)
250-
case 'search-replace':
251-
return Math.ceil(EDIT_FORMAT_INSTRUCTIONS_SEARCH_REPLACE.length / 4)
252-
case 'diff':
253-
return Math.ceil(EDIT_FORMAT_INSTRUCTIONS_DIFF.length / 4)
254-
case 'truncated':
255-
return Math.ceil(EDIT_FORMAT_INSTRUCTIONS_TRUNCATED.length / 4)
256-
257-
default:
258-
return 0
259-
}
260-
}
261-
262-
const edit_format_token_count = get_edit_format_token_count(props.edit_format)
263-
264238
return (
265239
<>
266240
<Header
@@ -329,6 +303,13 @@ export const MainView: React.FC<Props> = (props) => {
329303
currently_open_file_text={props.currently_open_file_text}
330304
on_caret_position_change={props.on_caret_position_change}
331305
caret_position_to_set={props.caret_position_to_set}
306+
prompt_token_count={
307+
(props.mode == MODE.WEB
308+
? props.web_prompt_type
309+
: props.api_prompt_type) == 'edit-files'
310+
? props.edit_instructions_token_count
311+
: props.ask_instructions_token_count
312+
}
332313
on_caret_position_set={props.on_caret_position_set}
333314
focus_and_select_key={props.chat_input_focus_and_select_key}
334315
focus_key={props.chat_input_focus_key}
@@ -359,6 +340,13 @@ export const MainView: React.FC<Props> = (props) => {
359340
on_tabs_reorder={props.on_tabs_reorder}
360341
warning={warning}
361342
voice_input_push_to_talk={props.voice_input_push_to_talk}
343+
selected_files_token_count={props.selected_files_token_count}
344+
include_selected_files={props.include_selected_files}
345+
on_toggle_include_selected_files={() =>
346+
props.on_toggle_include_selected_files(
347+
!props.include_selected_files
348+
)
349+
}
362350
currently_open_file_path={props.currently_open_file_path}
363351
translations={{
364352
voice_input: t('prompt-field.voice-input'),
@@ -384,38 +372,12 @@ export const MainView: React.FC<Props> = (props) => {
384372
copy_prompt: t('prompt-field.action.copy-prompt'),
385373
more_actions: t('prompt-field.action.more-actions'),
386374
send: t('prompt-field.action.send'),
375+
tokens_in_context: t('prompt-field.tokens-in-context'),
387376
mode: t('prompt-field.mode')
388377
}}
389378
/>
390379
</div>
391380

392-
<UiSeparator height={6} />
393-
394-
<UiTokenCounts
395-
token_count={{
396-
selected_files: display_token_count(
397-
props.selected_files_token_count
398-
),
399-
prompt: display_token_count(
400-
(props.mode == MODE.WEB
401-
? props.web_prompt_type
402-
: props.api_prompt_type) == 'edit-files'
403-
? props.edit_instructions_token_count + edit_format_token_count
404-
: props.ask_instructions_token_count
405-
)
406-
}}
407-
include_selected_files={props.include_selected_files}
408-
on_toggle_include_selected_files={
409-
props.on_toggle_include_selected_files
410-
}
411-
translations={{
412-
selected_files: t('main.token-count.selected-files'),
413-
prompt: t('main.token-count.prompt')
414-
}}
415-
/>
416-
417-
<UiSeparator height={10} />
418-
419381
{props.mode == MODE.WEB && (
420382
<UiConfigurations
421383
configurations={web_configurations}
Lines changed: 88 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,92 @@
11
export const main = {
2-
'main.token-count.selected-files': {
3-
en: 'Selected files',
4-
pl: 'Wybrane pliki',
5-
'zh-cn': '选定的文件',
6-
ja: '選択されたファイル',
7-
'zh-tw': '選定的檔案',
8-
de: 'Ausgewählte Dateien',
9-
es: 'Archivos seleccionados',
10-
fr: 'Fichiers sélectionnés',
11-
'pt-br': 'Arquivos selecionados',
12-
ru: 'Выбранные файлы',
13-
ko: '선택된 파일',
14-
it: 'File selezionati',
15-
tr: 'Seçili dosyalar',
16-
cs: 'Vybrané soubory',
17-
hu: 'Kiválasztott fájlok',
18-
bg: 'Избрани файлове'
2+
'main.token-counts.context-window': {
3+
en: 'Context window',
4+
pl: 'Okno kontekstu',
5+
'zh-cn': '上下文窗口',
6+
ja: 'コンテキストウィンドウ',
7+
'zh-tw': '上下文視窗',
8+
de: 'Kontextfenster',
9+
es: 'Ventana de contexto',
10+
fr: 'Fenêtre de contexte',
11+
'pt-br': 'Janela de contexto',
12+
ru: 'Контекстное окно',
13+
ko: '컨텍스트 창',
14+
it: 'Finestra di contesto',
15+
tr: 'Bağlam penceresi',
16+
cs: 'Kontextové okno',
17+
hu: 'Kontextus ablak',
18+
bg: 'Контекстен прозорец'
1919
},
20-
'main.token-count.prompt': {
21-
en: 'Prompt',
22-
pl: 'Prompt',
23-
'zh-cn': '提示',
24-
ja: 'プロンプト',
25-
'zh-tw': '提示',
26-
de: 'Prompt',
27-
es: 'Prompt',
28-
fr: 'Prompt',
29-
'pt-br': 'Prompt',
30-
ru: 'Промпт',
31-
ko: '프롬프트',
32-
it: 'Prompt',
33-
tr: 'Prompt',
34-
cs: 'Prompt',
35-
hu: 'Prompt',
36-
bg: 'Промпт'
20+
'main.token-counts.in-selected-files': {
21+
en: ' in selected files, ',
22+
pl: ' w wybranych plikach, ',
23+
'zh-cn': ' 在选定的文件中,',
24+
ja: ' 選択されたファイル内、',
25+
'zh-tw': ' 在選定的檔案中,',
26+
de: ' in ausgewählten Dateien, ',
27+
es: ' en archivos seleccionados, ',
28+
fr: ' dans les fichiers sélectionnés, ',
29+
'pt-br': ' nos arquivos selecionados, ',
30+
ru: ' в выбранных файлах, ',
31+
ko: ' 선택된 파일에서, ',
32+
it: ' nei file selezionati, ',
33+
tr: ' seçili dosyalarda, ',
34+
cs: ' ve vybraných souborech, ',
35+
hu: ' a kiválasztott fájlokban, ',
36+
bg: ' в избраните файлове, '
37+
},
38+
'main.token-counts.in-prompt': {
39+
en: ' in prompt, ',
40+
pl: ' w prompcie, ',
41+
'zh-cn': ' 在提示中,',
42+
ja: ' プロンプト内、',
43+
'zh-tw': ' 在提示中,',
44+
de: ' im Prompt, ',
45+
es: ' en el prompt, ',
46+
fr: ' dans le prompt, ',
47+
'pt-br': ' no prompt, ',
48+
ru: ' в промпте, ',
49+
ko: ' 프롬프트에서, ',
50+
it: ' nel prompt, ',
51+
tr: ' prompt içinde, ',
52+
cs: ' v promptu, ',
53+
hu: ' a promptban, ',
54+
bg: ' в промпта, '
55+
},
56+
'main.token-counts.totalling': {
57+
en: 'totalling ',
58+
pl: 'łącznie ',
59+
'zh-cn': '总计 ',
60+
ja: '合計 ',
61+
'zh-tw': '總計 ',
62+
de: 'insgesamt ',
63+
es: 'totalizando ',
64+
fr: 'totalisant ',
65+
'pt-br': 'totalizando ',
66+
ru: 'итого ',
67+
ko: '총 ',
68+
it: 'per un totale di ',
69+
tr: 'toplam ',
70+
cs: 'celkem ',
71+
hu: 'összesen ',
72+
bg: 'общо '
73+
},
74+
'main.token-counts.tokens': {
75+
en: ' tokens',
76+
pl: ' tokenów',
77+
'zh-cn': ' 个令牌',
78+
ja: ' トークン',
79+
'zh-tw': ' 個代幣',
80+
de: ' Token',
81+
es: ' tokens',
82+
fr: ' jetons',
83+
'pt-br': ' tokens',
84+
ru: ' токенов',
85+
ko: ' 토큰',
86+
it: ' token',
87+
tr: ' jeton',
88+
cs: ' tokenů',
89+
hu: ' token',
90+
bg: ' токена'
3791
}
3892
} as const

‎apps/editor/src/views/prompt/frontend/i18n/translations/prompt-field.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,24 @@ export const prompt_field = {
341341
hu: 'Küldés',
342342
bg: 'Изпращане'
343343
},
344+
'prompt-field.tokens-in-context': {
345+
en: 'Tokens in context',
346+
pl: 'Tokeny w kontekście',
347+
'zh-cn': '上下文中的令牌数',
348+
ja: 'コンテキスト内のトークン数',
349+
'zh-tw': '上下文中的權杖數',
350+
de: 'Tokens im Kontext',
351+
es: 'Tokens en contexto',
352+
fr: 'Tokens dans le contexte',
353+
'pt-br': 'Tokens no contexto',
354+
ru: 'Токены в контексте',
355+
ko: '컨텍스트 내 토큰 수',
356+
it: 'Token nel contesto',
357+
tr: 'Bağlamdaki belirteçler',
358+
cs: 'Tokeny v kontextu',
359+
hu: 'Tokenek a kontextusban',
360+
bg: 'Токени в контекста'
361+
},
344362
'prompt-field.mode': {
345363
en: 'Mode',
346364
pl: 'Tryb',

‎packages/ui/src/components/editor/common/prompts/PromptField/PromptField.module.scss‎

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,43 @@
5252
position: relative;
5353
}
5454

55+
.top-right {
56+
float: right;
57+
display: flex;
58+
align-items: center;
59+
margin: 5px 4px 0 4px;
60+
61+
&__prompt-token-count {
62+
font-size: 10px;
63+
transform: translateY(0.5px);
64+
color: var(--vscode-icon-foreground);
65+
opacity: var(--dimmed-opacity);
66+
pointer-events: none;
67+
font-variant-numeric: tabular-nums;
68+
}
69+
70+
&__clear-button {
71+
position: relative;
72+
width: 18px;
73+
cursor: pointer;
74+
color: var(--vscode-icon-foreground);
75+
opacity: var(--dimmed-opacity);
76+
display: flex;
77+
align-items: center;
78+
justify-content: center;
79+
padding-bottom: 2px;
80+
81+
&::before {
82+
font-size: 13px !important;
83+
line-height: 1;
84+
}
85+
86+
&:hover {
87+
opacity: 1;
88+
}
89+
}
90+
}
91+
5592
.warning {
5693
position: absolute;
5794
z-index: 3;
@@ -134,26 +171,6 @@
134171
}
135172
}
136173

137-
.clear-button {
138-
float: right;
139-
position: relative;
140-
width: 18px;
141-
cursor: pointer;
142-
color: var(--vscode-icon-foreground);
143-
opacity: var(--dimmed-opacity);
144-
transform: translate(5px, -3px);
145-
padding-bottom: 2px;
146-
147-
&::before {
148-
font-size: 13px !important;
149-
line-height: 1;
150-
}
151-
152-
&:hover {
153-
opacity: 1;
154-
}
155-
}
156-
157174
.footer {
158175
display: flex;
159176
padding: 6px 10px 6px 6px;
@@ -216,6 +233,35 @@
216233
min-width: 0;
217234
}
218235

236+
&__token-count-wrapper {
237+
position: relative;
238+
239+
&--clickable {
240+
cursor: pointer;
241+
242+
.footer__right__details__token-count {
243+
cursor: pointer;
244+
}
245+
246+
&:hover {
247+
.footer__right__details__token-count {
248+
color: var(--vscode-foreground);
249+
}
250+
}
251+
}
252+
}
253+
254+
&__token-count {
255+
color: var(--cwc-text-color-dimmed);
256+
font-variant-numeric: tabular-nums;
257+
cursor: default;
258+
259+
&--excluded {
260+
text-decoration: line-through;
261+
opacity: 0.5;
262+
}
263+
}
264+
219265
&__button {
220266
pointer-events: all;
221267
color: var(--vscode-foreground);

0 commit comments

Comments
 (0)