Skip to content

Commit b1070bd

Browse files
committed
feat: add hacked together demo for codium ai autocomplete
1 parent f550d21 commit b1070bd

11 files changed

Lines changed: 615 additions & 5 deletions

File tree

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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+
enum ExperimentKey {
14+
UNSPECIFIED = 0;
15+
JUPYTER_FORMAT = 77;
16+
}
17+
18+
// Next ID: 12, Previous field: entropy.
19+
message Completion {
20+
string completion_id = 1;
21+
string text = 2;
22+
string prefix = 3;
23+
string stop = 4;
24+
double score = 5;
25+
repeated uint64 tokens = 6;
26+
repeated string decoded_tokens = 7;
27+
repeated double probabilities = 8;
28+
repeated double adjusted_probabilities = 9;
29+
uint64 generated_length = 10;
30+
}
31+
32+
// Authentication source for users on the cloud service.
33+
enum AuthSource {
34+
AUTH_SOURCE_CODEIUM = 0;
35+
}
36+
37+
// Next ID: 15, Previous field: url.
38+
message Metadata {
39+
string ide_name = 1 /* [(validate.rules).string.min_len = 1] */;
40+
string ide_version = 7 /* [(validate.rules).string.min_len = 1] */;
41+
string extension_name = 12;
42+
string extension_version = 2 /* [(validate.rules).string.min_len = 1] */;
43+
string api_key = 3 /* [(validate.rules).string.uuid = true] */;
44+
// Regex derived from https://stackoverflow.com/a/48300605.
45+
// TODO(prem): Should this be mandatory?
46+
string locale = 4 /* [(validate.rules).string = {
47+
ignore_empty: true,
48+
pattern: "^[A-Za-z]{2,4}([_-][A-Za-z]{4})?([_-]([A-Za-z]{2}|[0-9]{3}))?$"
49+
}] */;
50+
// UID identifying a single session for the given user.
51+
string session_id = 10;
52+
53+
// Used purely in language server to cancel in flight requests.
54+
// If request_id is 0, then the request is not cancelable.
55+
// This should be a strictly monotonically increasing number
56+
// for the duration of a session.
57+
uint64 request_id = 9;
58+
59+
// Browser-specific information.
60+
string user_agent = 13;
61+
string url = 14 /* [(validate.rules).string = {
62+
ignore_empty: true,
63+
uri: true
64+
}] */;
65+
66+
// Authentication source information.
67+
AuthSource auth_source = 15;
68+
}
69+
70+
// Next ID: 3, Previous field: insert_spaces.
71+
message EditorOptions {
72+
uint64 tab_size = 1 /* [(validate.rules).uint64.gt = 0] */;
73+
bool insert_spaces = 2;
74+
}
75+
76+
message Event {
77+
EventType event_type = 1;
78+
string event_json = 2;
79+
int64 timestamp_unix_ms = 3;
80+
}
81+
82+
enum EventType {
83+
EVENT_TYPE_UNSPECIFIED = 0;
84+
EVENT_TYPE_ENABLE_CODEIUM = 1;
85+
EVENT_TYPE_DISABLE_CODEIUM = 2;
86+
EVENT_TYPE_SHOW_PREVIOUS_COMPLETION = 3;
87+
EVENT_TYPE_SHOW_NEXT_COMPLETION = 4;
88+
}
89+
90+
enum CompletionSource {
91+
COMPLETION_SOURCE_UNSPECIFIED = 0;
92+
COMPLETION_SOURCE_TYPING_AS_SUGGESTED = 1;
93+
COMPLETION_SOURCE_CACHE = 2;
94+
COMPLETION_SOURCE_NETWORK = 3;
95+
}
96+
97+
// Every time this list is updated, we should be redeploying the API server
98+
// since it uses the string representation for BQ.
99+
enum Language {
100+
LANGUAGE_UNSPECIFIED = 0;
101+
LANGUAGE_C = 1;
102+
LANGUAGE_CLOJURE = 2;
103+
LANGUAGE_COFFEESCRIPT = 3;
104+
LANGUAGE_CPP = 4;
105+
LANGUAGE_CSHARP = 5;
106+
LANGUAGE_CSS = 6;
107+
LANGUAGE_CUDACPP = 7;
108+
LANGUAGE_DOCKERFILE = 8;
109+
LANGUAGE_GO = 9;
110+
LANGUAGE_GROOVY = 10;
111+
LANGUAGE_HANDLEBARS = 11;
112+
LANGUAGE_HASKELL = 12;
113+
LANGUAGE_HCL = 13;
114+
LANGUAGE_HTML = 14;
115+
LANGUAGE_INI = 15;
116+
LANGUAGE_JAVA = 16;
117+
LANGUAGE_JAVASCRIPT = 17;
118+
LANGUAGE_JSON = 18;
119+
LANGUAGE_JULIA = 19;
120+
LANGUAGE_KOTLIN = 20;
121+
LANGUAGE_LATEX = 21;
122+
LANGUAGE_LESS = 22;
123+
LANGUAGE_LUA = 23;
124+
LANGUAGE_MAKEFILE = 24;
125+
LANGUAGE_MARKDOWN = 25;
126+
LANGUAGE_OBJECTIVEC = 26;
127+
LANGUAGE_OBJECTIVECPP = 27;
128+
LANGUAGE_PERL = 28;
129+
LANGUAGE_PHP = 29;
130+
LANGUAGE_PLAINTEXT = 30;
131+
LANGUAGE_PROTOBUF = 31;
132+
LANGUAGE_PBTXT = 32;
133+
LANGUAGE_PYTHON = 33;
134+
LANGUAGE_R = 34;
135+
LANGUAGE_RUBY = 35;
136+
LANGUAGE_RUST = 36;
137+
LANGUAGE_SASS = 37;
138+
LANGUAGE_SCALA = 38;
139+
LANGUAGE_SCSS = 39;
140+
LANGUAGE_SHELL = 40;
141+
LANGUAGE_SQL = 41;
142+
LANGUAGE_STARLARK = 42;
143+
LANGUAGE_SWIFT = 43;
144+
LANGUAGE_TSX = 44;
145+
LANGUAGE_TYPESCRIPT = 45;
146+
LANGUAGE_VISUALBASIC = 46;
147+
LANGUAGE_VUE = 47;
148+
LANGUAGE_XML = 48;
149+
LANGUAGE_XSL = 49;
150+
LANGUAGE_YAML = 50;
151+
LANGUAGE_SVELTE = 51;
152+
LANGUAGE_TOML = 52;
153+
LANGUAGE_DART = 53;
154+
LANGUAGE_RST = 54;
155+
LANGUAGE_OCAML = 55;
156+
LANGUAGE_CMAKE = 56;
157+
LANGUAGE_PASCAL = 57;
158+
LANGUAGE_ELIXIR = 58;
159+
LANGUAGE_FSHARP = 59;
160+
LANGUAGE_LISP = 60;
161+
LANGUAGE_MATLAB = 61;
162+
LANGUAGE_POWERSHELL = 62;
163+
LANGUAGE_SOLIDITY = 63;
164+
LANGUAGE_ADA = 64;
165+
LANGUAGE_OCAML_INTERFACE = 65;
166+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import path from 'node:path';
2+
import protobuf from 'protobufjs';
3+
import Long from 'long';
4+
import { type CodiumCompletionResult } from "@srcbook/shared";
5+
6+
// NOTE: this EDITOR_API_KEY value was just included as a raw string in
7+
// @codeium/react-code-editor. This seems to not be a secret?
8+
const EDITOR_API_KEY = 'd49954eb-cfba-4992-980f-d8fb37f0e942';
9+
const LANGUAGE_SERVER_PROTO_FILE_PATH = path.join(__dirname, "language_server.proto");
10+
11+
export async function runCodiumAiAutocomplete(source: string, cursorOffset: number): Promise<CodiumCompletionResult> {
12+
const protos = await protobuf.load(LANGUAGE_SERVER_PROTO_FILE_PATH)
13+
const GetCompletionsRequest = protos.lookupType("GetCompletionsRequest");
14+
const Metadata = protos.lookupType("Metadata");
15+
const DocumentInfo = protos.lookupType("Document");
16+
const EditorOptions = protos.lookupType("EditorOptions");
17+
const Language = protos.lookupEnum("Language");
18+
const GetCompletionsResponse = protos.lookupType("GetCompletionsResponse");
19+
20+
const sessionId = `react-editor-${crypto.randomUUID()}`;
21+
22+
const payload = {
23+
otherDocuments: [],
24+
metadata: Metadata.create({
25+
ideName: 'web',
26+
extensionVersion: '1.0.12',
27+
apiKey: 'd49954eb-cfba-4992-980f-d8fb37f0e942',
28+
ideVersion: 'unknown',
29+
extensionName: '@codeium/react-code-editor',
30+
sessionId,
31+
}),
32+
document: DocumentInfo.create({
33+
text: source,
34+
editorLanguage: 'javascript',
35+
language: Language.getOption("JAVASCRIPT"),
36+
cursorOffset: Long.fromValue(cursorOffset),
37+
lineEnding: '\n',
38+
}),
39+
editorOptions: EditorOptions.create({
40+
tabSize: Long.fromValue(4),
41+
insertSpaces: true
42+
}),
43+
};
44+
45+
// const verified = GetCompletionsRequest.verify(payload);
46+
// console.log('VERIFIED?', verified);
47+
48+
// console.log('REQUEST:', payload);
49+
50+
const requestData = GetCompletionsRequest.create(payload);
51+
const buffer = GetCompletionsRequest.encode(requestData).finish();
52+
53+
const response = await fetch('https://web-backend.codeium.com/exa.language_server_pb.LanguageServerService/GetCompletions', {
54+
method: 'POST',
55+
body: buffer,
56+
headers: {
57+
'Connect-Protocol-Version': '1',
58+
'Content-Type': 'application/proto',
59+
Authorization: `Basic ${EDITOR_API_KEY}-${sessionId}`,
60+
},
61+
});
62+
// console.log('RESPONSE:', response.status);
63+
64+
const responseBodyBytes = new Uint8Array(await response.arrayBuffer());
65+
const responseBody = GetCompletionsResponse.decode(responseBodyBytes);
66+
67+
// console.log('RESPONSE COMPLETIONS:');
68+
// for (const item of responseBody.completionItems) {
69+
// console.log(item.completion.text);
70+
// }
71+
72+
return responseBody;
73+
}

0 commit comments

Comments
 (0)