Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agent: make AgentWorkspaceDocuments more robust #4279

Merged
merged 2 commits into from
May 24, 2024
Merged

Conversation

olafurpg
Copy link
Member

The PR #4277 was a lesson that we have very brittle code around dealing with document synchronization. This PR is an attempt to improve code health by

  • Adding tests!
  • Being more rigorous with null handling
  • Making the code a bit easier to follow (hopefully)

Test plan

See new test suite.

@olafurpg olafurpg requested review from abeatrix and a team May 23, 2024 19:28
agent/src/agent.ts Outdated Show resolved Hide resolved
The PR #4277 was a lesson that
we have very brittle code around dealing with document synchronization.
This PR is an attempt to improve code health by

- Adding tests!
- Being more rigorous with null handling
- Making the code a bit easier to follow (hopefully)
Copy link
Contributor

@abeatrix abeatrix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

havent tested it locally but the code lgtm! Thanks for adding the tests too!

Copy link
Member Author

@olafurpg olafurpg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm planning to fix CODY-1829 : Handle null values in the protocol separately, where we add | null to the most important protocol properties.

@@ -44,33 +44,53 @@ export class AgentWorkspaceDocuments implements vscode_shim.WorkspaceDocuments {
} {
const fromCache = this.agentDocuments.get(document.underlying.uri)
if (!fromCache) {
return { document: new AgentTextDocument(document), contentChanges: [] }
const result = new AgentTextDocument(document)
this.agentDocuments.set(document.underlying.uri, result)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old flow was very weird, we populated the map at call site every single time, instead of doing it only once here.

@olafurpg
Copy link
Member Author

The integration tests caught a very critical regression (nice!). While fixing this, I saw that our implementation of vscode.TextEditor is not using a singleton instance for selection, which I'm fixing now.

@olafurpg
Copy link
Member Author

I will do a second round of review tomorrow since the additional diff ended up being quite large after your approval @abeatrix .

@olafurpg
Copy link
Member Author

Just to be 100% sure, I ran VS Code with the local diff

--- a/vscode/src/main.ts
+++ b/vscode/src/main.ts
@@ -753,6 +753,11 @@ const register = async (
         platform.extensionClient.provide({ enterpriseContextFactory }),
     ])
     disposables.push(extensionClientDispose)
+    for (const editor of vscode.window.visibleTextEditors) {
+        setInterval(() => {
+            console.log({ uri: editor.document.uri.toString(), text: editor.document.getText() })
+        }, 1000)
+    }

and confirmed that the text contents reflect the latest version as I make changes to the document even if I reuse the vscode.TextEditor instance.

While writing more tests, I discovered a surprising behavior that I
wasn't able to reuse instances of `vscode.TextEditor`. This commit fixes
this behavior.
}
viewColumn = vscode.ViewColumn.Active

// IMPORTANT(olafurpg): `edit` must be defined as a fat arrow. The tests
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue took me almost an hr to debug. Makes me wonder what other latent bugs we have caused by usage of class methods over property fat arrows.

@olafurpg olafurpg merged commit 0968610 into main May 24, 2024
19 checks passed
@olafurpg olafurpg deleted the olafurpg/nullish branch May 24, 2024 07:16
olafurpg added a commit to sourcegraph/jetbrains that referenced this pull request May 24, 2024
This bumps Cody to a commit that includes this PR here sourcegraph/cody#4279

This PR fixes a tricky issue related to how
`vscode.TextEditor.selection` works. Previously, the text editor
selection was a constant, it never updated to reflect the latest
selection of the document. This could have caused buggy behavior in
scenarios like this:

```ts
for (const editor of vscode.window.visibleTextEditors) {
  // editor.selection is correct
  await parseDocument(editor.document)
  // editor.selection is outdated because we received a
  // `textDocument/didChange` in the meantime
}
```
olafurpg added a commit to sourcegraph/jetbrains that referenced this pull request May 24, 2024
This bumps Cody to a commit that includes this PR here
sourcegraph/cody#4279

This PR fixes a tricky issue related to how
`vscode.TextEditor.selection` works. Previously, the text editor
selection was a constant, it never updated to reflect the latest
selection of the document. This could have caused buggy behavior in
scenarios like this:

```ts
for (const editor of vscode.window.visibleTextEditors) {
  // editor.selection is correct
  await parseDocument(editor.document)
  // editor.selection is outdated because we received a
  // `textDocument/didChange` in the meantime
}
```

## Test plan

n/a
<!-- All pull requests REQUIRE a test plan:
https://sourcegraph.com/docs/dev/background-information/testing_principles

Why does it matter?

These test plans are there to demonstrate that are following industry
standards which are important or critical for our customers.
They might be read by customers or an auditor. There are meant be simple
and easy to read. Simply explain what you did to ensure
your changes are correct!

Here are a non exhaustive list of test plan examples to help you:

- Making changes on a given feature or component:
- "Covered by existing tests" or "CI" for the shortest possible plan if
there is zero ambiguity
  - "Added new tests"
- "Manually tested" (if non trivial, share some output, logs, or
screenshot)
- Updating docs:
  - "previewed locally"
  - share a screenshot if you want to be thorough
- Updating deps, that would typically fail immediately in CI if
incorrect
  - "CI"
  - "locally tested"
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants