-
Notifications
You must be signed in to change notification settings - Fork 83
feat: port fs related tools from VSC. #894
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
Conversation
|
I get you were just porting, but any idea why we have separate fsRead/Write files? I would have assumed it is better to have a single module with all FS related utils. In this case a wrapper over the basic fs module, but with some more complex utilies.
Mocking the filesystem for tests seems like a code smell, there isn't a strong reason to not just test against the filesystem. So I'm in agreement with your decision to not mock the filesystem and just have them use the TestFolder util.
What do you mean by this? |
| throw new Error(`Path: "${this.fsPath}" does not exist or cannot be accessed.`) | ||
| } | ||
| } catch (err) { | ||
| throw new Error(`Path: "${this.fsPath}" does not exist or cannot be accessed. (${err})`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does workspace.fs come from? Assuming it is well written, it will already have a usable error code and message. So something like this seems redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that this is injected depending on the environment. For the common (non-web) use case, I believe its implemented here: https://github.com/aws/language-server-runtimes/blob/b31f851d7f16d290f29c93281d6646b50820b7fb/runtimes/runtimes/standalone.ts#L174 which doesn't have any error reporting or logging beyond the build in nodefs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. This is also why you get the linting errors. We try to avoid using Node platform specific filesystem libraries to make portability easier. If that is not possible in your use case, let's see if we can update workspace.fs to meet your requirements, or relax the linting rules for these specific tools.
Just know that if we do the latter, these tools will not be portable from one environment to the next, and that needs to be documented somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored it to avoid using these modules. I believe that relaxing the lint rules for specific tools could be problematic because it ignores indirect dependencies. For example, we use sanitize from @aws/lsp-core which requires these modules. It does have a note at the top of the file, but lmk if I can document this elsewhere as well.
| } | ||
|
|
||
| static async create() { | ||
| const tempDir = path.join( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: A future optimization you could do is delete the root folder at the start/end of the entire test run (if easily doable). This will handle any mistakes from tests failing to clean up properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree. I noticed the VS Code implementation does this, and it would be a great feature. We do this by wrapping all the tests with our own test runner in VSC, but I don't see similar logic here yet, so this change would require some ground work.
Not entirely sure why they made this design decision. My best guess is that they want to enforce the paradigm of each tool having a singular purpose. Separating it also seems like an easy way to manage granular access to the filesystem by only adding certain tools to an agent.
I agree. The number of filesystem quirks we've observed in VSC shows how easily bugs can slip through (especially on windows).
Added a link to the description. I didn't see any testing utilities other than this |
I believe its because agentic chat knows how to use tools is by looking up descriptions in the the tool_index.json. The description/input for fsRead/fsWrite are different, so it would be harder to merge them together |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably also call out what commit you copied from in the description just so its easy to find later if you're looking at PR's
| this.logging.log(`Validation succeeded for path: ${this.fsPath}`) | ||
| } | ||
|
|
||
| public queueDescription(updates: Writable): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this meant to update the chat panel with progress on the tool execution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It currently does not, but that seems like a useful feature. Original implementation lives here. I see an example of how this could be done in Flare here, which would require changes to the runtime to add something like this for file read progress. If that sounds like a good example to base this on I can mark it as a follow-up to add this for file read and write progress.
| private readonly logging: Features['logging'] | ||
| private readonly workspace: Features['workspace'] | ||
|
|
||
| constructor(features: Pick<Features, 'workspace' | 'logging'>, params: FsReadParams) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Pick, is there a reason to scope down the parameter type here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention was require as little as possible from the caller. However, this does force them to explicitly scope Features down so I changed it to Pick<Features, 'workspace' | 'logging'> & Partial<Features> to avoid this step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. This would work or passing in the Feature that you need explicitly. Glad you're not taking a dependency on the whole Features set to avoid coupling everything together.
In order to implement the tool invocation I think you can remove the params here, since in the Agent feature the tool creation is separate from the invocation: https://github.com/aws/language-server-runtimes/tree/main/runtimes#agent-tools
That can happen once we integrate the tools into qChatServer.ts.
ace27f7 to
9f72fc5
Compare
core/aws-lsp-core/src/index.ts
Outdated
| export * as timeoutUtils from './util/timeoutUtils' | ||
| export * from './util/awsError' | ||
| export * from './base/index' | ||
| export * from './test/testFolder' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it not likely that all these non-aliased * exports will eventually conflict? And that would then require quasi-namespacing. Instead of quasi-namespacing, we can solve the problem easily by aliasing, like this:
| export * from './test/testFolder' | |
| export * as testFolder from './test/testFolder' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw is it intentional/unavoidable that test/testFolder is part of the core (non-text) index.ts ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not see an existing location for test utilities, and this seemed like the most reasonable. The closest thing I saw was this in runtimes, but having to bump runtimes version every time you edit a test utility seemed excessive. If there is a more appropriate place to put this lmk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I imagine that it is unlikely TestFolder is reused, but I understand this is good practice going forward.
|
|
||
| /** | ||
| * Interface for working with temporary files. | ||
| * Simplified port of https://github.com/aws/aws-toolkit-vscode/blob/16477869525fb79f8dc82cb22e301aaea9c5e0c6/packages/core/src/test/testUtil.ts#L77 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for now, this kind of precise cross-reference will help a lot, in each of these util files.
7d7ccb1 to
49f47b1
Compare
| return normalizeSeparator(path.normalize(p)) | ||
| } | ||
|
|
||
| export function sanitize(inputPath: string): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In aws-toolkit-vscode this santize() was added recently, but I don't get why it was added: aws/aws-toolkit-vscode#6840 (comment)
Why is this needed instead of our normalize() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like they do slightly different things that definitely overlap with normalize. For example, normalize doesn't remove white space or expand ~. I agree they definitely overlap and could potentially be refactored to make this more clear.
c7f70ae to
4c02f9f
Compare
|
One of the commits - a merge from |
|
I was planning to squash-merge since the individual commits are not important. Lmk if rebasing is preferred. |
Problem
Some agent tools were implemented in the VSC codebase. However, agentic chat is moving to use Flare implementation, so these tools should live here instead.
relevant: aws/language-server-runtimes#393
Solution
Testing
TestFolder. This is a simplified version of a this utility from the VSC codebase.Future Work
^0.2.49, and add the tools to the agentic chat server hereLicense
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.