Skip to content

Commit e505a52

Browse files
committed
Implement the Prune Context API tool, refactor instruction naming conventions, and enhance symbol processing logic across the extension and UI
1 parent e4a3e32 commit e505a52

31 files changed

Lines changed: 954 additions & 140 deletions

‎packages/shared/src/constants/dictionary.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export const dictionary = {
4141
'No matching files found in workspace for the paths in clipboard.',
4242
NO_CODE_COMPLETIONS_CONFIGURATIONS_FOUND:
4343
'No "Code Completions" configurations found. Please add one in the settings.',
44+
NO_PRUNE_CONTEXT_CONFIGURATIONS_FOUND:
45+
'No "Prune Context" configurations found. Please add one in the settings.',
4446
NO_RECENT_CHANGES_TO_UNDO:
4547
'No recent changes found to undo or changes were already undone.',
4648
CONTEXT_COPIED_TO_CLIPBOARD: 'Context copied to clipboard.',

‎packages/ui/src/components/editor/panel/PromptField/PromptField.tsx‎

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ export const PromptField: React.FC<PromptFieldProps> = (props) => {
170170
const highlighted_html = useMemo(() => {
171171
return get_highlighted_text({
172172
text: props.value,
173-
is_in_code_completions_mode: props.is_in_code_completions_mode,
174173
has_active_selection: props.has_active_selection,
175174
context_file_paths: props.context_file_paths ?? []
176175
})
@@ -424,15 +423,13 @@ export const PromptField: React.FC<PromptFieldProps> = (props) => {
424423
>
425424
<Icon variant="AT_SIGN" />
426425
</button>
427-
{!props.is_in_code_completions_mode && (
428-
<button
429-
onClick={props.on_hash_sign_click}
430-
className={cn(styles['footer__left__button'])}
431-
title="Insert Symbol"
432-
>
433-
<Icon variant="HASH_SIGN" />
434-
</button>
435-
)}
426+
<button
427+
onClick={props.on_hash_sign_click}
428+
className={cn(styles['footer__left__button'])}
429+
title="Insert Symbol"
430+
>
431+
<Icon variant="HASH_SIGN" />
432+
</button>
436433
<button
437434
onClick={props.on_curly_braces_click}
438435
className={cn(styles['footer__left__button'])}

‎packages/ui/src/components/editor/panel/PromptField/utils/get-highlighted-text.tsx‎

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -46,44 +46,11 @@ const process_text_part_for_files = (
4646

4747
export const get_highlighted_text = (params: {
4848
text: string
49-
is_in_code_completions_mode: boolean
5049
has_active_selection: boolean
5150
context_file_paths: string[]
5251
}): string => {
5352
const saved_context_regex_part =
5453
'#SavedContext:(?:WorkspaceState|JSON)\\s+"[^"]+"'
55-
if (params.is_in_code_completions_mode) {
56-
const regex = new RegExp(`(${saved_context_regex_part})`, 'g')
57-
const parts = params.text.split(regex)
58-
const result = parts
59-
.map((part) => {
60-
const saved_context_match = part.match(
61-
/^#SavedContext:(WorkspaceState|JSON)\s+"([^"]+)"$/
62-
)
63-
if (part && saved_context_match) {
64-
const context_type = saved_context_match[1]
65-
const context_name = saved_context_match[2]
66-
return `<span class="${cn(
67-
styles['keyword'],
68-
styles['keyword--saved-context']
69-
)}" data-type="saved-context-keyword" data-context-type="${context_type}" data-context-name="${escape_html(
70-
context_name
71-
)}"><span class="${
72-
styles['keyword__icon']
73-
}" data-role="keyword-icon"></span><span class="${
74-
styles['keyword__text']
75-
}" data-role="keyword-text">Context "${escape_html(
76-
context_name
77-
)}"</span></span>`
78-
}
79-
return process_text_part_for_files(part, params.context_file_paths)
80-
})
81-
.join('')
82-
if (params.text.endsWith('\n')) {
83-
return result + '<br data-role="trailing-break">'
84-
}
85-
return result
86-
}
8754

8855
const commit_regex_part =
8956
'#(?:Commit|ContextAtCommit):[^:]+:[^\\s"]+\\s+"(?:\\\\.|[^"\\\\])*"'

‎packages/vscode/src/services/model-providers-manager.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,28 @@ export class ModelProvidersManager {
427427
return this._get_tool_configs_from_settings('configurationsForPruneContext')
428428
}
429429

430+
public async get_default_prune_context_config(): Promise<
431+
ToolConfig | undefined
432+
> {
433+
await this._load_promise
434+
const default_config = this._get_default_tool_config_from_settings(
435+
'configurationsForPruneContext'
436+
)
437+
if (default_config) return default_config
438+
439+
const configs = await this.get_prune_context_tool_configs()
440+
if (configs.length == 1) return configs[0]
441+
442+
return undefined
443+
}
444+
445+
public async set_default_prune_context_config(config: ToolConfig | null) {
446+
await this._set_default_tool_config_in_settings(
447+
'configurationsForPruneContext',
448+
config
449+
)
450+
}
451+
430452
public async save_prune_context_tool_configs(configs: PruneContextConfigs) {
431453
await this._save_tool_configs_to_settings(
432454
'configurationsForPruneContext',

‎packages/vscode/src/views/i18n/translations.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const translations = {
1010
'settings.sidebar.edit-context': 'Edit Context',
1111
'settings.sidebar.code-completions': 'Code Completions',
1212
'settings.sidebar.intelligent-update': 'Intelligent Update',
13+
'settings.sidebar.prune-context': 'Prune Context',
1314
'settings.sidebar.commit-messages': 'Commit Messages'
1415
},
1516
pl: {

‎packages/vscode/src/views/panel/backend/message-handlers/handle-at-sign-quick-pick/handle-at-sign-quick-pick.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,15 @@ export const handle_at_sign_quick_pick = async (
279279
? panel_provider.web_prompt_type
280280
: panel_provider.api_prompt_type
281281
if (mode == 'ask') {
282-
current_text = panel_provider.ask_instructions
282+
current_text = panel_provider.ask_about_context_instructions
283283
} else if (mode == 'edit-context') {
284-
current_text = panel_provider.edit_instructions
284+
current_text = panel_provider.edit_context_instructions
285285
} else if (mode == 'no-context') {
286286
current_text = panel_provider.no_context_instructions
287287
} else if (mode == 'code-completions') {
288-
current_text = panel_provider.code_completion_instructions
288+
current_text = panel_provider.code_at_cursor_instructions
289+
} else if (mode == 'prune-context') {
290+
current_text = panel_provider.prune_context_instructions
289291
}
290292

291293
const is_after_at_sign = current_text

‎packages/vscode/src/views/panel/backend/message-handlers/handle-code-completion.ts‎

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ import { CodeCompletionMessage } from '@/views/panel/types/messages'
1818
import { apply_reasoning_effort } from '@/utils/apply-reasoning-effort'
1919
import { dictionary } from '@shared/constants/dictionary'
2020
import { randomUUID } from 'crypto'
21+
import { replace_selection_placeholder } from '../utils/replace-selection-symbol'
22+
import {
23+
replace_changes_symbol,
24+
replace_commit_symbol,
25+
replace_context_at_commit_symbol
26+
} from '../utils/replace-git-symbols'
27+
import { replace_saved_context_placeholder } from '@/utils/replace-saved-context-placeholder'
2128

2229
const get_code_completion_config = async (
2330
api_providers_manager: ModelProvidersManager,
@@ -262,7 +269,7 @@ export const handle_code_completion = async (
262269
const api_providers_manager = new ModelProvidersManager(
263270
panel_provider.context
264271
)
265-
const completion_instructions = panel_provider.code_completion_instructions
272+
const completion_instructions = panel_provider.code_at_cursor_instructions
266273

267274
const config_result = await get_code_completion_config(
268275
api_providers_manager,
@@ -344,6 +351,43 @@ export const handle_code_completion = async (
344351
position.character
345352
)
346353

354+
let processed_completion_instructions = completion_instructions
355+
356+
if (processed_completion_instructions.includes('#Selection')) {
357+
processed_completion_instructions = replace_selection_placeholder(
358+
processed_completion_instructions
359+
)
360+
}
361+
362+
if (processed_completion_instructions.includes('#Changes:')) {
363+
processed_completion_instructions = await replace_changes_symbol({
364+
instruction: processed_completion_instructions
365+
})
366+
}
367+
368+
if (processed_completion_instructions.includes('#Commit:')) {
369+
processed_completion_instructions = await replace_commit_symbol({
370+
instruction: processed_completion_instructions
371+
})
372+
}
373+
374+
if (processed_completion_instructions.includes('#ContextAtCommit:')) {
375+
processed_completion_instructions =
376+
await replace_context_at_commit_symbol({
377+
instruction: processed_completion_instructions,
378+
workspace_provider: panel_provider.workspace_provider
379+
})
380+
}
381+
382+
if (processed_completion_instructions.includes('#SavedContext:')) {
383+
processed_completion_instructions =
384+
await replace_saved_context_placeholder({
385+
instruction: processed_completion_instructions,
386+
context: panel_provider.context,
387+
workspace_provider: panel_provider.workspace_provider
388+
})
389+
}
390+
347391
const files_collector = new FilesCollector(
348392
panel_provider.workspace_provider,
349393
panel_provider.open_editors_provider
@@ -359,8 +403,8 @@ export const handle_code_completion = async (
359403
}
360404

361405
const content = `${main_instructions}\n${payload.before}${
362-
completion_instructions
363-
? `<missing_text>${completion_instructions}</missing_text>`
406+
processed_completion_instructions
407+
? `<missing_text>${processed_completion_instructions}</missing_text>`
364408
: '<missing_text>'
365409
}${payload.after}\n${main_instructions}`
366410

@@ -405,7 +449,7 @@ export const handle_code_completion = async (
405449
'codeWebChat.applyChatResponse',
406450
{
407451
response: result.response,
408-
raw_instructions: completion_instructions,
452+
raw_instructions: processed_completion_instructions,
409453
original_editor_state: {
410454
file_path: document.uri.fsPath,
411455
position: {

‎packages/vscode/src/views/panel/backend/message-handlers/handle-copy-prompt.ts‎

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,46 @@ export const handle_copy_prompt = async (params: {
8686
position.line,
8787
position.character
8888
)
89-
const missing_text_tag = final_instruction
90-
? `<missing_text>${final_instruction}</missing_text>`
89+
90+
let processed_completion_instructions = final_instruction
91+
92+
if (processed_completion_instructions.includes('#Selection')) {
93+
processed_completion_instructions = replace_selection_placeholder(
94+
processed_completion_instructions
95+
)
96+
}
97+
98+
if (processed_completion_instructions.includes('#Changes:')) {
99+
processed_completion_instructions = await replace_changes_symbol({
100+
instruction: processed_completion_instructions
101+
})
102+
}
103+
104+
if (processed_completion_instructions.includes('#Commit:')) {
105+
processed_completion_instructions = await replace_commit_symbol({
106+
instruction: processed_completion_instructions
107+
})
108+
}
109+
110+
if (processed_completion_instructions.includes('#ContextAtCommit:')) {
111+
processed_completion_instructions =
112+
await replace_context_at_commit_symbol({
113+
instruction: processed_completion_instructions,
114+
workspace_provider: params.panel_provider.workspace_provider
115+
})
116+
}
117+
118+
if (processed_completion_instructions.includes('#SavedContext:')) {
119+
processed_completion_instructions =
120+
await replace_saved_context_placeholder({
121+
instruction: processed_completion_instructions,
122+
context: params.panel_provider.context,
123+
workspace_provider: params.panel_provider.workspace_provider
124+
})
125+
}
126+
127+
const missing_text_tag = processed_completion_instructions
128+
? `<missing_text>${processed_completion_instructions}</missing_text>`
91129
: '<missing_text>'
92130

93131
const text = `${system_instructions}\n<files>\n${context_text}<file path="${relative_path}">\n<![CDATA[\n${text_before_cursor}${missing_text_tag}${text_after_cursor}\n]]>\n</file>\n</files>\n${system_instructions}`

‎packages/vscode/src/views/panel/backend/message-handlers/handle-edit-context.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ export const handle_edit_context = async (
289289
panel_provider.open_editors_provider
290290
)
291291

292-
let instructions = panel_provider.edit_instructions
292+
let instructions = panel_provider.edit_context_instructions
293293

294294
if (!instructions) {
295295
vscode.window.showWarningMessage(

‎packages/vscode/src/views/panel/backend/message-handlers/handle-get-instructions.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ export const handle_get_instructions = (
55
): void => {
66
panel_provider.send_message({
77
command: 'INSTRUCTIONS',
8-
ask: panel_provider.ask_instructions,
9-
edit_context: panel_provider.edit_instructions,
8+
ask: panel_provider.ask_about_context_instructions,
9+
edit_context: panel_provider.edit_context_instructions,
1010
no_context: panel_provider.no_context_instructions,
11-
code_completions: panel_provider.code_completion_instructions,
11+
code_completions: panel_provider.code_at_cursor_instructions,
1212
prune_context: panel_provider.prune_context_instructions
1313
})
1414
}

0 commit comments

Comments
 (0)