Skip to content

Commit dcb0d17

Browse files
authored
Feat: AI Code AutoCompletion with Codeium Support (#328)
1 parent 362100e commit dcb0d17

File tree

24 files changed

+1366
-12
lines changed

24 files changed

+1366
-12
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ src/tailwind.output.css
3131

3232
*-checkpoint*
3333

34-
back/
34+
back/
35+
ui/src/proto/*
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "User" ADD COLUMN "codeiumAPIKey" TEXT DEFAULT '';

api/prisma/schema.prisma

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ model User {
5151
Repo Repo[] @relation("OWNER")
5252
sharedRepos Repo[] @relation("COLLABORATOR")
5353
UserRepoData UserRepoData[]
54+
55+
codeiumAPIKey String? @default("")
5456
}
5557

5658
model UserRepoData {

api/src/resolver_user.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ async function signupGuest(_, {}) {
6868
/**
6969
* Login a user with a guest ID and no password.
7070
*/
71-
async function loginGuest(_, {id}) {
71+
async function loginGuest(_, { id }) {
7272
const user = await prisma.user.findFirst({
7373
where: {
7474
id,
7575
isGuest: true,
76-
}
76+
},
7777
});
7878
if (!user) throw Error(`User does not exist`);
7979
return {
@@ -172,6 +172,29 @@ async function loginWithGoogle(_, { idToken }) {
172172
};
173173
}
174174

175+
async function updateCodeiumAPIKey(_, { apiKey }, { userId }) {
176+
if (!userId) throw Error("Unauthenticated");
177+
let user = await prisma.user.findFirst({
178+
where: {
179+
id: userId,
180+
},
181+
});
182+
if (!user) throw Error("User not found.");
183+
if (user.id !== userId) {
184+
throw new Error("You do not have access to the user.");
185+
}
186+
// do the udpate
187+
await prisma.user.update({
188+
where: {
189+
id: userId,
190+
},
191+
data: {
192+
codeiumAPIKey: apiKey,
193+
},
194+
});
195+
return true;
196+
}
197+
175198
export default {
176199
Query: {
177200
me,
@@ -183,5 +206,6 @@ export default {
183206
updateUser,
184207
signupGuest,
185208
loginGuest,
209+
updateCodeiumAPIKey,
186210
},
187211
};

api/src/typedefs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const typeDefs = gql`
1212
password: String!
1313
firstname: String!
1414
lastname: String!
15+
codeiumAPIKey: String!
1516
}
1617
1718
type Visibility {
@@ -143,5 +144,6 @@ export const typeDefs = gql`
143144
144145
exportJSON(repoId: String!): String!
145146
exportFile(repoId: String!): String!
147+
updateCodeiumAPIKey(apiKey: String!): Boolean
146148
}
147149
`;

compose/dev/compose.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ services:
6060
- 3000:3000
6161
environment:
6262
REACT_APP_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
63+
REACT_APP_CODEIUM_API_KEY: ${CODEIUM_API_KEY}
64+
6365
volumes:
6466
- ../../ui:/app
6567
- ui-node-modules:/app/node_modules
66-
command: sh -c "yarn && yarn dev"
68+
command: sh -c "yarn && yarn run generate && yarn dev"
6769

6870
proxy:
6971
image: node:18

ui/buf.gen.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# buf.gen.yaml defines a local generation template.
2+
# For details, see https://docs.buf.build/configuration/v1/buf-gen-yaml
3+
version: v1
4+
plugins:
5+
- name: es
6+
out: proto
7+
opt:
8+
- target=ts
9+
- import_extension=none
10+
- name: connect-es
11+
out: proto
12+
opt:
13+
- target=ts
14+
- import_extension=none

ui/buf.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Generated by buf. DO NOT EDIT.
2+
version: v1
3+
deps:
4+
- remote: buf.build
5+
owner: envoyproxy
6+
repository: protoc-gen-validate
7+
commit: 6607b10f00ed4a3d98f906807131c44a
8+
digest: shake256:acc7b2ededb2f88d296862943a003b157bdb68ec93ed13dcd8566b2d06e47993ea6daf12013b9655658aaf6bbdb141cf65bfe400ce2870f4654b0a5b45e57c09

ui/buf.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: v1
2+
deps:
3+
- buf.build/envoyproxy/protoc-gen-validate
4+
build:
5+
excludes:
6+
- node_modules
7+
lint:
8+
use:
9+
- DEFAULT
10+
except:
11+
- PACKAGE_VERSION_SUFFIX
12+
allow_comment_ignores: true
13+
breaking:
14+
except:
15+
- FILE_NO_DELETE
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright Exafunction, Inc.
2+
3+
syntax = "proto3";
4+
5+
package exa.codeium_common_pb;
6+
7+
import "google/protobuf/duration.proto";
8+
import "google/protobuf/timestamp.proto";
9+
import "validate/validate.proto";
10+
11+
option go_package = "github.com/Exafunction/Exafunction/exa/codeium_common_pb";
12+
13+
// Next ID: 12, Previous field: entropy.
14+
message Completion {
15+
string completion_id = 1;
16+
string text = 2;
17+
string prefix = 3;
18+
string stop = 4;
19+
double score = 5;
20+
repeated uint64 tokens = 6;
21+
repeated string decoded_tokens = 7;
22+
repeated double probabilities = 8;
23+
repeated double adjusted_probabilities = 9;
24+
uint64 generated_length = 10;
25+
}
26+
27+
// Authentication source for users on the cloud service.
28+
enum AuthSource {
29+
AUTH_SOURCE_CODEIUM = 0;
30+
}
31+
32+
// Next ID: 15, Previous field: url.
33+
message Metadata {
34+
string ide_name = 1 [(validate.rules).string.min_len = 1];
35+
string ide_version = 7 [(validate.rules).string.min_len = 1];
36+
string extension_name = 12;
37+
string extension_version = 2 [(validate.rules).string.min_len = 1];
38+
string api_key = 3 [(validate.rules).string.uuid = true];
39+
// Regex derived from https://stackoverflow.com/a/48300605.
40+
// TODO(prem): Should this be mandatory?
41+
string locale = 4 [(validate.rules).string = {
42+
ignore_empty: true,
43+
pattern: "^[A-Za-z]{2,4}([_-][A-Za-z]{4})?([_-]([A-Za-z]{2}|[0-9]{3}))?$"
44+
}];
45+
// UID identifying a single session for the given user.
46+
string session_id = 10;
47+
48+
// Used purely in language server to cancel in flight requests.
49+
// If request_id is 0, then the request is not cancelable.
50+
// This should be a strictly monotonically increasing number
51+
// for the duration of a session.
52+
uint64 request_id = 9;
53+
54+
// Browser-specific information.
55+
string user_agent = 13;
56+
string url = 14 [(validate.rules).string = {
57+
ignore_empty: true,
58+
uri: true
59+
}];
60+
61+
// Authentication source information.
62+
AuthSource auth_source = 15;
63+
}
64+
65+
// Next ID: 3, Previous field: insert_spaces.
66+
message EditorOptions {
67+
uint64 tab_size = 1 [(validate.rules).uint64.gt = 0];
68+
bool insert_spaces = 2;
69+
}
70+
71+
message Event {
72+
EventType event_type = 1;
73+
string event_json = 2;
74+
int64 timestamp_unix_ms = 3;
75+
}
76+
77+
enum EventType {
78+
EVENT_TYPE_UNSPECIFIED = 0;
79+
EVENT_TYPE_ENABLE_CODEIUM = 1;
80+
EVENT_TYPE_DISABLE_CODEIUM = 2;
81+
EVENT_TYPE_SHOW_PREVIOUS_COMPLETION = 3;
82+
EVENT_TYPE_SHOW_NEXT_COMPLETION = 4;
83+
}
84+
85+
enum CompletionSource {
86+
COMPLETION_SOURCE_UNSPECIFIED = 0;
87+
COMPLETION_SOURCE_TYPING_AS_SUGGESTED = 1;
88+
COMPLETION_SOURCE_CACHE = 2;
89+
COMPLETION_SOURCE_NETWORK = 3;
90+
}
91+
92+
// Every time this list is updated, we should be redeploying the API server
93+
// since it uses the string representation for BQ.
94+
enum Language {
95+
LANGUAGE_UNSPECIFIED = 0;
96+
LANGUAGE_C = 1;
97+
LANGUAGE_CLOJURE = 2;
98+
LANGUAGE_COFFEESCRIPT = 3;
99+
LANGUAGE_CPP = 4;
100+
LANGUAGE_CSHARP = 5;
101+
LANGUAGE_CSS = 6;
102+
LANGUAGE_CUDACPP = 7;
103+
LANGUAGE_DOCKERFILE = 8;
104+
LANGUAGE_GO = 9;
105+
LANGUAGE_GROOVY = 10;
106+
LANGUAGE_HANDLEBARS = 11;
107+
LANGUAGE_HASKELL = 12;
108+
LANGUAGE_HCL = 13;
109+
LANGUAGE_HTML = 14;
110+
LANGUAGE_INI = 15;
111+
LANGUAGE_JAVA = 16;
112+
LANGUAGE_JAVASCRIPT = 17;
113+
LANGUAGE_JSON = 18;
114+
LANGUAGE_JULIA = 19;
115+
LANGUAGE_KOTLIN = 20;
116+
LANGUAGE_LATEX = 21;
117+
LANGUAGE_LESS = 22;
118+
LANGUAGE_LUA = 23;
119+
LANGUAGE_MAKEFILE = 24;
120+
LANGUAGE_MARKDOWN = 25;
121+
LANGUAGE_OBJECTIVEC = 26;
122+
LANGUAGE_OBJECTIVECPP = 27;
123+
LANGUAGE_PERL = 28;
124+
LANGUAGE_PHP = 29;
125+
LANGUAGE_PLAINTEXT = 30;
126+
LANGUAGE_PROTOBUF = 31;
127+
LANGUAGE_PBTXT = 32;
128+
LANGUAGE_PYTHON = 33;
129+
LANGUAGE_R = 34;
130+
LANGUAGE_RUBY = 35;
131+
LANGUAGE_RUST = 36;
132+
LANGUAGE_SASS = 37;
133+
LANGUAGE_SCALA = 38;
134+
LANGUAGE_SCSS = 39;
135+
LANGUAGE_SHELL = 40;
136+
LANGUAGE_SQL = 41;
137+
LANGUAGE_STARLARK = 42;
138+
LANGUAGE_SWIFT = 43;
139+
LANGUAGE_TSX = 44;
140+
LANGUAGE_TYPESCRIPT = 45;
141+
LANGUAGE_VISUALBASIC = 46;
142+
LANGUAGE_VUE = 47;
143+
LANGUAGE_XML = 48;
144+
LANGUAGE_XSL = 49;
145+
LANGUAGE_YAML = 50;
146+
LANGUAGE_SVELTE = 51;
147+
LANGUAGE_TOML = 52;
148+
LANGUAGE_DART = 53;
149+
LANGUAGE_RST = 54;
150+
LANGUAGE_OCAML = 55;
151+
LANGUAGE_CMAKE = 56;
152+
LANGUAGE_PASCAL = 57;
153+
LANGUAGE_ELIXIR = 58;
154+
LANGUAGE_FSHARP = 59;
155+
LANGUAGE_LISP = 60;
156+
LANGUAGE_MATLAB = 61;
157+
LANGUAGE_POWERSHELL = 62;
158+
LANGUAGE_SOLIDITY = 63;
159+
LANGUAGE_ADA = 64;
160+
LANGUAGE_OCAML_INTERFACE = 65;
161+
}

0 commit comments

Comments
 (0)