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

Feat: AI Code AutoCompletion with Codeium Support #328

Merged
merged 13 commits into from
Jul 5, 2023

Conversation

li-xin-yi
Copy link
Collaborator

Usage

Right-click the pane and select this option:
image
Then it prompts a tab and requires your Codeium token obtained from this tab:
image
image

After that, try to type some prompts in code editor, it gives inline completion suggestions:

image

Tips

  1. Turn off the Codeium Chrome extension if installed
  2. Run npx prisma migrate dev in docker api's shell and then restart

Don't merge, just for test, many issues may exist

Todo

  1. clean up
  2. handle exceptions
  3. better UI and logic implementation for Codeium auth? (how about anonymous users?)
  4. fix bugs with storing api keys
  5. only use the context in the same editor, we may add more code editor contents in the following PRs.

@li-xin-yi li-xin-yi marked this pull request as draft June 9, 2023 19:32
@@ -51,6 +51,8 @@ model User {
Repo Repo[] @relation("OWNER")
sharedRepos Repo[] @relation("COLLABORATOR")
UserRepoData UserRepoData[]

codeiumAPIKey String? @default("")
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we'd better not store user tokens in the database, for security and privacy policy purposes.

Let's use the browser cache (localStorage) instead? And let's make all the Codeium API requests directly from the user's browser.

I'm having the same concern in #216, and I plan to use localStorage for GitHub token as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree. localStorage seems available across all browsers. Should we use it to store users' API keys or their tokens?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Another strange question: if one stored his/her own token before, after he/she logs out and signs in with another account, should the stored token remains?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Good, good point. The settings should come and go with the user. If a user logout, the token should also be removed for security purpose. People might log in and out on a public computer in the library.

Copy link
Collaborator

Choose a reason for hiding this comment

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

In this sense, localStorage is not a good option to store either settings or user tokens. We should indeed use the database.

@senwang86
Copy link
Collaborator

Thanks for the hard work, @li-xin-yi !
A couple of thoughts regarding the To-do list:

  1. better UI and logic implementation for Codeium auth? (how about anonymous users?)
  • If the enabling/disabling behavior is not tied to certain pods/scopes, it may be better to move the menu item from "right click" to "sidebar", making it easier for users to enable/disable Codeium support.
  • As @lihebi mentioned, to reduce the UI complexity, we might not require an extra pop-up window for the Codeium token. Once the functionality/connection to Codeium server is stabilized, we can improve the UI work, e.g., by subsequently developing a "User setting" page to add various tokens.
  • By default, we can register another Codeium account (e.g., anony_codepod) for anonymous users.

@lihebi
Copy link
Collaborator

lihebi commented Jun 10, 2023

By default, we can register another Codeium account (e.g., anony_codepod) for anonymous users.

I think people should bring their tokens; it's their business and pricing plans with Codeium (though it is free). Otherwise, we need to obtain some enterprise licenses with Codeium to provide it for our users.

Anonymous users can still set a token. If we use localStorage to store the token, it doesn't matter whether the user is registered or not.

@li-xin-yi
Copy link
Collaborator Author

li-xin-yi commented Jun 14, 2023

Update:

I also keep the option on the sidebar (BTW, I think many options can also be kept on sidebar, for example, show line numbers)

I'm considering about storing stuffs in the browser's local storage, not only the token, but the option to turn on/off some feats, such as auto-completion, show annotations, or maybe the last viewpoint...

what do you think about it? @lihebi @senwang86

@forrestbao
Copy link
Collaborator

I agree that we should move "show line numbers" and "Enable auto completion" to the side bar.

@lihebi
Copy link
Collaborator

lihebi commented Jun 14, 2023

I also keep the option on the sidebar (BTW, I think many options can also be kept on sidebar, for example, show line numbers)

I have a settingSlice.ts to keep all the localStorage settings. You can put the settings there.

export const createSettingSlice: StateCreator<MyState, [], [], SettingSlice> = (
set,
get
) => ({
scopedVars: localStorage.getItem("scopedVars")
? JSON.parse(localStorage.getItem("scopedVars")!)
: true,
showAnnotations: localStorage.getItem("showAnnotations")
? JSON.parse(localStorage.getItem("showAnnotations")!)
: false,
setScopedVars: (b: boolean) => {
// set it
set({ scopedVars: b });
// also write to local storage
localStorage.setItem("scopedVars", JSON.stringify(b));
},
setShowAnnotations: (b: boolean) => {
// set it
set({ showAnnotations: b });
// also write to local storage
localStorage.setItem("showAnnotations", JSON.stringify(b));
},
devMode: localStorage.getItem("devMode")
? JSON.parse(localStorage.getItem("devMode")!)
: false,
setDevMode: (b: boolean) => {
// set it
set({ devMode: b });
// also write to local storage
localStorage.setItem("devMode", JSON.stringify(b));
},

@lihebi
Copy link
Collaborator

lihebi commented Jun 14, 2023

I'm considering about storing stuffs in the browser's local storage, not only the token, but the option to turn on/off some feats, such as auto-completion, show annotations, or maybe the last viewpoint...

Let's think twice about localStorage, it has several downsides:

  1. the most important (as you mentioned): the settings/tokens should come and go with the users. In this sense, we should not use localStorage.
  2. it does not support cross-browser syncing.

I think we could put a few simple things like "debug mode" in localStorage, and clear (reset) it after user logouts. All other settings and tokens that are expected to sync cross browsers should be kept in the database.

@forrestbao
Copy link
Collaborator

If the tokens were saved in Auto-Fill, it could be synced by browsers? LIke password synching via Chrome or Firefox.

@li-xin-yi li-xin-yi force-pushed the feat/auto-complete branch from 19f8d93 to 51532f7 Compare June 23, 2023 15:56
@li-xin-yi
Copy link
Collaborator Author

Update:

image
  1. Allow user to bring their own API key (token) by clicking on the small help icon right after the auto-completion option:
image
  1. Store the user's API key in DB, the option of turn on/off auto-completion/custom-API in the browser's local storage.
image

(warning if no stored API key for yourself)
3. Set a default API key if user doesn't specify their own key.
4. Ban the auto-completion for guest users (not anonymous users, refer to the users who doesn't have a write access to the repo)

To add the default Codeium API key: add one line in compose/dev/.env:

CODEIUM_API_KEY=<your_api_key>

To get the plaintext of your Codeium key, verify your key in the dialog above, check the console log, it prints your updated api key (I will remove it for final clean-up, just for tests)

@li-xin-yi li-xin-yi force-pushed the feat/auto-complete branch from 1ad8d32 to 1c51cf4 Compare July 4, 2023 14:51
@li-xin-yi li-xin-yi marked this pull request as ready for review July 4, 2023 14:53
@li-xin-yi
Copy link
Collaborator Author

Update: when no default API specified in .env file, the "auto-completion" switch is in the off state, when trying to turn it on, the setting window shows up.

@li-xin-yi li-xin-yi changed the title [WIP] Feat: AI Code AutoCompletion with Codeium Support Feat: AI Code AutoCompletion with Codeium Support Jul 4, 2023
Copy link
Collaborator

@lihebi lihebi left a comment

Choose a reason for hiding this comment

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

Thanks, Xinyi. The PR looks and works very well. A few minor comments.

const client = useApolloClient();
const autoCompletion = useStore(store, (state) => state.autoCompletion);

console.log("autoCompletion", autoCompletion);
Copy link
Collaborator

Choose a reason for hiding this comment

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

clean this?

signal,
headers: this.getHeaders(request.metadata?.apiKey),
});
console.log("codeium request", request);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is printed very often. Change it to console.debug so that user's console stays clean.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or we could show an indicator in a "status bar" (or the toolbar near the "auto-complete" switch) to show that we are doing a Codeium request.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I like the idea of indicator. Do we have to implement it in this PR? I can add it later.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sg, let’s add it later.

Comment on lines +66 to +68
if (api_key === "" || api_key === undefined) {
throw new Error("Invalid token");
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's also provide a way so that people can clear their tokens?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds good. Added!

Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel these changes are leftovers (to be removed) from your code to test Codeium plugins.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, definitely my fault, I forgot to clean them up.

@lihebi
Copy link
Collaborator

lihebi commented Jul 5, 2023

Merging. Thanks, Xinyi!

@lihebi lihebi merged commit dcb0d17 into codepod-io:main Jul 5, 2023
@li-xin-yi
Copy link
Collaborator Author

Forgot to ask: Do I also need to update the compose/prod/compose.yml?

@forrestbao
Copy link
Collaborator

Forgot to ask: Do I also need to update the compose/prod/compose.yml?

I would be helpful to leave a placeholder there for Codeium API.

@lihebi
Copy link
Collaborator

lihebi commented Jul 7, 2023

compose/prod/compose.yml has been deprecated as it was used for hosting CodePod in a production environment. However, the production setup has been transitioned from Docker to Kubernetes (k8s). You can find the updated configuration at https://github.com/codepod-io/codepod-k8s.

Although the prod configuration is no longer recommended for production, it can still be useful for users (non-developers) who want to launch a "local CodePod" with minimal resource requirements. This configuration serves plain HTML and JavaScript instead of using react start, which requires more than 3GB of RAM. Additionally, there is no need to mount the src/ folder since there is no intention to develop the CodePod source code in this scenario.

However, to avoid confusion, it is advisable to temporarily remove the prod configuration. We should release a "local CodePod" in some form once we have a clear plan in place.

lihebi added a commit to lihebi/codepod that referenced this pull request Jul 7, 2023
lihebi added a commit that referenced this pull request Jul 7, 2023
@@ -63,6 +70,7 @@
"zustand": "^4.1.3"
},
"scripts": {
"generate": "chmod 777 /root && rm -rf ./src/proto && npx buf generate --output ./src/",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need chmod 777 /root? The app inside the container is mounted at /app/src/.

Copy link
Collaborator Author

@li-xin-yi li-xin-yi Jul 8, 2023

Choose a reason for hiding this comment

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

Otherwise, npx buf generate will fail because it needs to create & read a /root/.config/buf/config.yaml. I have no idea how to fix it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see. I'll take a look later.

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.

4 participants