Skip to content

Commit 450b50d

Browse files
committed
Refactor skill symbol replacement to extract definitions once and reference them throughout prompts
1 parent 9a03b9f commit 450b50d

8 files changed

Lines changed: 67 additions & 25 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Code Web Chat is a free and open-source AI coding toolkit. You can use CWC in **
3535
With its focus on context engineering, CWC proposes a non-agentic workflow, where all the necessary for the task files, includnig useful examples, are picked with engineer's intent. Such guided model is easy to prompt and as accurate as it can get. It's a perfect companion for all kinds of coding tasks; from mass renamings to features.
3636

3737
> [!TIP]
38-
> Feeling lost in the codebase? Pick context roughly, switch prompt type to _Prune context_ and ask AI for help narrowing it down.
38+
> Feeling lost in the codebase? Pick context roughly, switch prompt type to _Prune context_, include your task and AI will help narrowing it down to reasonable size.
3939
4040
When pair-programming with Code Web Chat you foster codebase understanding, iterate on changes easier to review, and enter the flow state like in the good old days!
4141

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ export const handle_code_completion = async (
353353
)
354354

355355
let processed_completion_instructions = completion_instructions
356+
let skill_definitions = ''
356357

357358
if (processed_completion_instructions.includes('#Selection')) {
358359
processed_completion_instructions = replace_selection_placeholder(
@@ -390,9 +391,11 @@ export const handle_code_completion = async (
390391
}
391392

392393
if (processed_completion_instructions.includes('#Skill:')) {
393-
processed_completion_instructions = await replace_skill_symbol({
394+
const result = await replace_skill_symbol({
394395
instruction: processed_completion_instructions
395396
})
397+
processed_completion_instructions = result.instruction
398+
skill_definitions = result.skill_definitions
396399
}
397400

398401
const files_collector = new FilesCollector(
@@ -409,7 +412,7 @@ export const handle_code_completion = async (
409412
after: `${text_after_cursor}\n]]>\n</file>\n</files>`
410413
}
411414

412-
const content = `${main_instructions}\n${payload.before}${
415+
const content = `${main_instructions}\n${skill_definitions}${payload.before}${
413416
processed_completion_instructions
414417
? `<missing_text>${processed_completion_instructions}</missing_text>`
415418
: '<missing_text>'

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export const handle_copy_prompt = async (params: {
9090
)
9191

9292
let processed_completion_instructions = final_instruction
93+
let skill_definitions = ''
9394

9495
if (processed_completion_instructions.includes('#Selection')) {
9596
processed_completion_instructions = replace_selection_placeholder(
@@ -127,16 +128,18 @@ export const handle_copy_prompt = async (params: {
127128
}
128129

129130
if (processed_completion_instructions.includes('#Skill:')) {
130-
processed_completion_instructions = await replace_skill_symbol({
131+
const result = await replace_skill_symbol({
131132
instruction: processed_completion_instructions
132133
})
134+
processed_completion_instructions = result.instruction
135+
skill_definitions = result.skill_definitions
133136
}
134137

135138
const missing_text_tag = processed_completion_instructions
136139
? `<missing_text>${processed_completion_instructions}</missing_text>`
137140
: '<missing_text>'
138141

139-
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}`
142+
const text = `${system_instructions}\n${skill_definitions}<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}`
140143

141144
vscode.env.clipboard.writeText(text.trim())
142145
} else if (!is_in_code_completions_prompt_type) {
@@ -154,6 +157,7 @@ export const handle_copy_prompt = async (params: {
154157
const instructions = replace_selection_placeholder(final_instruction)
155158

156159
let processed_instructions = instructions
160+
let skill_definitions = ''
157161

158162
if (processed_instructions.includes('#Changes:')) {
159163
processed_instructions = await replace_changes_symbol({
@@ -183,9 +187,11 @@ export const handle_copy_prompt = async (params: {
183187
}
184188

185189
if (processed_instructions.includes('#Skill:')) {
186-
processed_instructions = await replace_skill_symbol({
190+
const result = await replace_skill_symbol({
187191
instruction: processed_instructions
188192
})
193+
processed_instructions = result.instruction
194+
skill_definitions = result.skill_definitions
189195
}
190196

191197
let system_instructions_xml = ''
@@ -226,12 +232,12 @@ export const handle_copy_prompt = async (params: {
226232
const text = context_text
227233
? `${
228234
system_instructions_xml ? system_instructions_xml + '\n' : ''
229-
}<files>\n${context_text}</files>\n${
235+
}${skill_definitions}<files>\n${context_text}</files>\n${
230236
system_instructions_xml ? system_instructions_xml + '\n' : ''
231237
}${processed_instructions}`
232238
: `${
233239
system_instructions_xml ? system_instructions_xml + '\n' : ''
234-
}${processed_instructions}`
240+
}${skill_definitions}${processed_instructions}`
235241
vscode.env.clipboard.writeText(text.trim())
236242
} else {
237243
vscode.window.showWarningMessage(

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ export const handle_edit_context = async (
310310
}
311311

312312
let processed_instructions = instructions
313+
let skill_definitions = ''
313314

314315
if (processed_instructions.includes('#Changes:')) {
315316
processed_instructions = await replace_changes_symbol({
@@ -339,9 +340,11 @@ export const handle_edit_context = async (
339340
}
340341

341342
if (processed_instructions.includes('#Skill:')) {
342-
processed_instructions = await replace_skill_symbol({
343+
const result = await replace_skill_symbol({
343344
instruction: processed_instructions
344345
})
346+
processed_instructions = result.instruction
347+
skill_definitions = result.skill_definitions
345348
}
346349

347350
const is_prune_context = panel_provider.api_prompt_type == 'prune-context'
@@ -437,7 +440,7 @@ export const handle_edit_context = async (
437440

438441
const content = `${
439442
system_instructions_xml ? system_instructions_xml + '\n' : ''
440-
}${files}\n${
443+
}${skill_definitions}${files}\n${
441444
system_instructions_xml ? system_instructions_xml + '\n' : ''
442445
}${processed_instructions}`
443446

‎packages/vscode/src/views/panel/backend/message-handlers/handle-preview-preset.ts‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export const handle_preview_preset = async (
7070
config.get<string>('chatCodeCompletionsInstructions') || ''
7171

7272
let processed_completion_instructions = current_instructions
73+
let skill_definitions = ''
7374

7475
if (processed_completion_instructions.includes('#Selection')) {
7576
processed_completion_instructions = replace_selection_placeholder(
@@ -107,16 +108,18 @@ export const handle_preview_preset = async (
107108
}
108109

109110
if (processed_completion_instructions.includes('#Skill:')) {
110-
processed_completion_instructions = await replace_skill_symbol({
111+
const result = await replace_skill_symbol({
111112
instruction: processed_completion_instructions
112113
})
114+
processed_completion_instructions = result.instruction
115+
skill_definitions = result.skill_definitions
113116
}
114117

115118
const missing_text_tag = processed_completion_instructions
116119
? `<missing_text>${processed_completion_instructions}</missing_text>`
117120
: '<missing_text>'
118121

119-
text_to_send = `${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}`
122+
text_to_send = `${system_instructions}\n${skill_definitions}<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}`
120123
} else if (panel_provider.web_prompt_type != 'code-at-cursor') {
121124
let instructions = apply_preset_affixes_to_instruction({
122125
instruction: current_instructions,
@@ -143,6 +146,7 @@ export const handle_preview_preset = async (
143146
}
144147

145148
let processed_instructions = instructions
149+
let skill_definitions = ''
146150

147151
if (processed_instructions.includes('#Changes:')) {
148152
processed_instructions = await replace_changes_symbol({
@@ -172,9 +176,11 @@ export const handle_preview_preset = async (
172176
}
173177

174178
if (processed_instructions.includes('#Skill:')) {
175-
processed_instructions = await replace_skill_symbol({
179+
const result = await replace_skill_symbol({
176180
instruction: processed_instructions
177181
})
182+
processed_instructions = result.instruction
183+
skill_definitions = result.skill_definitions
178184
}
179185

180186
let system_instructions_xml = ''
@@ -202,12 +208,12 @@ export const handle_preview_preset = async (
202208
text_to_send = context_text
203209
? `${
204210
system_instructions_xml ? system_instructions_xml + '\n' : ''
205-
}<files>\n${context_text}</files>\n${
211+
}${skill_definitions}<files>\n${context_text}</files>\n${
206212
system_instructions_xml ? system_instructions_xml + '\n' : ''
207213
}${processed_instructions}`
208214
: `${
209215
system_instructions_xml ? system_instructions_xml + '\n' : ''
210-
}${processed_instructions}`
216+
}${skill_definitions}${processed_instructions}`
211217
} else {
212218
vscode.window.showWarningMessage(
213219
dictionary.warning_message

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ export const handle_prune_context = async (
302302
}
303303

304304
let processed_instructions = instructions
305+
let skill_definitions = ''
305306

306307
if (processed_instructions.includes('#Changes:')) {
307308
processed_instructions = await replace_changes_symbol({
@@ -331,9 +332,11 @@ export const handle_prune_context = async (
331332
}
332333

333334
if (processed_instructions.includes('#Skill:')) {
334-
processed_instructions = await replace_skill_symbol({
335+
const result = await replace_skill_symbol({
335336
instruction: processed_instructions
336337
})
338+
processed_instructions = result.instruction
339+
skill_definitions = result.skill_definitions
337340
}
338341

339342
const collected_files = await files_collector.collect_files({
@@ -398,7 +401,7 @@ export const handle_prune_context = async (
398401
config_prune_instructions_prefix || prune_context_instructions_prefix
399402
const system_instructions_xml = `${instructions_to_use}\n${prune_context_format}`
400403

401-
const content = `${system_instructions_xml}\n${files}\n${system_instructions_xml}\n${processed_instructions}`
404+
const content = `${system_instructions_xml}\n${skill_definitions}${files}\n${system_instructions_xml}\n${processed_instructions}`
402405

403406
const messages = [
404407
{

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ export const handle_send_prompt = async (params: {
117117
params.panel_provider.code_at_cursor_instructions
118118

119119
let processed_completion_instructions = completion_instructions
120+
let skill_definitions = ''
120121

121122
if (processed_completion_instructions.includes('#Selection')) {
122123
processed_completion_instructions = replace_selection_placeholder(
@@ -154,9 +155,11 @@ export const handle_send_prompt = async (params: {
154155
}
155156

156157
if (processed_completion_instructions.includes('#Skill:')) {
157-
processed_completion_instructions = await replace_skill_symbol({
158+
const result = await replace_skill_symbol({
158159
instruction: processed_completion_instructions
159160
})
161+
processed_completion_instructions = result.instruction
162+
skill_definitions = result.skill_definitions
160163
}
161164

162165
const context_text = await files_collector.collect_files({
@@ -176,7 +179,7 @@ export const handle_send_prompt = async (params: {
176179
after: `${text_after_cursor}\n]]>\n</file>\n</files>`
177180
}
178181

179-
const text = `${main_instructions}\n${payload.before}${
182+
const text = `${main_instructions}\n${skill_definitions}${payload.before}${
180183
processed_completion_instructions
181184
? `<missing_text>${processed_completion_instructions}</missing_text>`
182185
: '<missing_text>'
@@ -220,6 +223,7 @@ export const handle_send_prompt = async (params: {
220223
}
221224

222225
let processed_instructions = instructions
226+
let skill_definitions = ''
223227
if (processed_instructions.includes('#Changes:')) {
224228
processed_instructions = await replace_changes_symbol({
225229
instruction: processed_instructions
@@ -247,9 +251,11 @@ export const handle_send_prompt = async (params: {
247251
}
248252

249253
if (processed_instructions.includes('#Skill:')) {
250-
processed_instructions = await replace_skill_symbol({
254+
const result = await replace_skill_symbol({
251255
instruction: processed_instructions
252256
})
257+
processed_instructions = result.instruction
258+
skill_definitions = result.skill_definitions
253259
}
254260

255261
let system_instructions_xml = ''
@@ -287,12 +293,12 @@ export const handle_send_prompt = async (params: {
287293
text: context_text
288294
? `${
289295
system_instructions_xml ? system_instructions_xml + '\n' : ''
290-
}<files>\n${context_text}</files>\n${
296+
}${skill_definitions}<files>\n${context_text}</files>\n${
291297
system_instructions_xml ? system_instructions_xml + '\n' : ''
292298
}${processed_instructions}`
293299
: `${
294300
system_instructions_xml ? system_instructions_xml + '\n' : ''
295-
}${processed_instructions}`,
301+
}${skill_definitions}${processed_instructions}`,
296302
preset_name,
297303
raw_instructions: current_instructions,
298304
prompt_type: params.panel_provider.web_prompt_type,

‎packages/vscode/src/views/panel/backend/utils/replace-skill-symbol.ts‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@ import {
88

99
export const replace_skill_symbol = async (params: {
1010
instruction: string
11-
}): Promise<string> => {
11+
}): Promise<{ instruction: string; skill_definitions: string }> => {
1212
const regex = /#Skill:([^:]+):([^:]+(?::[^:]+)?):([^\s,;:.!?]+)/g
13+
let skill_definitions = ''
14+
const processed_skills = new Set<string>()
1315

14-
return params.instruction.replace(
16+
const instruction = params.instruction.replace(
1517
regex,
1618
(_, agent_name, _repo_id, skill_name) => {
19+
const key = `${agent_name}:${skill_name}`
20+
const reference = `<skill name="${skill_name}" />`
21+
22+
if (processed_skills.has(key)) {
23+
return reference
24+
}
25+
1726
const agent = agents[agent_name]
1827
if (!agent) {
1928
Logger.warn({
@@ -34,6 +43,8 @@ export const replace_skill_symbol = async (params: {
3443
return ''
3544
}
3645

46+
processed_skills.add(key)
47+
3748
let skill_content = `<skill name="${skill_name}">\n`
3849

3950
try {
@@ -66,7 +77,11 @@ export const replace_skill_symbol = async (params: {
6677
}
6778

6879
skill_content += `</skill>`
69-
return skill_content
80+
skill_definitions += skill_content + '\n'
81+
82+
return reference
7083
}
7184
)
85+
86+
return { instruction, skill_definitions }
7287
}

0 commit comments

Comments
 (0)