Idea: replace edit tool input string with formatted code to gaslight the model to think it generated formatted code and have less edit failures #1674

Closed
opened 2026-02-16 17:32:06 -05:00 by yindo · 7 comments
Owner

Originally created by @remorses on GitHub (Sep 10, 2025).

Originally assigned to: @thdxr on GitHub.

Currently when the LLM edits a file opencode will format the result and pass the formatted code in the tool output

This is nice because the code is always formatted after every tool call, the problem is that the LLM still thinks the edit it generated was the one applied. So subsequent edits will easily fail because the model will pass a non formatted search string for edits.

This could be done by modifying the messages in the next request to format the tool inputs. This way the LLM will think it generated formatted code the first time and not get confused. This will probably help with following edits too because the LLM will follow the same formatting style.

This could decrease a bit tokens caching but should not be a big problem given only the last tool is modified so you only lose a bit of cached tokens, the ones for the edit tool input.

Possible implementation

The simplest method would be to insert random string comments at start and end of the snippet, then use them later to extract the formatted string from the formatted file and save the formatted file discarding the random string separators.

Another way is to use the AST of TreeSitter and compute an Id for the token on the start and end positions of the tool input. Then find the same token with the same id in the formatted code, find the position and return that portion of the string. For computing the id you can concatenate each parent node type and content up until the token on the start and end positions.

Originally created by @remorses on GitHub (Sep 10, 2025). Originally assigned to: @thdxr on GitHub. Currently when the LLM edits a file opencode will format the result and pass the formatted code in the tool output This is nice because the code is always formatted after every tool call, the problem is that the LLM still thinks the edit it generated was the one applied. So subsequent edits will easily fail because the model will pass a non formatted search string for edits. This could be done by modifying the messages in the next request to format the tool inputs. This way the LLM will think it generated formatted code the first time and not get confused. This will probably help with following edits too because the LLM will follow the same formatting style. This could decrease a bit tokens caching but should not be a big problem given only the last tool is modified so you only lose a bit of cached tokens, the ones for the edit tool input. ## Possible implementation The simplest method would be to insert random string comments at start and end of the snippet, then use them later to extract the formatted string from the formatted file and save the formatted file discarding the random string separators. Another way is to use the AST of TreeSitter and compute an Id for the token on the start and end positions of the tool input. Then find the same token with the same id in the formatted code, find the position and return that portion of the string. For computing the id you can concatenate each parent node type and content up until the token on the start and end positions.
yindo closed this issue 2026-02-16 17:32:06 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Sep 10, 2025):

This issue might be a duplicate of existing issues. Please check:

  • #2433: Discusses problems with the BlockAnchorReplacer causing edit tool failures and syntax errors due to incorrect string replacements
  • #1457: Reports every single edit failing on the first attempt, similar to the formatting/search string mismatch problem described
  • #1357: Documents constant failures with Write/Edit tools where models seem incapable of producing compatible output
  • #2255: Shows edit tools returning errors despite successful operations, indicating tool feedback/state confusion

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Sep 10, 2025): This issue might be a duplicate of existing issues. Please check: - #2433: Discusses problems with the BlockAnchorReplacer causing edit tool failures and syntax errors due to incorrect string replacements - #1457: Reports every single edit failing on the first attempt, similar to the formatting/search string mismatch problem described - #1357: Documents constant failures with Write/Edit tools where models seem incapable of producing compatible output - #2255: Shows edit tools returning errors despite successful operations, indicating tool feedback/state confusion Feel free to ignore if none of these address your specific case.
Author
Owner

@rekram1-node commented on GitHub (Sep 10, 2025):

interesting

@rekram1-node commented on GitHub (Sep 10, 2025): interesting
Author
Owner

@remorses commented on GitHub (Sep 10, 2025):

This can be done with ai sdk prepareStep. would you like a PR?

@remorses commented on GitHub (Sep 10, 2025): This can be done with ai sdk prepareStep. would you like a PR?
Author
Owner

@rekram1-node commented on GitHub (Sep 10, 2025):

it's up to Dax if he wants the implementation or not (not me) but you can try your hand at a PR

@rekram1-node commented on GitHub (Sep 10, 2025): it's up to Dax if he wants the implementation or not (not me) but you can try your hand at a PR
Author
Owner

@remorses commented on GitHub (Sep 10, 2025):

Working on a PR right now for this @thdxr

@remorses commented on GitHub (Sep 10, 2025): Working on a PR right now for this @thdxr
Author
Owner

@remorses commented on GitHub (Sep 10, 2025):

Edit: we are so back. I found a way to implement this using a diff algorithm

Thinking more about this issue I don't thing it's a good idea

Problems

  • Using the magic comments trick will not work when the LLM replacement string starts or end at a position where the comment would be invalid
  • Using the treesitter approach could theoretically work but it will take time and custom code for each language.

For the time being https://github.com/sst/opencode/issues/2535 is a better solution to this problem

@remorses commented on GitHub (Sep 10, 2025): Edit: we are so back. I found a way to implement this using a diff algorithm Thinking more about this issue I don't thing it's a good idea Problems - Using the magic comments trick will not work when the LLM replacement string starts or end at a position where the comment would be invalid - Using the treesitter approach could theoretically work but it will take time and custom code for each language. For the time being https://github.com/sst/opencode/issues/2535 is a better solution to this problem
Author
Owner

@rekram1-node commented on GitHub (Dec 27, 2025):

[automated] Closing due to 90+ days of inactivity. Feel free to reopen if you still need this!

@rekram1-node commented on GitHub (Dec 27, 2025): [automated] Closing due to 90+ days of inactivity. Feel free to reopen if you still need this!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#1674