Skip to content

Commit 9fefb65

Browse files
committed
Implement voice input support in the settings and update documentation
1 parent a3b3ef0 commit 9fefb65

16 files changed

Lines changed: 270 additions & 37 deletions

‎README.md‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,20 @@ Pair-programming using natural language instructions.
8181
Integrate changes from malformed markdown code blocks.
8282

8383
**🛠️ Prune Context** \
84-
Remove irrelevant files from the current context selection.
84+
Remove irrelevant files from the current context.
8585

8686
**🛠️ Code at Cursor** \
87-
Get accurate inline suggestions from state-of-the-art models.
87+
Accurate inline code from reasoning models.
88+
89+
**🛠️ Voice Input** \
90+
Transcribe speech to text in the prompt field.
8891

8992
**🛠️ Commit Messages** \
90-
Meaningful summaries of changes adhering to your preffered style.
93+
Meaningful summaries of changes in your style.
9194

9295
## Enterprise security
9396

94-
**Code Web Chat operates exclusively on your machine.** Your prompts are sent directly to chatbots via editor-browser communication channel run on local Websockets. For API tools, model providers are called directly.
97+
Code Web Chat operates exclusively on your machine. Your prompts are sent directly to chatbots via editor-browser communication channel run on local Websockets. For API tools, model providers are called directly.
9598

9699
## Commands
97100

‎apps/editor/package.json‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,6 +1850,44 @@
18501850
"model"
18511851
]
18521852
}
1853+
},
1854+
"codeWebChat.configurationsForVoiceInput": {
1855+
"type": "array",
1856+
"scope": "resource",
1857+
"default": [],
1858+
"items": {
1859+
"type": "object",
1860+
"properties": {
1861+
"providerName": {
1862+
"type": "string"
1863+
},
1864+
"model": {
1865+
"type": "string"
1866+
},
1867+
"temperature": {
1868+
"type": "number"
1869+
},
1870+
"reasoningEffort": {
1871+
"type": "string",
1872+
"enum": [
1873+
"none",
1874+
"low",
1875+
"medium",
1876+
"high"
1877+
]
1878+
},
1879+
"isDefault": {
1880+
"type": "boolean"
1881+
},
1882+
"isPinned": {
1883+
"type": "boolean"
1884+
}
1885+
},
1886+
"required": [
1887+
"providerName",
1888+
"model"
1889+
]
1890+
}
18531891
}
18541892
}
18551893
}

‎apps/editor/src/services/model-providers-manager.ts‎

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export type EditContextConfigs = ToolConfig[]
4444
export type IntelligentUpdateConfigs = ToolConfig[]
4545
export type CommitMessagesConfigs = ToolConfig[]
4646
export type PruneContextConfigs = ToolConfig[]
47+
export type VoiceInputConfigs = ToolConfig[]
4748

4849
export class ModelProvidersManager {
4950
private _providers: Provider[] = []
@@ -444,6 +445,40 @@ export class ModelProvidersManager {
444445
)
445446
}
446447

