Cody standalone web app prototype and dev helper
The web/ subdir implements a standalone web app for Cody for development purposes only. This is useful:
- When developing changes to Cody's chat webview, because you get instant reloads (vs. the VS Code extension restart cycle). If you are working on changes that interact deeply with VS Code, the
web/shim might be insufficient.- As a followup, we can even auto-deploy this web app to try out chat webview diffs on PR branches.
- For prototyping how we can get the new agent architecture of Cody into Sourcegraph itself (the https://github.com/sourcegraph/sourcegraph repository).
The web app runs the Cody agent in a Web Worker, with some noop shims. Known issues:
- @-mentions of files use dummy data, not an actual list of files
- Some UI glitches occur (such as multiple copy/insert buttons being added after code blocks in chat responses)
- The Sourcegraph endpoint is hardcoded
It is OK to break web/ in your other PRs; don't waste time trying to make it work (until further notice, anyone relying on web/ is responsible for keeping it working).
Try it out at https://noodle-cody-web-x847yqf4z.netlify.app/ and enter a Sourcegraph.com access token.
Test plan
Run pnpm -C web dev and visit http://localhost:5777. After entering a Sourcegraph.com access token, you should see the chat webview UI and be able to select models and chat.
Nothing in the VS Code extension or agent should break or change behavior as a result of this change.
‼️ Hey @sourcegraph/cody-security, please review this PR carefully as it introduces the usage of an unsafe_ function or abuses PromptString.
@sqs, have you tried building this package? It seems that the target output module is having a problem with web worker creation.
RollupError: [vite:worker-import-meta-url] Invalid value "iife" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.
I've tried changing the target and formats for the build option but it had no effect. Also, I probably should compile/build this with lib mode or don't build this at all, because I'm not sure how the pre-build module will go with module resolution on the consumer side (I guess web-worker URI resolution won't work)
or don't build this at all
This would mean that consumers should override shims themselves, but maybe this is needed anyway because we won't have dynamic shims for file resolution, for example.
Found worker.format option in vite config (was looking in the wrong settings the whole time), still trying to figure out how exactly we should ship this package considering that shims mocked API should be open for extending on consumer layer (for example to provide possible files for the context)
@vovakulikov No, I haven't tried building this package. I haven't thought through the best way to allow the consumer to shim it, but since it's just 1 real consumer for now (sourcegraph), it's probably fine to have something that's not yet generalized.
FYI, I'm going to rebase and merge this because there are some changes (to the chat message editor UI) that I'd like to make that would be a lot easier to iterate on with this.
(But as the PR description states, web/ is still experimental and anyone can break it! So don't take it being merged to main as a sign that its API/impl is settled or anything. :smile:)
@dominiccooney:
How big is the burden for DOM and Node APIs, in the limit? Part of me is wondering if we could run Agent in-process in JetBrains in a JavaScript environment.
Interesting idea. If you're referring to the extra burden of running the agent in a Web Worker vs. just running it as a separate node process, I don't anticipate it would be much (either in terms of resource consumption or complexity). It might be trickier to do certain HTTP proxy things in the worker, though, which have been a pain in the past.
but since it's just 1 real consumer for now (sourcegraph), it's probably fine to have something that's not yet generalized.
Yeah, I don't worry about generalized API at the moment, but since we override native nodejs API with "vite replacements," it means that these noop API implementations with which we replaced NodeJs implementation are included in the bundle, and the consumer doesn't have any API to get access to them. We need this for instance to provide the right list of files for suggestions in the chat input UI (readdir)
So what I have in mind is either
- Let's consumer bundle this (the downside here is that the consumer should know about internal native NodeJs API usage in the Cody repo)
- We bundle (add shims) cody/web package in Cody repository but shims should expose some API to override their return values, for example
// fs__promises.ts
import type { Dirent, Stats } from 'node:fs'
import { CodyContextStore } from './context-store'
export function readdir(): Promise<Dirent[]> {
return Promise.resolve(CodyContextStore.DIRECTORIES)
}
// context-store.ts
export class CodyContextStore {
static DIRECTORIES = []
static setContextDirectories(dirs: Dirent) {
CodyContextStore.DIRECTORIES = dirs
}
...
}
Then, the consumer, as we go to the blob UI page, will set CodyContextStore with the right values, and then when we open Cody chat directories, all internal API inside cody/web packages will be mocked properly.
@vovakulikov Yep, makes sense. Either of those seem like good approaches. And eventually we'll probably get to the ultimate state where agent does not depend on global file system and other node state.