The detail I want to underline is find_symbol returning a 1-based position "specifically so that position can be fed straight into goto_definition". Models really are bad at deriving line/column from a text dump, and making the cheap tool emit coordinates for the expensive one is the cleanest fix I have seen written down. One more property of tree-sitter worth naming for this use case: its error recovery. Mid-edit files parse to a tree with error nodes instead of failing, so find_symbol keeps working while the agent is halfway through a refactor, exactly when the language server starts complaining. On your open question about invalidation: pyright republishes diagnostics on didChange without a didOpen round trip, so a thin didChange with a debounce may get you fresh diagnostics cheaper than reopening files. Did you consider caching find_references results, or is the staleness risk after edits too high to bother?