Skip to content

Commit 6b321ca

Browse files
committed
Add patch repair via CLI agents and default agent configuration
- add 'invoke agent' option to 'patch repair' - allow setting default 'patch repair' agent ├── README.md ├── apps │ ├── browser │ │ └── README.md │ ├── editor │ │ ├── package.json │ │ └── src │ │ ├── commands │ │ │ ├── apply-response-command │ │ │ │ ├── apply-response-command.ts │ │ │ │ ├── response-processor │ │ │ │ │ ├── handlers │ │ │ │ │ │ └── patch-repair-handler.ts │ │ │ │ │ └── response-processor.ts │ │ │ │ ├── types │ │ │ │ │ └── original-file-state.ts │ │ │ │ └── utils │ │ │ │ ├── preview │ │ │ │ │ ├── build-history-files.ts │ │ │ │ │ ├── file-preparer.ts │ │ │ │ │ ├── preview.ts │ │ │ │ │ └── workspace-listener.ts │ │ │ │ └── response-parser │ │ │ │ ├── parsers │ │ │ │ │ ├── index.ts │ │ │ │ │ └── patch-repair-parser │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── patch-repair-parser.ts │ │ │ │ │ └── test │ │ │ │ │ └── patch-repair-parser.spec.ts │ │ │ │ └── response-parser.ts │ │ │ ├── code-at-cursor-command │ │ │ │ └── utils │ │ │ │ └── perform-code-at-cursor.ts │ │ │ └── generate-commit-message-commands │ │ │ └── actions │ │ │ └── run-generate-action.ts │ │ ├── constants │ │ │ ├── instructions.ts │ │ │ └── state-keys.ts │ │ ├── features │ │ │ ├── agentic-search │ │ │ │ └── agentic-search.ts │ │ │ └── search-files │ │ │ └── search-modes │ │ │ └── perform-intelligent-search-mode.ts │ │ ├── i18n │ │ │ └── translations │ │ │ ├── common.ts │ │ │ └── views │ │ │ └── prompt │ │ │ └── handlers │ │ │ ├── handle-patch-repair.ts │ │ │ └── index.ts │ │ ├── utils │ │ │ ├── agentic-cli-invocation │ │ │ │ ├── agents │ │ │ │ │ ├── antigravity.ts │ │ │ │ │ ├── claude.ts │ │ │ │ │ ├── codex.ts │ │ │ │ │ ├── cursor.ts │ │ │ │ │ ├── grok.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── opencode.ts │ │ │ │ ├── index.ts │ │ │ │ ├── invoke-agentic-cli.ts │ │ │ │ ├── types.ts │ │ │ │ └── utils │ │ │ │ ├── check-command-exists.ts │ │ │ │ ├── format-duration.ts │ │ │ │ ├── generate-diff-markdown.ts │ │ │ │ └── get-progress-dots.ts │ │ │ └── cli-configuration-format-converters.ts │ │ └── views │ │ ├── prompt │ │ │ ├── backend │ │ │ │ ├── message-handlers │ │ │ │ │ ├── handle-cancel-intelligent-update-file-in-preview.ts │ │ │ │ │ ├── handle-invoke-agentic-cli.ts │ │ │ │ │ ├── handle-patch-repair.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── utils │ │ │ │ │ └── patch-repair-utils.ts │ │ │ │ └── prompt-view-provider.ts │ │ │ ├── frontend │ │ │ │ ├── Prompt.tsx │ │ │ │ └── hooks │ │ │ │ └── use-preview-manager.ts │ │ │ └── types │ │ │ └── messages.ts │ │ └── settings │ │ ├── backend │ │ │ ├── message-handlers │ │ │ │ ├── handle-get-cli-configurations.ts │ │ │ │ ├── handle-select-default-cli-configuration.ts │ │ │ │ └── handle-set-default-cli-configuration.ts │ │ │ └── settings-view-provider.ts │ │ ├── frontend │ │ │ ├── Home │ │ │ │ ├── Home.tsx │ │ │ │ └── sections │ │ │ │ └── CliSection.tsx │ │ │ ├── Settings.tsx │ │ │ ├── hooks │ │ │ │ └── use-settings.ts │ │ │ └── i18n │ │ │ └── translations │ │ │ └── cli.ts │ │ └── types │ │ └── messages.ts │ └── old-website │ └── README.md ├── docs │ ├── api-tools │ │ └── index.mdx │ └── chatbot-initialization.mdx ├── media │ └── README.md └── packages ├── shared │ └── src │ └── types │ └── file-in-preview.ts └── ui └── src └── components └── editor └── prompt └── ResponsePreview ├── ResponsePreview.stories.tsx ├── ResponsePreview.tsx └── components └── FileItem └── FileItem.tsx
1 parent 4fd05ca commit 6b321ca