448+
public async get_voice_input_tool_configs(): Promise<VoiceInputConfigs> {
449+
await this._load_promise
450+
return this._get_tool_configs_from_settings('configurationsForVoiceInput')
451+
}
452+
453+
public async get_default_voice_input_config(): Promise<
454+
ToolConfig | undefined
455+
> {
456+
await this._load_promise
457+
const default_config = this._get_default_tool_config_from_settings(
458+
'configurationsForVoiceInput'
459+
)
460+
if (default_config) return default_config
461+
462+
const configs = await this.get_voice_input_tool_configs()
463+
if (configs.length == 1) return configs[0]
464+
465+
return undefined
466+
}
467+
468+
public async set_default_voice_input_config(config: ToolConfig | null) {
469+
await this._set_default_tool_config_in_settings(
470+
'configurationsForVoiceInput',
471+
config
472+
)
473+
}
474+
475+
public async save_voice_input_tool_configs(configs: VoiceInputConfigs) {
476+
await this._save_tool_configs_to_settings(
477+
'configurationsForVoiceInput',
478+
configs
479+
)
480+
}
481+
447482
public async update_provider_name_in_configs(params: {
448483
old_name: string
449484
new_name: string
@@ -456,7 +491,8 @@ export class ModelProvidersManager {
456491
'configurationsForEditContext',
457492
'configurationsForIntelligentUpdate',
458493
'configurationsForCommitMessages',
459-
'configurationsForPruneContext'
494+
'configurationsForPruneContext',
495+
'configurationsForVoiceInput'
460496
]
461497

462498
for (const key of settings_keys) {

‎apps/editor/src/views/i18n/translations.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ export const translations = {
1111
'settings.sidebar.code-at-cursor': 'Code at Cursor',
1212
'settings.sidebar.intelligent-update': 'Intelligent Update',
1313
'settings.sidebar.prune-context': 'Prune Context',
14-
'settings.sidebar.commit-messages': 'Commit Messages'
14+
'settings.sidebar.commit-messages': 'Commit Messages',
15+
'settings.sidebar.voice-input': 'Voice Input'
1516
},
1617
pl: {
1718
'panel.header.settings': 'Ustawienia',

‎apps/editor/src/views/settings/backend/message-handlers/handle-delete-configuration.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const handle_delete_configuration = async (
1010
| 'intelligent-update'
1111
| 'commit-messages'
1212
| 'prune-context'
13+
| 'voice-input'
1314
): Promise<void> => {
1415
await delete_configuration(provider.context, configuration_id, type)
1516
}

‎apps/editor/src/views/settings/backend/message-handlers/handle-get-configurations.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const handle_get_configurations = async (
2525
| 'intelligent-update'
2626
| 'commit-messages'
2727
| 'prune-context'
28+
| 'voice-input'
2829
): Promise<void> => {
2930
const providers_manager = new ModelProvidersManager(provider.context)
3031

@@ -61,6 +62,11 @@ export const handle_get_configurations = async (
6162
saved_configs = await providers_manager.get_prune_context_tool_configs()
6263
command = 'PRUNE_CONTEXT_CONFIGURATIONS'
6364
break
65+
case 'voice-input':
66+
saved_configs = await providers_manager.get_voice_input_tool_configs()
67+
default_config = await providers_manager.get_default_voice_input_config()
68+
command = 'VOICE_INPUT_CONFIGURATIONS'
69+
break
6470
}
6571

6672
const default_config_id = default_config

‎apps/editor/src/views/settings/backend/message-handlers/handle-reorder-configuration.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const handle_reorder_configuration = async (
1414
| 'intelligent-update'
1515
| 'commit-messages'
1616
| 'prune-context'
17+
| 'voice-input'
1718
): Promise<void> => {
1819
const providers_manager = new ModelProvidersManager(provider.context)
1920

@@ -45,6 +46,10 @@ export const handle_reorder_configuration = async (
4546
get_configs = () => providers_manager.get_prune_context_tool_configs()
4647
save_configs = (c) => providers_manager.save_prune_context_tool_configs(c)
4748
break
49+
case 'voice-input':
50+
get_configs = () => providers_manager.get_voice_input_tool_configs()
51+
save_configs = (c) => providers_manager.save_voice_input_tool_configs(c)
52+
break
4853
}
4954

5055
const current_configs = await get_configs()

‎apps/editor/src/views/settings/backend/message-handlers/handle-set-default-configuration.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const handle_set_default_configuration = async (
1313
| 'intelligent-update'
1414
| 'commit-messages'
1515
| 'prune-context'
16+
| 'voice-input'
1617
): Promise<void> => {
1718
const providers_manager = new ModelProvidersManager(provider.context)
1819

@@ -41,6 +42,11 @@ export const handle_set_default_configuration = async (
4142
set_default_config = (c) =>
4243
providers_manager.set_default_prune_context_config(c)
4344
break
45+
case 'voice-input':
46+
get_configs = () => providers_manager.get_voice_input_tool_configs()
47+
set_default_config = (c) =>
48+
providers_manager.set_default_voice_input_config(c)
49+
break
4450
}
4551

4652
if (configuration_id === null) {

‎apps/editor/src/views/settings/backend/settings-provider.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,26 @@ export class SettingsProvider {
208208
message.configuration_id,
209209
'prune-context'
210210
)
211+
} else if (message.command == 'GET_VOICE_INPUT_CONFIGURATIONS') {
212+
await handle_get_configurations(this, 'voice-input')
213+
} else if (message.command == 'REORDER_VOICE_INPUT_CONFIGURATIONS') {
214+
await handle_reorder_configuration(
215+
this,
216+
message.configurations,
217+
'voice-input'
218+
)
219+
} else if (message.command == 'DELETE_VOICE_INPUT_CONFIGURATION') {
220+
await handle_delete_configuration(
221+
this,
222+
message.configuration_id,
223+
'voice-input'
224+
)
225+
} else if (message.command == 'SET_DEFAULT_VOICE_INPUT_CONFIGURATION') {
226+
await handle_set_default_configuration(
227+
this,
228+
message.configuration_id,
229+
'voice-input'
230+
)
211231
} else if (message.command == 'GET_COMMIT_MESSAGES_CONFIGURATIONS') {
212232
await handle_get_configurations(this, 'commit-messages')
213233
} else if (
@@ -311,6 +331,7 @@ export class SettingsProvider {
311331
void handle_get_configurations(this, 'edit-context')
312332
void handle_get_edit_context_system_instructions(this)
313333
void handle_get_edit_format_instructions(this)
334+
void handle_get_configurations(this, 'voice-input')
314335
void handle_get_configurations(this, 'intelligent-update')
315336
void handle_get_configurations(this, 'prune-context')
316337
void handle_get_context_size_warning_threshold(this)

‎apps/editor/src/views/settings/frontend/Home/Home.tsx‎

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type NavItem =
2626
| 'edit-context'
2727
| 'code-at-cursor'
2828
| 'intelligent-update'
29+
| 'voice-input'
2930
| 'prune-context'
3031
| 'commit-messages'
3132

@@ -61,6 +62,11 @@ const NAV_ITEMS_CONFIG: NavConfigItem[] = [
6162
id: 'code-at-cursor',
6263
label: 'settings.sidebar.code-at-cursor'
6364
},
65+
{
66+
type: 'item',
67+
id: 'voice-input',
68+
label: 'settings.sidebar.voice-input'
69+
},
6470
{
6571
type: 'item',
6672
id: 'commit-messages',
@@ -73,6 +79,7 @@ type Props = {
7379
code_at_cursor_configs: ConfigurationForClient[]
7480
commit_messages_configs: ConfigurationForClient[]
7581
edit_context_configs: ConfigurationForClient[]
82+
voice_input_configs: ConfigurationForClient[]
7683
edit_context_system_instructions: string
7784
intelligent_update_configs: ConfigurationForClient[]
7885
prune_context_configs: ConfigurationForClient[]
@@ -93,6 +100,7 @@ type Props = {
93100
set_edit_context_configs: (configs: ConfigurationForClient[]) => void
94101
set_code_at_cursor_configs: (configs: ConfigurationForClient[]) => void
95102
set_intelligent_update_configs: (configs: ConfigurationForClient[]) => void
103+
set_voice_input_configs: (configs: ConfigurationForClient[]) => void
96104
set_prune_context_configs: (configs: ConfigurationForClient[]) => void
97105
set_commit_messages_configs: (configs: ConfigurationForClient[]) => void
98106
on_context_size_warning_threshold_change: (
@@ -151,6 +159,7 @@ export const Home: React.FC<Props> = (props) => {
151159
'edit-context': null,
152160
'intelligent-update': null,
153161
'prune-context': null,
162+
'voice-input': null,
154163
'code-at-cursor': null,
155164
'commit-messages': null
156165
})
@@ -199,6 +208,10 @@ export const Home: React.FC<Props> = (props) => {
199208
(is_stuck: boolean) => handle_stuck_change('intelligent-update', is_stuck),
200209
[handle_stuck_change]
201210
)
211+
const voice_input_on_stuck_change = useCallback(
212+
(is_stuck: boolean) => handle_stuck_change('voice-input', is_stuck),
213+
[handle_stuck_change]
214+
)
202215
const prune_context_on_stuck_change = useCallback(
203216
(is_stuck: boolean) => handle_stuck_change('prune-context', is_stuck),
204217
[handle_stuck_change]
@@ -470,7 +483,7 @@ export const Home: React.FC<Props> = (props) => {
470483
ref={(el) => (section_refs.current['prune-context'] = el)}
471484
group="API Tool"
472485
title="Prune Context"
473-
subtitle="Remove irrelevant files from the current context selection."
486+
subtitle="Remove irrelevant files from the current context."
474487
on_stuck_change={prune_context_on_stuck_change}
475488
actions={
476489
<Button
@@ -501,7 +514,7 @@ export const Home: React.FC<Props> = (props) => {
501514
ref={(el) => (section_refs.current['code-at-cursor'] = el)}
502515
group="API Tool"
503516
title="Code at Cursor"
504-
subtitle="Get accurate inline suggestions from state-of-the-art models."
517+
subtitle="Accurate inline code from reasoning models."
505518
on_stuck_change={code_at_cursor_on_stuck_change}
506519
actions={
507520
<Button
@@ -547,11 +560,51 @@ export const Home: React.FC<Props> = (props) => {
547560
/>
548561
</Group>
549562
</Section>
563+
<Section
564+
ref={(el) => (section_refs.current['voice-input'] = el)}
565+
group="API Tool"
566+
title="Voice Input"
567+
subtitle="Transcribe speech to text in the prompt field."
568+
on_stuck_change={voice_input_on_stuck_change}
569+
actions={
570+
<Button
571+
on_click={() =>
572+
props.on_add_config('VOICE_INPUT', {
573+
create_on_top: true
574+
})
575+
}
576+
>
577+
Add New...
578+
</Button>
579+
}
580+
>
581+
<Group>
582+
<ApiToolConfigurationSection
583+
configurations={props.voice_input_configs}
584+
set_configurations={props.set_voice_input_configs}
585+
tool_name="VOICE_INPUT"
586+
can_have_default={true}
587+
on_add={(params) => props.on_add_config('VOICE_INPUT', params)}
588+
on_reorder={(reordered) =>
589+
props.on_reorder_configs('VOICE_INPUT', reordered)
590+
}
591+
on_edit={(id) => props.on_edit_config('VOICE_INPUT', id)}
592+
on_delete={(id) => props.on_delete_config('VOICE_INPUT', id)}
593+
on_set_default={(id) =>
594+
props.on_set_default_config('VOICE_INPUT', id)
595+
}
596+
on_unset_default={() =>
597+
props.on_unset_default_config('VOICE_INPUT')
598+
}
599+
/>
600+
</Group>
601+
</Section>
602+
550603
<Section
551604
ref={(el) => (section_refs.current['commit-messages'] = el)}
552605
group="API Tool"
553606
title="Commit Messages"
554-
subtitle="Meaningful summaries of changes adhering to your preffered style."
607+
subtitle="Meaningful summaries of changes in your style."
555608
on_stuck_change={commit_messages_on_stuck_change}
556609
actions={
557610
<Button

0 commit comments

Comments
 (0)