fix(ai): route /fix-code to the fence fixer instead of the formatter - #314
Merged
petertzy merged 1 commit intoOct 2, 2026
Merged
Conversation
build_ai_automation_fallback() dispatches on keywords, and the 'Format and Fix
Code Blocks' template ships the prompt 'Format Markdown code fences and fix
common fence syntax issues.' None of ('format code', 'code block', 'correct
syntax', 'fix code') appear in it -- 'format code' is not a substring of
'format markdown code', and the prompt says 'code fences' / 'fence syntax',
not 'code block'. It fell through to the generic formatter.
The existing test passed the literal '/fix-code', which the slash table maps
to 'format code blocks and correct syntax' and so does match. The real UI
never sends that: useSlashCommands.ts looks the template up by id and submits
template.prompt verbatim, so the shipped wording is exactly what arrives.
Result: an unbalanced fence stayed unbalanced, because the formatter cannot
close one, and the command still reported success. The branch's own
selection-required guard was skipped too.
Add 'code fence' and 'fence syntax'. Branch order already puts the code fixer
ahead of the formatter.
Adds 5 cases incl. a parametrised check that every shipped template reaches
its own handler; verified 4 fail against the unmodified ai_logic.py.
harsh-thakkar7
force-pushed
the
fix/fix-code-slash-dispatch
branch
from
October 2, 2026 09:52
7e0ac0e to
c54c90e
Compare
Owner
|
Reviewed and verified locally. The fix correctly routes the shipped fix_code_blocks template prompt to the fence fixer by recognizing the actual “code fences” and “fence syntax” wording. The added tests cover unbalanced fences, balanced fences, the selection guard, all shipped template dispatch paths, and ensure /format still uses the formatter. All 270 backend tests pass, and Ruff checks and formatting checks are clean. This change is focused and safe to merge. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/fix-coderan the wrong tool. Instead of fixing code fences it applied theplain Markdown formatter, so an unbalanced fence stayed unbalanced.
Root cause
build_ai_automation_fallback()dispatches on keywords in the prompt. The"Format and Fix Code Blocks" template ships this prompt:
and the code-block branch matched on:
None of those substrings appear in the shipped prompt.
"format code"is notin
"format markdown code", and the prompt says "code fences" and "fencesyntax", not "code block". So it fell through to the generic formatter branch
below.
This is invisible to the existing test because
tests/test_ai_automation_logic.pypasses the literal string
"/fix-code", which the slash-command table maps to"format code blocks and correct syntax"— that does match. The real UI sendssomething else.
The real UI sends the template prompt, not the slash name
useSlashCommands.tslooks each template up by id and submitstemplate.prompt:So
/fix-codealways arrived at the backend as the template's wording — the onestring that matched no keyword. Confirmed by dispatching every shipped
template prompt:
format_selectionformat_rulesformat_rulesgenerate_tocgenerate_tocgenerate_tocgenerate_summarygenerate_summarygenerate_summaryfix_code_blocksformat_rulesfix_code_blocksThat table is now asserted by a test, so a template prompt that stops matching
its own handler fails CI.
Effect
For an unbalanced fence:
The formatter cannot close a fence, so the command reported success and changed
nothing. It also skipped the branch's own guard, so
/fix-codewith noselection silently reformatted the whole document instead of asking the user to
select the block.
Aggravates the fence-corruption problem in the sibling PR: with the wrong handler
selected, a code selection was dragged through the formatter that rewrites
shebangs.
Changes
backend/ai_logic.py— two keywords added to the code-block branch:Nothing else changed. The branch order already puts the code fixer ahead of the
formatter, so this only claims prompts that the formatter was never going to
handle correctly anyway.
Testing
tests/test_ai_automation_logic.py::TestTemplatePromptsReachTheirOwnHandler, 5cases driving the real shipped prompts through
build_ai_automation_fallback():fix_code_blocksreaches the fence fixer and closes an unbalanced fenceselection_required_for_code_fixguard with no selectionfails if the template set changes)
/formatstill uses the formatter and is not diverted into the fence fixerVerified all 4 behavioural assertions fail against the unmodified
ai_logic.py.Verification
pytest— 200 passed (was 195 onmain; this PR adds 5)ruff check/ruff format --checkon changed files — cleannpm test— 23 passed, unchangednpm run lint/npm run build— clean