11 files changed

Lines changed: 158 additions & 28 deletions

File tree

‎apps/editor/package.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,9 @@
10481048
},
10491049
"isDefaultForIntelligentSearch": {
10501050
"type": "boolean"
1051+
},
1052+
"isDefaultForPatchRepair": {
1053+
"type": "boolean"
10511054
}
10521055
},
10531056
"required": [

‎apps/editor/src/constants/state-keys.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ export const LAST_USED_PATCH_REPAIR_CONFIG_ID_STATE_KEY =
6464
'last-used-patch-repair-config-id'
6565
export const LAST_USED_PATCH_REPAIR_ACTION_STATE_KEY =
6666
'last-used-patch-repair-action'
67+
export const LAST_SELECTED_WORKSPACE_FOR_PATCH_REPAIR_STATE_KEY =
68+
'last-selected-workspace-for-patch-repair'
69+
export const LAST_USED_AGENT_FOR_PATCH_REPAIR_STATE_KEY =
70+
'last-used-agent-for-patch-repair'
6771
export const LAST_USED_VOICE_INPUT_CONFIG_ID_STATE_KEY =
6872
'last-used-voice-input-config-id'
6973

‎apps/editor/src/utils/cli-configuration-format-converters.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export type ConfigAgentConfigurationFormat = {
99
isDefaultForAgenticSearch?: boolean
1010
isDefaultForCodeAtCursor?: boolean
1111
isDefaultForIntelligentSearch?: boolean
12+
isDefaultForPatchRepair?: boolean
1213
}
1314

1415
export const config_cli_configuration_to_ui_format = (

‎apps/editor/src/views/prompt/backend/message-handlers/handle-patch-repair.ts‎

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { PromptViewProvider } from '@/views/prompt/backend/prompt-view-provider'
44
import {
55
LAST_APPLIED_CHANGES_STATE_KEY,
66
LAST_APPLIED_CLIPBOARD_CONTENT_STATE_KEY,
7-
LAST_USED_PATCH_REPAIR_ACTION_STATE_KEY
7+
LAST_USED_PATCH_REPAIR_ACTION_STATE_KEY,
8+
LAST_SELECTED_WORKSPACE_FOR_PATCH_REPAIR_STATE_KEY,
9+
LAST_USED_AGENT_FOR_PATCH_REPAIR_STATE_KEY
810
} from '@/constants/state-keys'
911
import { OriginalFileState } from '@/commands/apply-response-command/types/original-file-state'
1012
import { parse_response } from '@/commands/apply-response-command/utils/response-parser'
@@ -23,9 +25,11 @@ import { show_configurations_quick_pick } from '@/utils/show-configurations-quic
2325
import { get_last_used_web_configuration_key } from '@/constants/state-keys'
2426
import {
2527
patch_repair_format_instructions,
26-
patch_repair_task_instructions
28+
patch_repair_task_instructions,
29+
cli_edit_ask_requirements
2730
} from '@/constants/instructions'
2831
import { ConfigWebConfigurationFormat } from '@/utils/web-configuration-format-converters'
32+
import { invoke_agentic_cli } from '@/utils/agentic-cli-invocation'
2933

3034
export const handle_patch_repair = async (params: {
3135
prompt_view_provider: PromptViewProvider
@@ -157,6 +161,10 @@ export const handle_patch_repair = async (params: {
157161
label: t('common.action.send-request'),
158162
id: 'make-api'
159163
},
164+
{
165+
label: t('common.action.invoke-agent'),
166+
id: 'invoke-agent'
167+
},
160168
...(params.prompt_view_provider.websocket_server_instance.is_connected_with_browser()
161169
? [
162170
{
@@ -235,6 +243,74 @@ export const handle_patch_repair = async (params: {
235243
return
236244
}
237245

246+
if (action == 'invoke-agent') {
247+
let cli_prompt = ''
248+
for (const item of files_to_process) {
249+
const backticks = item.file_state.content.includes('```') ? '````' : '```'
250+
const display_path =
251+
!is_single_root_folder_workspace && item.file_state.workspace_name
252+
? `${item.file_state.workspace_name}/${item.file_state.file_path}`
253+
: item.file_state.file_path
254+
cli_prompt += `# File: \`${display_path}\`\n\n${backticks}\n${item.file_state.content}\n${backticks}\n\n${item.instructions}\n\n`
255+
}
256+
cli_prompt += `# Output formatting\n\n`
257+
cli_prompt += `${patch_repair_format_instructions}\n\n`
258+
cli_prompt += `# Requirements\n\n- ${cli_edit_ask_requirements.preloaded_context}\n- ${cli_edit_ask_requirements.restrict_shell_commands}\n\n`
259+
cli_prompt += `# Task\n\n${patch_repair_task_instructions}`
260+
261+
const config_codeWebChat = vscode.workspace.getConfiguration('codeWebChat')
262+
const agent_configs = config_codeWebChat.get<any[]>('agents', []) || []
263+
const default_agent = agent_configs.find(
264+
(c: any) => c.isDefaultForPatchRepair
265+
)
266+
267+
const use_quick_pick = !default_agent
268+
const cli_configuration_name = default_agent
269+
? default_agent.name
270+
: undefined
271+
272+
const invoke_cli_result = await invoke_agentic_cli({
273+
workspace_provider: params.prompt_view_provider.workspace_provider,
274+
extension_context: params.prompt_view_provider.extension_context,
275+
build_prompt: async () => cli_prompt,
276+
notification_title: 'Patch Repair',
277+
last_selected_workspace_state_key:
278+
LAST_SELECTED_WORKSPACE_FOR_PATCH_REPAIR_STATE_KEY,
279+
last_used_agent_config_name:
280+
params.prompt_view_provider.extension_context.workspaceState.get<string>(
281+
LAST_USED_AGENT_FOR_PATCH_REPAIR_STATE_KEY
282+
),
283+
cli_configuration_name,
284+
use_quick_pick,
285+
on_agent_selected: (name) => {
286+
params.prompt_view_provider.extension_context.workspaceState.update(
287+
LAST_USED_AGENT_FOR_PATCH_REPAIR_STATE_KEY,
288+
name
289+
)
290+
params.prompt_view_provider.extension_context.globalState.update(
291+
LAST_USED_AGENT_FOR_PATCH_REPAIR_STATE_KEY,
292+
name
293+
)
294+
},
295+
show_back_button: true,
296+
isolate_in_temp_dir: true,
297+
agent_args_type: 'isolated-dir'
298+
})
299+
300+
if (invoke_cli_result === 'back') {
301+
return handle_patch_repair({ ...params, show_quick_pick: true })
302+
}
303+
304+
if (!invoke_cli_result) {
305+
return
306+
}
307+
308+
await vscode.commands.executeCommand('codeWebChat.applyResponse', {
309+
response: invoke_cli_result.agent_output
310+
})
311+
return
312+
}
313+
238314
if (action == 'copy') {
239315
let chatbot_prompt = ''
240316
for (const item of files_to_process) {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ export const handle_get_cli_configurations = async (
2626
'intelligent-search':
2727
cli_configurations_config.find(
2828
(c: any) => c.isDefaultForIntelligentSearch
29-
)?.name || null
29+
)?.name || null,
30+
'patch-repair':
31+
cli_configurations_config.find((c: any) => c.isDefaultForPatchRepair)
32+
?.name || null
3033
}
3134
})
3235
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ export const handle_select_default_cli_configuration = async (
7575
} else {
7676
delete new_c.isDefaultForIntelligentSearch
7777
}
78+
} else if (message.cli_feature == 'patch-repair') {
79+
if (c.name == selected.cli_configuration_name) {
80+
new_c.isDefaultForPatchRepair = true
81+
} else {
82+
delete new_c.isDefaultForPatchRepair
83+
}
7884
}
7985
return new_c
8086
})

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ export const handle_set_default_cli_configuration = async (
2626
} else {
2727
delete new_c.isDefaultForIntelligentSearch
2828
}
29+
} else if (message.cli_feature == 'patch-repair') {
30+
if (c.name == message.cli_configuration_name) {
31+
new_c.isDefaultForPatchRepair = true
32+
} else {
33+
delete new_c.isDefaultForPatchRepair
34+
}
2935
}
3036
return new_c
3137
})

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -309,21 +309,6 @@ export const ApiSection = forwardRef<HTMLDivElement, Props>((props, ref) => {
309309
title={t('api.default-configurations.title')}
310310
is_disabled={props.api_configurations.length === 0}
311311
>
312-
<DefaultConfigurationSelector
313-
title={t('api.default-configurations.tool.patch-repair')}
314-
value={props.defaults['patch-repair'] || null}
315-
configurations={selector_configurations}
316-
on_unset={() =>
317-
props.on_set_default_api_configuration('patch-repair', null)
318-
}
319-
on_select={() =>
320-
props.on_select_default_api_configuration('patch-repair')
321-
}
322-
translations={{
323-
select: t('api.configurations.action.select-default'),
324-
unset: t('api.configurations.action.unset-default')
325-
}}
326-
/>
327312
<DefaultConfigurationSelector
328313
title={t('api.default-configurations.tool.code-at-cursor')}
329314
value={props.defaults['code-at-cursor'] || null}
@@ -339,7 +324,6 @@ export const ApiSection = forwardRef<HTMLDivElement, Props>((props, ref) => {
339324
unset: t('api.configurations.action.unset-default')
340325
}}
341326
/>
342-
343327
<DefaultConfigurationSelector
344328
title={t('api.default-configurations.tool.voice-input')}
345329
value={props.defaults['voice-input'] || null}
@@ -355,7 +339,6 @@ export const ApiSection = forwardRef<HTMLDivElement, Props>((props, ref) => {
355339
unset: t('api.configurations.action.unset-default')
356340
}}
357341
/>
358-
359342
<DefaultConfigurationSelector
360343
title={t('api.default-configurations.tool.intelligent-search')}
361344
value={props.defaults['intelligent-search'] || null}
@@ -371,6 +354,21 @@ export const ApiSection = forwardRef<HTMLDivElement, Props>((props, ref) => {
371354
unset: t('api.configurations.action.unset-default')
372355
}}
373356
/>
357+
<DefaultConfigurationSelector
358+
title={t('api.default-configurations.tool.patch-repair')}
359+
value={props.defaults['patch-repair'] || null}
360+
configurations={selector_configurations}
361+
on_unset={() =>
362+
props.on_set_default_api_configuration('patch-repair', null)
363+
}
364+
on_select={() =>
365+
props.on_select_default_api_configuration('patch-repair')
366+
}
367+
translations={{
368+
select: t('api.configurations.action.select-default'),
369+
unset: t('api.configurations.action.unset-default')
370+
}}
371+
/>
374372
</UiGroup>
375373
</div>
376374

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,21 @@ export const CliSection = forwardRef<HTMLDivElement, Props>((props, ref) => {
217217
unset: t('agents.configurations.action.unset-default')
218218
}}
219219
/>
220+
<DefaultConfigurationSelector
221+
title={t('cli.default-configurations.tool.patch-repair')}
222+
value={props.agent_defaults['patch-repair'] || null}
223+
configurations={selector_configurations}
224+
on_unset={() =>
225+
props.on_set_default_cli_configuration('patch-repair', null)
226+
}
227+
on_select={() =>
228+
props.on_select_default_cli_configuration('patch-repair')
229+
}
230+
translations={{
231+
select: t('agents.configurations.action.select-default'),
232+
unset: t('agents.configurations.action.unset-default')
233+
}}
234+
/>
220235
</UiGroup>
221236
</div>
222237
</UiSection>

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,29 +362,29 @@ export const WebSection = forwardRef<HTMLDivElement, Props>((props, ref) => {
362362
}}
363363
/>
364364
<DefaultConfigurationSelector
365-
title={t('web.default-configurations.tool.patch-repair')}
366-
value={props.web_defaults['patch-repair'] || null}
365+
title={t('web.default-configurations.tool.intelligent-search')}
366+
value={props.web_defaults['intelligent-search'] || null}
367367
configurations={selector_configurations}
368368
on_unset={() =>
369-
props.on_set_default_web_configuration('patch-repair', null)
369+
props.on_set_default_web_configuration('intelligent-search', null)
370370
}
371371
on_select={() =>
372-
props.on_select_default_web_configuration('patch-repair')
372+
props.on_select_default_web_configuration('intelligent-search')
373373
}
374374
translations={{
375375
select: t('chatbots.configurations.action.select-default'),
376376
unset: t('chatbots.configurations.action.unset-default')
377377
}}
378378
/>
379379
<DefaultConfigurationSelector
380-
title={t('web.default-configurations.tool.intelligent-search')}
381-
value={props.web_defaults['intelligent-search'] || null}
380+
title={t('web.default-configurations.tool.patch-repair')}
381+
value={props.web_defaults['patch-repair'] || null}
382382
configurations={selector_configurations}
383383
on_unset={() =>
384-
props.on_set_default_web_configuration('intelligent-search', null)
384+
props.on_set_default_web_configuration('patch-repair', null)
385385
}
386386
on_select={() =>
387-
props.on_select_default_web_configuration('intelligent-search')
387+
props.on_select_default_web_configuration('patch-repair')
388388
}
389389
translations={{
390390
select: t('chatbots.configurations.action.select-default'),

0 commit comments

Comments
 (0)