Skip to content

Commit 425087c

Browse files
committed
Add fallback full file edit format and retry logic for intelligent updates
- sometimes model returns invalid search-replace blocks, in should re-send using intelligent_update_fallback_edit_format_instructions - when called with fallback edit format, on chunk should provide param 'using fallback'. Only when using fallback should report progress percentage (as only with fallback we can estimate it by comparing to the full length)
1 parent 6510a4a commit 425087c

4 files changed

Lines changed: 64 additions & 21 deletions

File tree

‎apps/editor/src/constants/instructions.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Find correct replacement text for the <missing_text> symbol.`
2828
export const intelligent_update_task_instructions =
2929
'Refactor the file according to the attached changes without explanations or any other text.'
3030

31-
export const intelligent_update_edit_format_instructions = `Output a markdown code block showing the original and updated code snippets with Git-style merge conflict syntax. Example:
31+
export const intelligent_update_edit_format_instructions = `Print a markdown code block showing the original and updated code snippets with Git-style merge conflict syntax. Example:
3232
3333
\`\`\`python
3434
<<<<<<< SEARCH
@@ -45,6 +45,8 @@ WISHES = "Have a nice day!"
4545
>>>>>>> REPLACE
4646
\`\`\``
4747

48+
export const intelligent_update_fallback_edit_format_instructions = `Print the updated file in FULL.`
49+
4850
export const commit_message_instructions =
4951
"Write a brief and precise summary for the changes, limited to a single sentence. Because the summary will be used for a commit message, don't use any markdown formatting and don't include a trailing dot. Use an imperative tone to ensure clarity and focus on the primary change or purpose."
5052

‎apps/editor/src/views/prompt/backend/message-handlers/handle-fix-all-failed-files.ts‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,13 @@ export const handle_fix_all_failed_files = async (params: {
165165
const original_file_size = file_state.content.length
166166
const estimated_total_tokens = Math.ceil(original_file_size / 4)
167167

168-
const on_chunk = (tokens_per_second: number, total_tokens: number) => {
169-
let progress = 0
170-
if (estimated_total_tokens > 0) {
168+
const on_chunk = (
169+
tokens_per_second: number,
170+
total_tokens: number,
171+
using_fallback: boolean
172+
) => {
173+
let progress: number | undefined
174+
if (using_fallback && estimated_total_tokens > 0) {
171175
progress = Math.min(
172176
Math.round((total_tokens / estimated_total_tokens) * 100),
173177
100

‎apps/editor/src/views/prompt/backend/message-handlers/handle-intelligent-update-file-in-preview.ts‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,13 @@ export const handle_intelligent_update_file_in_preview = async (
154154
const original_file_size = file_state.content.length
155155
const estimated_total_tokens = Math.ceil(original_file_size / 4)
156156

157-
const on_chunk = (tokens_per_second: number, total_tokens: number) => {
158-
let progress = 0
159-
if (estimated_total_tokens > 0) {
157+
const on_chunk = (
158+
tokens_per_second: number,
159+
total_tokens: number,
160+
using_fallback: boolean
161+
) => {
162+
let progress: number | undefined
163+
if (using_fallback && estimated_total_tokens > 0) {
160164
progress = Math.min(
161165
Math.round((total_tokens / estimated_total_tokens) * 100),
162166
100

‎apps/editor/src/views/prompt/backend/message-handlers/utils/intelligent-update-utils.ts‎

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import { send_llm_message } from '@/utils/send-llm-message'
1111
import { cleanup_api_response } from '@/utils/cleanup-api-response'
1212
import {
1313
intelligent_update_task_instructions,
14-
intelligent_update_edit_format_instructions
14+
intelligent_update_edit_format_instructions,
15+
intelligent_update_fallback_edit_format_instructions
1516
} from '@/constants/instructions'
1617
import { dictionary } from '@shared/constants/dictionary'
1718
import { apply_reasoning_effort } from '@/utils/apply-reasoning-effort'
@@ -112,15 +113,28 @@ export const process_file = async (params: {
112113
file_content: string
113114
instruction: string
114115
abort_signal?: AbortSignal
115-
on_chunk?: (tokens_per_second: number, total_tokens: number) => void
116+
on_chunk?: (
117+
tokens_per_second: number,
118+
total_tokens: number,
119+
using_fallback: boolean
120+
) => void
116121
on_thinking_chunk?: (text: string) => void
122+
use_fallback_edit_format?: boolean
117123
}): Promise<string> => {
118124
Logger.info({
119125
function_name: 'process_file',
120126
message: 'start',
121-
data: { file_path: params.file_path }
127+
data: {
128+
file_path: params.file_path,
129+
use_fallback_format: params.use_fallback_edit_format
130+
}
122131
})
123-
const content = `# Task\n\n${intelligent_update_task_instructions}\n\n# File\n\n${params.file_content}\n\n# Output formatting\n\n${intelligent_update_edit_format_instructions}\n\n# Task\n\n${intelligent_update_task_instructions}\n\n# Changes\n\n${params.instruction}`
132+
133+
const edit_format_instructions = params.use_fallback_edit_format
134+
? intelligent_update_fallback_edit_format_instructions
135+
: intelligent_update_edit_format_instructions
136+
137+
const content = `# Task\n\n${intelligent_update_task_instructions}\n\n# File\n\n${params.file_content}\n\n# Output formatting\n\n${edit_format_instructions}\n\n# Task\n\n${intelligent_update_task_instructions}\n\n# Changes\n\n${params.instruction}`
124138

125139
const messages = [
126140
{
@@ -146,7 +160,14 @@ export const process_file = async (params: {
146160
api_key: params.api_key,
147161
body,
148162
abort_signal: params.abort_signal,
149-
on_chunk: params.on_chunk,
163+
on_chunk: params.on_chunk
164+
? (tokens_per_second, total_tokens) =>
165+
params.on_chunk!(
166+
tokens_per_second,
167+
total_tokens,
168+
!!params.use_fallback_edit_format
169+
)
170+
: undefined,
150171
on_thinking_chunk: params.on_thinking_chunk,
151172
rethrow_error: true
152173
})
@@ -166,15 +187,27 @@ export const process_file = async (params: {
166187
})
167188

168189
let final_content = cleaned_content
169-
if (
170-
cleaned_content.includes('<<<<<<<') &&
171-
cleaned_content.includes('=======') &&
172-
cleaned_content.includes('>>>>>>>')
173-
) {
174-
final_content = apply_search_replace_to_content({
175-
original_content: params.file_content,
176-
segments: parse_search_replace_segments(cleaned_content)
177-
})
190+
if (!params.use_fallback_edit_format) {
191+
try {
192+
final_content = apply_search_replace_to_content({
193+
original_content: params.file_content,
194+
segments: parse_search_replace_segments(cleaned_content)
195+
})
196+
} catch (error: any) {
197+
Logger.warn({
198+
function_name: 'process_file',
199+
message:
200+
'Failed to apply search-replace blocks, retrying with fallback edit format',
201+
data: { error, file_path: params.file_path }
202+
})
203+
204+
if (!params.abort_signal?.aborted) {
205+
return await process_file({
206+
...params,
207+
use_fallback_edit_format: true
208+
})
209+
}
210+
}
178211
}
179212

180213
Logger.info({

0 commit comments

Comments
 (0)