cody icon indicating copy to clipboard operation
cody copied to clipboard

Cody standalone web app prototype and dev helper

Open sqs opened this issue 1 year ago • 3 comments

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.

image

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.

sqs avatar May 03 '24 22:05 sqs

‼️ Hey @sourcegraph/cody-security, please review this PR carefully as it introduces the usage of an unsafe_ function or abuses PromptString.

github-actions[bot] avatar May 03 '24 22:05 github-actions[bot]

@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.

vovakulikov avatar May 17 '24 14:05 vovakulikov

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 avatar May 17 '24 23:05 vovakulikov

@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.

sqs avatar May 18 '24 15:05 sqs

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:)

sqs avatar May 18 '24 15:05 sqs

@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.

sqs avatar May 18 '24 17:05 sqs

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 avatar May 18 '24 19:05 vovakulikov

@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.

sqs avatar May 18 '24 20:05 sqs