monacopilot 0.9.33 → 0.9.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -160
- package/build/index.d.mts +42 -57
- package/build/index.d.ts +42 -57
- package/build/index.js +11 -17
- package/build/index.mjs +11 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
# Monacopilot
|
|
4
4
|
|
|
@@ -8,26 +8,27 @@
|
|
|
8
8
|
|
|
9
9
|
- [Examples](#examples)
|
|
10
10
|
- [Installation](#installation)
|
|
11
|
-
- [
|
|
11
|
+
- [Inline Completions](#inline-completions)
|
|
12
|
+
- [Usage](#usage)
|
|
13
|
+
- [API Handler](#api-handler)
|
|
14
|
+
- [Register Completion with the Monaco Editor](#register-completion-with-the-monaco-editor)
|
|
15
|
+
- [Register Completion Options](#register-completion-options)
|
|
16
|
+
- [External Context](#external-context)
|
|
17
|
+
- [Filename](#filename)
|
|
18
|
+
- [Completions for Specific Technologies](#completions-for-specific-technologies)
|
|
19
|
+
- [Get Completions in Real-Time](#get-completions-in-real-time)
|
|
12
20
|
- [Copilot Options](#copilot-options)
|
|
13
21
|
- [Changing the Provider and Model](#changing-the-provider-and-model)
|
|
14
22
|
- [Custom Model](#custom-model)
|
|
15
23
|
- [Completion Request Options](#completion-request-options)
|
|
16
24
|
- [Custom Headers](#custom-headers)
|
|
17
25
|
- [Custom Prompt](#custom-prompt)
|
|
18
|
-
- [
|
|
19
|
-
- [Get Completions in Real-Time](#get-completions-in-real-time)
|
|
20
|
-
- [External Context](#external-context)
|
|
21
|
-
- [Filename](#filename)
|
|
22
|
-
- [Completions for Specific Technologies](#completions-for-specific-technologies)
|
|
23
|
-
- [Cost Overview](#cost-overview)
|
|
26
|
+
- [Select and Edit](#select-and-edit)
|
|
24
27
|
- [Contributing](#contributing)
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
### Examples
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Here are some examples of how to use Monacopilot in different project setups:
|
|
31
|
+
Here are some examples of how to integrate Monacopilot into your project:
|
|
31
32
|
|
|
32
33
|
- Next.js
|
|
33
34
|
- [App Router](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/app)
|
|
@@ -42,28 +43,21 @@ To install Monacopilot, run:
|
|
|
42
43
|
npm install monacopilot
|
|
43
44
|
```
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
## Usage
|
|
46
|
+
## Inline Completions
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
AI-generated suggestions that appear directly within your code as you type.
|
|
50
49
|
|
|
51
|
-
|
|
50
|
+
[Inline Completions Demo Video](https://github.com/user-attachments/assets/f2ec4ae1-f658-4002-af9c-c6b1bbad70d9)
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
# .env.local
|
|
57
|
-
GROQ_API_KEY=your-api-key
|
|
58
|
-
```
|
|
52
|
+
### Usage
|
|
59
53
|
|
|
60
54
|
#### API Handler
|
|
61
55
|
|
|
62
56
|
Set up an API handler to manage auto-completion requests. An example using Express.js:
|
|
63
57
|
|
|
64
58
|
```javascript
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
import express from 'express';
|
|
60
|
+
import {Copilot} from 'monacopilot';
|
|
67
61
|
|
|
68
62
|
const app = express();
|
|
69
63
|
const port = process.env.PORT || 3000;
|
|
@@ -71,7 +65,7 @@ const copilot = new Copilot(process.env.GROQ_API_KEY);
|
|
|
71
65
|
|
|
72
66
|
app.use(express.json());
|
|
73
67
|
|
|
74
|
-
app.post('/
|
|
68
|
+
app.post('/complete', async (req, res) => {
|
|
75
69
|
const completion = await copilot.complete({
|
|
76
70
|
body: req.body,
|
|
77
71
|
});
|
|
@@ -81,24 +75,24 @@ app.post('/copilot', async (req, res) => {
|
|
|
81
75
|
app.listen(port);
|
|
82
76
|
```
|
|
83
77
|
|
|
84
|
-
|
|
78
|
+
Now, Monacopilot is set up to send completion requests to the `/complete` endpoint and receive completions in response.
|
|
85
79
|
|
|
86
80
|
The `copilot.complete` method processes the request body sent by Monacopilot and returns the corresponding completion.
|
|
87
81
|
|
|
88
|
-
#### Register
|
|
82
|
+
#### Register Completion with the Monaco Editor
|
|
89
83
|
|
|
90
|
-
Now, let's integrate
|
|
84
|
+
Now, let's integrate AI auto-completion into your Monaco editor. Here's how you can do it:
|
|
91
85
|
|
|
92
86
|
```javascript
|
|
93
87
|
import * as monaco from 'monaco-editor';
|
|
94
|
-
import {
|
|
88
|
+
import {registerCompletion} from 'monacopilot';
|
|
95
89
|
|
|
96
90
|
const editor = monaco.editor.create(document.getElementById('container'), {
|
|
97
91
|
language: 'javascript',
|
|
98
92
|
});
|
|
99
93
|
|
|
100
|
-
|
|
101
|
-
endpoint: 'https://api.example.com/
|
|
94
|
+
registerCompletion(monaco, editor, {
|
|
95
|
+
endpoint: 'https://api.example.com/complete',
|
|
102
96
|
language: 'javascript',
|
|
103
97
|
});
|
|
104
98
|
```
|
|
@@ -108,13 +102,80 @@ registerCopilot(monaco, editor, {
|
|
|
108
102
|
| `endpoint` | `string` | The URL of the API endpoint that we created in the previous step. |
|
|
109
103
|
| `language` | `string` | The language of the editor. |
|
|
110
104
|
|
|
111
|
-
🎉
|
|
105
|
+
🎉 Congratulations! The AI auto-completion is now connected to the Monaco Editor. Start typing and see completions in the editor.
|
|
106
|
+
|
|
107
|
+
## Register Completion Options
|
|
108
|
+
|
|
109
|
+
### External Context
|
|
110
|
+
|
|
111
|
+
Enhance the accuracy and relevance of Copilot's completions by providing additional code context from your workspace.
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
registerCompletion(monaco, editor, {
|
|
115
|
+
// ...other options
|
|
116
|
+
externalContext: [
|
|
117
|
+
{
|
|
118
|
+
path: './utils.js',
|
|
119
|
+
content:
|
|
120
|
+
'export const reverse = (str) => str.split("").reverse().join("")',
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
By providing external context, Copilot can offer more intelligent suggestions. For example, if you start typing `const isPalindrome = `, Copilot may suggest using the `reverse` function from `utils.js`.
|
|
127
|
+
|
|
128
|
+
### Filename
|
|
129
|
+
|
|
130
|
+
Specify the name of the file being edited to receive more contextually relevant completions.
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
registerCompletion(monaco, editor, {
|
|
134
|
+
// ...other options
|
|
135
|
+
filename: 'utils.js', // e.g., "index.js", "utils/objects.js"
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Now, the completions will be more relevant to the file's context.
|
|
140
|
+
|
|
141
|
+
### Completions for Specific Technologies
|
|
142
|
+
|
|
143
|
+
Enable completions tailored to specific technologies by using the `technologies` option.
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
registerCompletion(monaco, editor, {
|
|
147
|
+
// ...other options
|
|
148
|
+
technologies: ['react', 'next.js', 'tailwindcss'],
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
This configuration will provide completions relevant to React, Next.js, and Tailwind CSS.
|
|
153
|
+
|
|
154
|
+
### Get Completions in Real-Time
|
|
155
|
+
|
|
156
|
+
The `trigger` option determines when the completion service provides code completions. You can choose between receiving suggestions/completions in real-time as you type or after a brief pause.
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
registerCompletion(monaco, editor, {
|
|
160
|
+
// ...other options
|
|
161
|
+
trigger: 'onTyping',
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
| Trigger | Description | Notes |
|
|
166
|
+
| -------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
167
|
+
| `'onIdle'` (default) | The completion service provides completions after a brief pause in typing. | This approach is less resource-intensive, as it only initiates a request when the editor is idle. However, compared to `onTyping`, it may result in a slightly reduced experience with completions. |
|
|
168
|
+
| `'onTyping'` | The completion service provides completions in real-time as you type. | This approach is best suited for models with low response latency, such as Groq models. Please note that this trigger mode initiates additional background requests to deliver real-time suggestions. Technically, this method is called predictive caching. |
|
|
169
|
+
|
|
170
|
+
[OnTyping Demo](https://github.com/user-attachments/assets/22c2ce44-334c-4963-b853-01b890b8e39f)
|
|
171
|
+
|
|
172
|
+
> **Note:** If you prefer real-time completions, you can set the `trigger` option to `'onTyping'`. This may increase the number of requests made to the provider and the cost. This should not be too costly since most small models are very inexpensive.
|
|
112
173
|
|
|
113
174
|
## Copilot Options
|
|
114
175
|
|
|
115
176
|
### Changing the Provider and Model
|
|
116
177
|
|
|
117
|
-
You can specify a different provider and model
|
|
178
|
+
You can specify a different provider and model by setting the `provider` and `model` parameters in the `Copilot` instance.
|
|
118
179
|
|
|
119
180
|
```javascript
|
|
120
181
|
const copilot = new Copilot(process.env.OPENAI_API_KEY, {
|
|
@@ -123,7 +184,7 @@ const copilot = new Copilot(process.env.OPENAI_API_KEY, {
|
|
|
123
184
|
});
|
|
124
185
|
```
|
|
125
186
|
|
|
126
|
-
The default provider is `groq
|
|
187
|
+
The default provider is `groq`, and the default model is `llama-3-70b`.
|
|
127
188
|
|
|
128
189
|
There are other providers and models available. Here is a list:
|
|
129
190
|
|
|
@@ -137,11 +198,14 @@ There are other providers and models available. Here is a list:
|
|
|
137
198
|
|
|
138
199
|
You can use a custom AI model that isn't built into Monacopilot by setting up a `model` when you create a new Copilot. This feature lets you connect to AI models from other services or your own custom-built models.
|
|
139
200
|
|
|
201
|
+
Please ensure you are using a high-quality model, especially for coding tasks, to get the best and most accurate completions. Also, use a model with very low response latency (preferably under 1.5 seconds) to enjoy a great experience and utilize the full power of Monacopilot.
|
|
202
|
+
|
|
140
203
|
#### Example
|
|
141
204
|
|
|
142
205
|
```javascript
|
|
143
206
|
const copilot = new Copilot(process.env.HUGGINGFACE_API_KEY, {
|
|
144
|
-
//
|
|
207
|
+
// You don't need to set the provider if you are using a custom model.
|
|
208
|
+
// provider: 'huggingface',
|
|
145
209
|
model: {
|
|
146
210
|
config: (apiKey, prompt) => ({
|
|
147
211
|
endpoint:
|
|
@@ -159,49 +223,29 @@ const copilot = new Copilot(process.env.HUGGINGFACE_API_KEY, {
|
|
|
159
223
|
},
|
|
160
224
|
},
|
|
161
225
|
}),
|
|
162
|
-
transformResponse: response =>
|
|
163
|
-
if (response.error) {
|
|
164
|
-
return {
|
|
165
|
-
completion: null,
|
|
166
|
-
error: response.error,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
completion: response[0].generated_text,
|
|
172
|
-
};
|
|
173
|
-
},
|
|
226
|
+
transformResponse: response => response[0].generated_text,
|
|
174
227
|
},
|
|
175
228
|
});
|
|
176
229
|
```
|
|
177
230
|
|
|
178
|
-
> Please make sure you are using a better model, especially for coding tasks, to get the best and most accurate completions. Otherwise, you may experience poor performance or inaccurate completions.
|
|
179
|
-
|
|
180
231
|
#### Configuration
|
|
181
232
|
|
|
182
233
|
The `model` option accepts an object with two functions:
|
|
183
234
|
|
|
184
|
-
| Function | Description
|
|
185
|
-
| ------------------- |
|
|
186
|
-
| `config` | A function that receives the API key and prompt data, and returns the configuration for the custom model API request.
|
|
187
|
-
| `transformResponse` | A function that takes the raw/parsed response from the custom model API and
|
|
235
|
+
| Function | Description | Type |
|
|
236
|
+
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
237
|
+
| `config` | A function that receives the API key and prompt data, and returns the configuration for the custom model API request. | `(apiKey: string, prompt: { system: string; user: string }) => { endpoint: string; body?: object; headers?: object }` |
|
|
238
|
+
| `transformResponse` | A function that takes the raw/parsed response from the custom model API and returns the model-generated text or null if the response is not valid. | `(response: unknown) => string \| null` |
|
|
188
239
|
|
|
189
240
|
The `config` function must return an object with the following properties:
|
|
190
241
|
|
|
191
|
-
| Property | Type
|
|
192
|
-
| ---------- |
|
|
193
|
-
| `endpoint` | `string`
|
|
194
|
-
| `body` | `object
|
|
195
|
-
| `headers` | `object
|
|
196
|
-
|
|
197
|
-
The `transformResponse` function must return an object with the following structure:
|
|
242
|
+
| Property | Type | Description |
|
|
243
|
+
| ---------- | ----------------------- | -------------------------------------------- |
|
|
244
|
+
| `endpoint` | `string` | The URL of the custom model API endpoint. |
|
|
245
|
+
| `body` | `object` or `undefined` | The body of the custom model API request. |
|
|
246
|
+
| `headers` | `object` or `undefined` | The headers of the custom model API request. |
|
|
198
247
|
|
|
199
|
-
|
|
200
|
-
| ------------ | --------------------- | ----------------------------------------------------------- |
|
|
201
|
-
| `completion` | `string \| null` | The generated completion text to be inserted in the editor. |
|
|
202
|
-
| `error` | `string \| undefined` | An error message if something went wrong. |
|
|
203
|
-
|
|
204
|
-
This structure allows for easy integration of the custom model's output with the rest of the Monacopilot system, providing either the generated completion text or an error message if something went wrong.
|
|
248
|
+
The `transformResponse` function must return the model-generated text.
|
|
205
249
|
|
|
206
250
|
## Completion Request Options
|
|
207
251
|
|
|
@@ -211,7 +255,6 @@ You can add custom headers to the provider's completion requests. For example, i
|
|
|
211
255
|
|
|
212
256
|
```javascript
|
|
213
257
|
copilot.complete({
|
|
214
|
-
body,
|
|
215
258
|
options: {
|
|
216
259
|
// ...other options
|
|
217
260
|
headers: {
|
|
@@ -229,7 +272,6 @@ You can customize the prompt used for generating completions by providing a `cus
|
|
|
229
272
|
|
|
230
273
|
```javascript
|
|
231
274
|
copilot.complete({
|
|
232
|
-
body,
|
|
233
275
|
options: {
|
|
234
276
|
customPrompt: metadata => ({
|
|
235
277
|
system: 'Your custom system prompt here',
|
|
@@ -239,11 +281,10 @@ copilot.complete({
|
|
|
239
281
|
});
|
|
240
282
|
```
|
|
241
283
|
|
|
242
|
-
The `system` and `user` prompts in the `customPrompt` function are optional.
|
|
284
|
+
The `system` and `user` prompts in the `customPrompt` function are optional. If you omit either the `system` or `user` prompt, the default prompt for that field will be used. Example of customizing only the system prompt:
|
|
243
285
|
|
|
244
286
|
```javascript
|
|
245
287
|
copilot.complete({
|
|
246
|
-
body,
|
|
247
288
|
options: {
|
|
248
289
|
customPrompt: metadata => ({
|
|
249
290
|
system:
|
|
@@ -255,34 +296,34 @@ copilot.complete({
|
|
|
255
296
|
|
|
256
297
|
#### Parameters
|
|
257
298
|
|
|
258
|
-
The `customPrompt` function receives a `completionMetadata` object
|
|
299
|
+
The `customPrompt` function receives a `completionMetadata` object, which contains information about the current editor state and can be used to tailor the prompt.
|
|
259
300
|
|
|
260
|
-
| Property
|
|
261
|
-
|
|
|
262
|
-
| language | `string`
|
|
263
|
-
| cursorPosition | `{lineNumber: number
|
|
264
|
-
| filename | `string
|
|
265
|
-
| technologies | `string[]
|
|
266
|
-
| externalContext | `object
|
|
267
|
-
| textAfterCursor | `string`
|
|
268
|
-
| textBeforeCursor | `string`
|
|
269
|
-
| editorState | `object`
|
|
301
|
+
| Property | Type | Description |
|
|
302
|
+
| ------------------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
303
|
+
| `language` | `string` | The programming language of the code. |
|
|
304
|
+
| `cursorPosition` | `{ lineNumber: number; column: number }` | The current cursor position in the editor. |
|
|
305
|
+
| `filename` | `string` or `undefined` | The name of the file being edited. Only available if you have provided the `filename` option in the `registerCompletion` function. |
|
|
306
|
+
| `technologies` | `string[]` or `undefined` | An array of technologies used in the project. Only available if you have provided the `technologies` option in the `registerCompletion` function. |
|
|
307
|
+
| `externalContext` | `object` or `undefined` | Additional context from related files. Only available if you have provided the `externalContext` option in the `registerCompletion` function. |
|
|
308
|
+
| `textAfterCursor` | `string` | The text that appears after the cursor. |
|
|
309
|
+
| `textBeforeCursor` | `string` | The text that appears before the cursor. |
|
|
310
|
+
| `editorState` | `object` | An object containing the `completionMode` property. |
|
|
270
311
|
|
|
271
312
|
The `editorState.completionMode` can be one of the following:
|
|
272
313
|
|
|
273
|
-
| Mode
|
|
274
|
-
|
|
|
275
|
-
| fill-in-the-middle | Indicates that the cursor is positioned within the existing text. In this mode, the AI will generate content to be inserted at the cursor position. |
|
|
276
|
-
| completion | Indicates that the cursor is at the end of the existing text. In this mode, the AI will generate content to continue or complete the text from the cursor position. |
|
|
314
|
+
| Mode | Description |
|
|
315
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
316
|
+
| `fill-in-the-middle` | Indicates that the cursor is positioned within the existing text. In this mode, the AI will generate content to be inserted at the cursor position. |
|
|
317
|
+
| `completion` | Indicates that the cursor is at the end of the existing text. In this mode, the AI will generate content to continue or complete the text from the cursor position. |
|
|
277
318
|
|
|
278
319
|
For additional `completionMetadata` needs, please [open an issue](https://github.com/arshad-yaseen/monacopilot/issues/new).
|
|
279
320
|
|
|
280
321
|
The `customPrompt` function should return an object with two properties:
|
|
281
322
|
|
|
282
|
-
| Property | Type
|
|
283
|
-
| -------- |
|
|
284
|
-
| system
|
|
285
|
-
| user
|
|
323
|
+
| Property | Type | Description |
|
|
324
|
+
| -------- | ----------------------- | ------------------------------------------------------ |
|
|
325
|
+
| `system` | `string` or `undefined` | A string representing the system prompt for the model. |
|
|
326
|
+
| `user` | `string` or `undefined` | A string representing the user prompt for the model. |
|
|
286
327
|
|
|
287
328
|
#### Example
|
|
288
329
|
|
|
@@ -294,90 +335,30 @@ const customPrompt = ({textBeforeCursor, textAfterCursor}) => ({
|
|
|
294
335
|
'You are an AI assistant specialized in writing React components. Focus on creating clean, reusable, and well-structured components.',
|
|
295
336
|
user: `Please complete the following React component:
|
|
296
337
|
|
|
297
|
-
${textBeforeCursor}
|
|
298
|
-
// Cursor position
|
|
299
|
-
${textAfterCursor}
|
|
338
|
+
${textBeforeCursor}
|
|
339
|
+
// Cursor position
|
|
340
|
+
${textAfterCursor}
|
|
300
341
|
|
|
301
|
-
Use modern React practices and hooks where appropriate. If you're adding new props, make sure to include proper TypeScript types. Please provide only the finished code without additional comments or explanations.`,
|
|
342
|
+
Use modern React practices and hooks where appropriate. If you're adding new props, make sure to include proper TypeScript types. Please provide only the finished code without additional comments or explanations.`,
|
|
302
343
|
});
|
|
303
344
|
|
|
304
345
|
copilot.complete({
|
|
305
|
-
body,
|
|
306
346
|
options: {customPrompt},
|
|
307
347
|
});
|
|
308
348
|
```
|
|
309
349
|
|
|
310
350
|
By using a custom prompt, you can guide the model to generate completions that better fit your coding style, project requirements, or specific technologies you're working with.
|
|
311
351
|
|
|
312
|
-
##
|
|
313
|
-
|
|
314
|
-
### Get Completions in Real-Time
|
|
315
|
-
|
|
316
|
-
The `trigger` option determines when Copilot provides code completions. You can choose between receiving suggestions in real-time as you type or after a brief pause.
|
|
317
|
-
|
|
318
|
-
```javascript
|
|
319
|
-
registerCopilot(monaco, editor, {
|
|
320
|
-
// ...other options
|
|
321
|
-
trigger: 'onTyping',
|
|
322
|
-
});
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
| Trigger | Description | Notes |
|
|
326
|
-
| -------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
327
|
-
| `'onIdle'` (default) | Copilot provides completions after a brief pause in typing. | This approach is less resource-intensive, as it only initiates a request when the editor is idle. However, compared to `onTyping` it may result in a bit reduced experience with completions. |
|
|
328
|
-
| `'onTyping'` | Copilot provides completions in real-time as you type. | This approach is best suited for models with low response latency, such as Groq. Please note that this trigger mode initiates additional background requests to deliver real-time suggestions. Technically, this method is called predictive caching. |
|
|
329
|
-
|
|
330
|
-
[OnTyping Demo](https://github.com/user-attachments/assets/22c2ce44-334c-4963-b853-01b890b8e39f)
|
|
331
|
-
|
|
332
|
-
If you prefer real-time completions, you can set the `trigger` option to `'onTyping'`. This is ideal for those who need immediate or fast completion experiences.
|
|
333
|
-
|
|
334
|
-
### External Context
|
|
335
|
-
|
|
336
|
-
Enhance the accuracy and relevance of Copilot's completions by providing additional code context from your workspace.
|
|
337
|
-
|
|
338
|
-
```javascript
|
|
339
|
-
registerCopilot(monaco, editor, {
|
|
340
|
-
// ...other options
|
|
341
|
-
externalContext: [
|
|
342
|
-
{
|
|
343
|
-
path: './utils.js',
|
|
344
|
-
content:
|
|
345
|
-
'export const reverse = (str) => str.split("").reverse().join("")',
|
|
346
|
-
},
|
|
347
|
-
],
|
|
348
|
-
});
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
By providing external context, Copilot can offer more intelligent suggestions. For example, if you start typing `const isPalindrome = `, Copilot may suggest using the `reverse` function from `utils.js`.
|
|
352
|
+
## Select and Edit
|
|
352
353
|
|
|
353
|
-
|
|
354
|
+
Select and Edit is a feature that allows you to select code from the editor and edit it inline with AI assistance in the Monaco Editor.
|
|
354
355
|
|
|
355
|
-
|
|
356
|
+
<img width="871" alt="select-and-edit-example" src="https://github.com/user-attachments/assets/87c6245a-7827-47f3-8b59-1f59eec9d2ef">
|
|
356
357
|
|
|
357
|
-
|
|
358
|
-
registerCopilot(monaco, editor, {
|
|
359
|
-
// ...other options
|
|
360
|
-
filename: 'utils.js', // e.g., "index.js", "utils/objects.js"
|
|
361
|
-
});
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
Now, the completions will be more relevant to utilities.
|
|
365
|
-
|
|
366
|
-
### Completions for Specific Technologies
|
|
367
|
-
|
|
368
|
-
Enable completions tailored to specific technologies by using the `technologies` option.
|
|
369
|
-
|
|
370
|
-
```javascript
|
|
371
|
-
registerCopilot(monaco, editor, {
|
|
372
|
-
// ...other options
|
|
373
|
-
technologies: ['react', 'next.js', 'tailwindcss'],
|
|
374
|
-
});
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
This configuration will provide completions relevant to React, Next.js, and Tailwind CSS.
|
|
358
|
+
This feature is coming soon.
|
|
378
359
|
|
|
379
360
|
## Contributing
|
|
380
361
|
|
|
381
|
-
For guidelines on contributing,
|
|
362
|
+
For guidelines on contributing, please read the [contributing guide](https://github.com/arshad-yaseen/monacopilot/blob/main/CONTRIBUTING.md).
|
|
382
363
|
|
|
383
|
-
We welcome contributions from the community to enhance Monacopilot's capabilities and make it even more powerful ❤️
|
|
364
|
+
We welcome contributions from the community to enhance Monacopilot's capabilities and make it even more powerful. ❤️
|
package/build/index.d.mts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import * as monaco from 'monaco-editor';
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
type
|
|
5
|
-
type
|
|
6
|
-
|
|
3
|
+
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
4
|
+
type GroqModel = 'llama-3-70b';
|
|
5
|
+
type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
|
|
6
|
+
type CopilotModel = OpenAIModel | GroqModel | AnthropicModel;
|
|
7
|
+
type CopilotProvider = 'openai' | 'groq' | 'anthropic';
|
|
8
|
+
type PromptData = {
|
|
9
|
+
system: string;
|
|
10
|
+
user: string;
|
|
11
|
+
};
|
|
7
12
|
/**
|
|
8
13
|
* Options for configuring the Copilot instance.
|
|
9
14
|
*/
|
|
10
15
|
interface CopilotOptions {
|
|
11
16
|
/**
|
|
12
|
-
* The
|
|
17
|
+
* The provider to use (e.g., 'openai', 'anthropic', 'groq').
|
|
13
18
|
* If not specified, a default provider will be used.
|
|
14
19
|
*/
|
|
15
|
-
provider?:
|
|
20
|
+
provider?: CopilotProvider;
|
|
16
21
|
/**
|
|
17
|
-
* The model to use for
|
|
22
|
+
* The model to use for copilot AI requests.
|
|
18
23
|
* This can be either:
|
|
19
24
|
* 1. A predefined model name (e.g. 'claude-3-opus'): Use this option if you want to use a model that is built into Monacopilot.
|
|
20
25
|
* If you choose this option, also set the `provider` property to the corresponding provider of the model.
|
|
@@ -22,9 +27,9 @@ interface CopilotOptions {
|
|
|
22
27
|
*
|
|
23
28
|
* If not specified, a default model will be used.
|
|
24
29
|
*/
|
|
25
|
-
model?:
|
|
30
|
+
model?: CopilotModel | CustomCopilotModel;
|
|
26
31
|
}
|
|
27
|
-
type
|
|
32
|
+
type CustomCopilotModel = {
|
|
28
33
|
/**
|
|
29
34
|
* A function to configure the custom model.
|
|
30
35
|
* This function takes the API key and the prompt data and returns the configuration for the custom model.
|
|
@@ -36,31 +41,27 @@ type CustomModel = {
|
|
|
36
41
|
* - headers: Additional HTTP headers for the API request (optional)
|
|
37
42
|
* - body: The request body data for the custom model API (optional)
|
|
38
43
|
*/
|
|
39
|
-
config:
|
|
44
|
+
config: CustomCopilotModelConfig;
|
|
40
45
|
/**
|
|
41
46
|
* A function to transform the response from the custom model.
|
|
42
47
|
* This function takes the raw response from the custom model API
|
|
43
|
-
* and
|
|
48
|
+
* and returns the model generated text or null.
|
|
44
49
|
*
|
|
45
50
|
* @param response - The raw response from the custom model API.
|
|
46
51
|
* The type is 'unknown' because different APIs
|
|
47
52
|
* may return responses in different formats.
|
|
48
|
-
* @returns
|
|
49
|
-
* or an error message. The completion should be the actual
|
|
50
|
-
* text to be inserted or used as the completion, without
|
|
51
|
-
* any metadata or additional structure.
|
|
53
|
+
* @returns The model generated text or null if no valid text could be extracted.
|
|
52
54
|
*/
|
|
53
|
-
transformResponse:
|
|
55
|
+
transformResponse: CustomCopilotModelTransformResponse;
|
|
54
56
|
};
|
|
55
|
-
type
|
|
57
|
+
type CustomCopilotModelConfig = (apiKey: string, prompt: {
|
|
56
58
|
system: string;
|
|
57
59
|
user: string;
|
|
58
60
|
}) => {
|
|
59
61
|
/**
|
|
60
62
|
* The URL endpoint for the custom model's API.
|
|
61
|
-
* This is where the completion request will be sent.
|
|
62
63
|
*/
|
|
63
|
-
endpoint:
|
|
64
|
+
endpoint: string;
|
|
64
65
|
/**
|
|
65
66
|
* Additional HTTP headers to include with the API request.
|
|
66
67
|
* Use this to add any necessary authentication or custom headers.
|
|
@@ -68,11 +69,15 @@ type CustomModelConfig = (apiKey: string, prompt: {
|
|
|
68
69
|
headers?: Record<string, string>;
|
|
69
70
|
/**
|
|
70
71
|
* The data to be sent in the request body to the custom model API.
|
|
71
|
-
* This should contain all necessary parameters for generating a completion.
|
|
72
72
|
*/
|
|
73
73
|
body?: Record<string, unknown>;
|
|
74
74
|
};
|
|
75
|
-
type
|
|
75
|
+
type CustomCopilotModelTransformResponse = (response: unknown) => string | null;
|
|
76
|
+
|
|
77
|
+
type Monaco = typeof monaco;
|
|
78
|
+
type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
|
79
|
+
type CursorPosition = monaco.IPosition;
|
|
80
|
+
|
|
76
81
|
type Endpoint = string;
|
|
77
82
|
type Filename = string;
|
|
78
83
|
type Technologies = string[];
|
|
@@ -91,7 +96,7 @@ type ExternalContext = {
|
|
|
91
96
|
*/
|
|
92
97
|
content: string;
|
|
93
98
|
}[];
|
|
94
|
-
interface
|
|
99
|
+
interface RegisterCompletionOptions {
|
|
95
100
|
/**
|
|
96
101
|
* Language of the current model
|
|
97
102
|
*/
|
|
@@ -101,11 +106,11 @@ interface RegisterCopilotOptions {
|
|
|
101
106
|
*/
|
|
102
107
|
endpoint: Endpoint;
|
|
103
108
|
/**
|
|
104
|
-
* Specifies when
|
|
109
|
+
* Specifies when the completion service should provide code completions.
|
|
105
110
|
*
|
|
106
111
|
* Options:
|
|
107
|
-
* - `'onIdle'`:
|
|
108
|
-
* - `'onTyping'`:
|
|
112
|
+
* - `'onIdle'`: The completion service provides completions after a brief pause in typing.
|
|
113
|
+
* - `'onTyping'`: The completion service offers completions in real-time as you type.
|
|
109
114
|
* - *Note:* Best suited for models with low response latency (e.g., Groq).
|
|
110
115
|
* - *Consideration:* May initiate additional background requests to deliver real-time suggestions.
|
|
111
116
|
*
|
|
@@ -134,23 +139,13 @@ interface RegisterCopilotOptions {
|
|
|
134
139
|
*/
|
|
135
140
|
externalContext?: ExternalContext;
|
|
136
141
|
}
|
|
137
|
-
interface
|
|
142
|
+
interface CompletionRegistration {
|
|
138
143
|
/**
|
|
139
|
-
* Deregisters the
|
|
140
|
-
* This should be called when the
|
|
144
|
+
* Deregisters the completion from the Monaco editor.
|
|
145
|
+
* This should be called when the completion is no longer needed.
|
|
141
146
|
*/
|
|
142
147
|
deregister: () => void;
|
|
143
148
|
}
|
|
144
|
-
|
|
145
|
-
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
146
|
-
type GroqModel = 'llama-3-70b';
|
|
147
|
-
type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
|
|
148
|
-
type CompletionModel = OpenAIModel | GroqModel | AnthropicModel;
|
|
149
|
-
type CompletionProvider = 'openai' | 'groq' | 'anthropic';
|
|
150
|
-
type PromptData = {
|
|
151
|
-
system: string;
|
|
152
|
-
user: string;
|
|
153
|
-
};
|
|
154
149
|
interface CompletionRequest {
|
|
155
150
|
/**
|
|
156
151
|
* The body of the completion request.
|
|
@@ -245,20 +240,6 @@ declare class Copilot {
|
|
|
245
240
|
* Ensures the selected model is supported by the provider.
|
|
246
241
|
*/
|
|
247
242
|
private validateInputs;
|
|
248
|
-
/**
|
|
249
|
-
* Generates the prompt based on the completion metadata and any custom prompt function.
|
|
250
|
-
* @param completionMetadata - The metadata for the completion.
|
|
251
|
-
* @param customPrompt - An optional custom prompt function.
|
|
252
|
-
* @returns The generated prompt.
|
|
253
|
-
*/
|
|
254
|
-
private generatePrompt;
|
|
255
|
-
/**
|
|
256
|
-
* Prepares the request details including endpoint, request body, and headers.
|
|
257
|
-
* @param prompt - The generated prompt.
|
|
258
|
-
* @param customHeaders - Any custom headers to include.
|
|
259
|
-
* @returns An object containing the endpoint, request body, and headers.
|
|
260
|
-
*/
|
|
261
|
-
private prepareRequest;
|
|
262
243
|
/**
|
|
263
244
|
* Sends a completion request to the API and returns the completion.
|
|
264
245
|
* @param request - The completion request containing the body and options.
|
|
@@ -268,12 +249,16 @@ declare class Copilot {
|
|
|
268
249
|
}
|
|
269
250
|
|
|
270
251
|
/**
|
|
271
|
-
* Registers the
|
|
252
|
+
* Registers the completion with the Monaco editor.
|
|
272
253
|
* @param monaco The Monaco instance.
|
|
273
254
|
* @param editor The editor instance.
|
|
274
|
-
* @param options The options for the
|
|
275
|
-
* @returns
|
|
255
|
+
* @param options The options for the completion.
|
|
256
|
+
* @returns CompletionRegistration object with a deregister method.
|
|
257
|
+
*/
|
|
258
|
+
declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
259
|
+
/**
|
|
260
|
+
* @deprecated Use `registerCompletion` instead. This function will be removed in a future version.
|
|
276
261
|
*/
|
|
277
|
-
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options:
|
|
262
|
+
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
278
263
|
|
|
279
|
-
export { type CompletionMetadata, type
|
|
264
|
+
export { type CompletionMetadata, type CompletionRegistration, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, Copilot, type CopilotModel, type CopilotOptions, type CopilotProvider, type CustomCopilotModel, type CustomCopilotModelConfig, type CustomCopilotModelTransformResponse, type Monaco, type RegisterCompletionOptions, type StandaloneCodeEditor, registerCompletion, registerCopilot };
|
package/build/index.d.ts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import * as monaco from 'monaco-editor';
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
type
|
|
5
|
-
type
|
|
6
|
-
|
|
3
|
+
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
4
|
+
type GroqModel = 'llama-3-70b';
|
|
5
|
+
type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
|
|
6
|
+
type CopilotModel = OpenAIModel | GroqModel | AnthropicModel;
|
|
7
|
+
type CopilotProvider = 'openai' | 'groq' | 'anthropic';
|
|
8
|
+
type PromptData = {
|
|
9
|
+
system: string;
|
|
10
|
+
user: string;
|
|
11
|
+
};
|
|
7
12
|
/**
|
|
8
13
|
* Options for configuring the Copilot instance.
|
|
9
14
|
*/
|
|
10
15
|
interface CopilotOptions {
|
|
11
16
|
/**
|
|
12
|
-
* The
|
|
17
|
+
* The provider to use (e.g., 'openai', 'anthropic', 'groq').
|
|
13
18
|
* If not specified, a default provider will be used.
|
|
14
19
|
*/
|
|
15
|
-
provider?:
|
|
20
|
+
provider?: CopilotProvider;
|
|
16
21
|
/**
|
|
17
|
-
* The model to use for
|
|
22
|
+
* The model to use for copilot AI requests.
|
|
18
23
|
* This can be either:
|
|
19
24
|
* 1. A predefined model name (e.g. 'claude-3-opus'): Use this option if you want to use a model that is built into Monacopilot.
|
|
20
25
|
* If you choose this option, also set the `provider` property to the corresponding provider of the model.
|
|
@@ -22,9 +27,9 @@ interface CopilotOptions {
|
|
|
22
27
|
*
|
|
23
28
|
* If not specified, a default model will be used.
|
|
24
29
|
*/
|
|
25
|
-
model?:
|
|
30
|
+
model?: CopilotModel | CustomCopilotModel;
|
|
26
31
|
}
|
|
27
|
-
type
|
|
32
|
+
type CustomCopilotModel = {
|
|
28
33
|
/**
|
|
29
34
|
* A function to configure the custom model.
|
|
30
35
|
* This function takes the API key and the prompt data and returns the configuration for the custom model.
|
|
@@ -36,31 +41,27 @@ type CustomModel = {
|
|
|
36
41
|
* - headers: Additional HTTP headers for the API request (optional)
|
|
37
42
|
* - body: The request body data for the custom model API (optional)
|
|
38
43
|
*/
|
|
39
|
-
config:
|
|
44
|
+
config: CustomCopilotModelConfig;
|
|
40
45
|
/**
|
|
41
46
|
* A function to transform the response from the custom model.
|
|
42
47
|
* This function takes the raw response from the custom model API
|
|
43
|
-
* and
|
|
48
|
+
* and returns the model generated text or null.
|
|
44
49
|
*
|
|
45
50
|
* @param response - The raw response from the custom model API.
|
|
46
51
|
* The type is 'unknown' because different APIs
|
|
47
52
|
* may return responses in different formats.
|
|
48
|
-
* @returns
|
|
49
|
-
* or an error message. The completion should be the actual
|
|
50
|
-
* text to be inserted or used as the completion, without
|
|
51
|
-
* any metadata or additional structure.
|
|
53
|
+
* @returns The model generated text or null if no valid text could be extracted.
|
|
52
54
|
*/
|
|
53
|
-
transformResponse:
|
|
55
|
+
transformResponse: CustomCopilotModelTransformResponse;
|
|
54
56
|
};
|
|
55
|
-
type
|
|
57
|
+
type CustomCopilotModelConfig = (apiKey: string, prompt: {
|
|
56
58
|
system: string;
|
|
57
59
|
user: string;
|
|
58
60
|
}) => {
|
|
59
61
|
/**
|
|
60
62
|
* The URL endpoint for the custom model's API.
|
|
61
|
-
* This is where the completion request will be sent.
|
|
62
63
|
*/
|
|
63
|
-
endpoint:
|
|
64
|
+
endpoint: string;
|
|
64
65
|
/**
|
|
65
66
|
* Additional HTTP headers to include with the API request.
|
|
66
67
|
* Use this to add any necessary authentication or custom headers.
|
|
@@ -68,11 +69,15 @@ type CustomModelConfig = (apiKey: string, prompt: {
|
|
|
68
69
|
headers?: Record<string, string>;
|
|
69
70
|
/**
|
|
70
71
|
* The data to be sent in the request body to the custom model API.
|
|
71
|
-
* This should contain all necessary parameters for generating a completion.
|
|
72
72
|
*/
|
|
73
73
|
body?: Record<string, unknown>;
|
|
74
74
|
};
|
|
75
|
-
type
|
|
75
|
+
type CustomCopilotModelTransformResponse = (response: unknown) => string | null;
|
|
76
|
+
|
|
77
|
+
type Monaco = typeof monaco;
|
|
78
|
+
type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
|
79
|
+
type CursorPosition = monaco.IPosition;
|
|
80
|
+
|
|
76
81
|
type Endpoint = string;
|
|
77
82
|
type Filename = string;
|
|
78
83
|
type Technologies = string[];
|
|
@@ -91,7 +96,7 @@ type ExternalContext = {
|
|
|
91
96
|
*/
|
|
92
97
|
content: string;
|
|
93
98
|
}[];
|
|
94
|
-
interface
|
|
99
|
+
interface RegisterCompletionOptions {
|
|
95
100
|
/**
|
|
96
101
|
* Language of the current model
|
|
97
102
|
*/
|
|
@@ -101,11 +106,11 @@ interface RegisterCopilotOptions {
|
|
|
101
106
|
*/
|
|
102
107
|
endpoint: Endpoint;
|
|
103
108
|
/**
|
|
104
|
-
* Specifies when
|
|
109
|
+
* Specifies when the completion service should provide code completions.
|
|
105
110
|
*
|
|
106
111
|
* Options:
|
|
107
|
-
* - `'onIdle'`:
|
|
108
|
-
* - `'onTyping'`:
|
|
112
|
+
* - `'onIdle'`: The completion service provides completions after a brief pause in typing.
|
|
113
|
+
* - `'onTyping'`: The completion service offers completions in real-time as you type.
|
|
109
114
|
* - *Note:* Best suited for models with low response latency (e.g., Groq).
|
|
110
115
|
* - *Consideration:* May initiate additional background requests to deliver real-time suggestions.
|
|
111
116
|
*
|
|
@@ -134,23 +139,13 @@ interface RegisterCopilotOptions {
|
|
|
134
139
|
*/
|
|
135
140
|
externalContext?: ExternalContext;
|
|
136
141
|
}
|
|
137
|
-
interface
|
|
142
|
+
interface CompletionRegistration {
|
|
138
143
|
/**
|
|
139
|
-
* Deregisters the
|
|
140
|
-
* This should be called when the
|
|
144
|
+
* Deregisters the completion from the Monaco editor.
|
|
145
|
+
* This should be called when the completion is no longer needed.
|
|
141
146
|
*/
|
|
142
147
|
deregister: () => void;
|
|
143
148
|
}
|
|
144
|
-
|
|
145
|
-
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
146
|
-
type GroqModel = 'llama-3-70b';
|
|
147
|
-
type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
|
|
148
|
-
type CompletionModel = OpenAIModel | GroqModel | AnthropicModel;
|
|
149
|
-
type CompletionProvider = 'openai' | 'groq' | 'anthropic';
|
|
150
|
-
type PromptData = {
|
|
151
|
-
system: string;
|
|
152
|
-
user: string;
|
|
153
|
-
};
|
|
154
149
|
interface CompletionRequest {
|
|
155
150
|
/**
|
|
156
151
|
* The body of the completion request.
|
|
@@ -245,20 +240,6 @@ declare class Copilot {
|
|
|
245
240
|
* Ensures the selected model is supported by the provider.
|
|
246
241
|
*/
|
|
247
242
|
private validateInputs;
|
|
248
|
-
/**
|
|
249
|
-
* Generates the prompt based on the completion metadata and any custom prompt function.
|
|
250
|
-
* @param completionMetadata - The metadata for the completion.
|
|
251
|
-
* @param customPrompt - An optional custom prompt function.
|
|
252
|
-
* @returns The generated prompt.
|
|
253
|
-
*/
|
|
254
|
-
private generatePrompt;
|
|
255
|
-
/**
|
|
256
|
-
* Prepares the request details including endpoint, request body, and headers.
|
|
257
|
-
* @param prompt - The generated prompt.
|
|
258
|
-
* @param customHeaders - Any custom headers to include.
|
|
259
|
-
* @returns An object containing the endpoint, request body, and headers.
|
|
260
|
-
*/
|
|
261
|
-
private prepareRequest;
|
|
262
243
|
/**
|
|
263
244
|
* Sends a completion request to the API and returns the completion.
|
|
264
245
|
* @param request - The completion request containing the body and options.
|
|
@@ -268,12 +249,16 @@ declare class Copilot {
|
|
|
268
249
|
}
|
|
269
250
|
|
|
270
251
|
/**
|
|
271
|
-
* Registers the
|
|
252
|
+
* Registers the completion with the Monaco editor.
|
|
272
253
|
* @param monaco The Monaco instance.
|
|
273
254
|
* @param editor The editor instance.
|
|
274
|
-
* @param options The options for the
|
|
275
|
-
* @returns
|
|
255
|
+
* @param options The options for the completion.
|
|
256
|
+
* @returns CompletionRegistration object with a deregister method.
|
|
257
|
+
*/
|
|
258
|
+
declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
259
|
+
/**
|
|
260
|
+
* @deprecated Use `registerCompletion` instead. This function will be removed in a future version.
|
|
276
261
|
*/
|
|
277
|
-
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options:
|
|
262
|
+
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
278
263
|
|
|
279
|
-
export { type CompletionMetadata, type
|
|
264
|
+
export { type CompletionMetadata, type CompletionRegistration, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, Copilot, type CopilotModel, type CopilotOptions, type CopilotProvider, type CustomCopilotModel, type CustomCopilotModelConfig, type CustomCopilotModelTransformResponse, type Monaco, type RegisterCompletionOptions, type StandaloneCodeEditor, registerCompletion, registerCopilot };
|
package/build/index.js
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`);return`
|
|
3
|
-
\x1B[1m\x1B[37m[${n}]\x1B[0m${r==="error"?"\x1B[31m":"\x1B[33m"} [${t}]\x1B[0m \x1B[2m${i}\x1B[0m
|
|
4
|
-
${h}
|
|
5
|
-
`}styleStackTrace(e){return e.split(`
|
|
6
|
-
`).map((n,i)=>i===0?`\x1B[31m${n}\x1B[0m`:`\x1B[2m${n}\x1B[0m`).join(`
|
|
7
|
-
`)}getTimestamp(){return new Date().toISOString()}};var E=class E{constructor(){this.logger=O.getInstance()}static getInstance(){return E.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logger.error(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};E.instance=new E;var $=E;var d=(o,e)=>$.getInstance().handleError(o,e);var q=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},T=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var I=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],ee=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),g=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),oe=o=>{let e=o.split(`
|
|
8
|
-
`);return e[e.length-1].length+1};var F=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),U=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var te=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},Me=(o,e)=>te(o,"GET",e),Re=(o,e,t)=>te(o,"POST",{...t,body:e}),b={GET:Me,POST:Re};var re=(o,e)=>{let t=I(o,e);return!!t&&!Q.has(t)},ne=(o,e)=>{let t=ee(o,e).trim(),r=g(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var v="<<CURSOR>>",ie=o=>o==="javascript"?"latest JavaScript":o,se=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},Oe=o=>{let e=ie(o.language),t=se(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},Ie=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${T(o)}`:"",r=ie(e);return`The code is written${r?` in ${r}`:""}${t}.`},be=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,p=se(n),c=e?`the file named "${e}"`:"a larger project",l=`You are tasked with ${p} for a code snippet. The code is part of ${c}.
|
|
1
|
+
"use strict";var N=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var he=(e,o)=>{for(var t in o)N(e,t,{get:o[t],enumerable:!0})},fe=(e,o,t,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of Ce(o))!ge.call(e,n)&&n!==t&&N(e,n,{get:()=>o[n],enumerable:!(r=ue(o,n))||r.enumerable});return e};var Pe=e=>fe(N({},"__esModule",{value:!0}),e);var Be={};he(Be,{Copilot:()=>O,registerCompletion:()=>j,registerCopilot:()=>de});module.exports=Pe(Be);var w=["groq","openai","anthropic"],Y={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},D={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},G="llama-3-70b",K="groq",X={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},x=.3;var J=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var f=class f{constructor(){}static getInstance(){return f.instance}handleError(o,t){let r=this.getErrorDetails(o),n=`\x1B[31m[${t}]\x1B[0m \x1B[1m${r.message}\x1B[0m`;return console.error(n),r}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};f.instance=new f;var S=f;var C=(e,o)=>S.getInstance().handleError(e,o);var B=(e,o)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(e(...i)),r=null},o)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},P=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var y=(e,o)=>o.getLineContent(e.lineNumber)[e.column-1],z=(e,o)=>o.getLineContent(e.lineNumber).slice(e.column-1),h=(e,o)=>o.getLineContent(e.lineNumber).slice(0,e.column-1),Z=e=>{let o=e.split(`
|
|
2
|
+
`);return o[o.length-1].length+1};var k=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),H=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var Q=async(e,o,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},Ee=(e,o)=>Q(e,"GET",o),Te=(e,o,t)=>Q(e,"POST",{...t,body:o}),R={GET:Ee,POST:Te};var ee=(e,o)=>{let t=y(e,o);return!!t&&!J.has(t)},oe=(e,o)=>{let t=z(e,o).trim(),r=h(e,o).trim();return e.column<=3&&(t!==""||r!=="")};var M="<<CURSOR>>",te=e=>e==="javascript"?"latest JavaScript":e,re=e=>{switch(e){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},xe=e=>{let o=te(e.language),t=re(e.editorState.completionMode),r=o?` ${o}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},ye=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${P(e)}`:"",r=te(o);return`The code is written${r?` in ${r}`:""}${t}.`},Re=e=>{let{filename:o,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=re(n),m=o?`the file named "${o}"`:"a larger project",l=`You are tasked with ${p} for a code snippet. The code is part of ${m}.
|
|
9
3
|
|
|
10
|
-
`;return l+=
|
|
4
|
+
`;return l+=ye(r,t),l+=`
|
|
11
5
|
|
|
12
6
|
Here are the details about how the completion should be generated:
|
|
13
|
-
- The cursor position is marked with '${
|
|
7
|
+
- The cursor position is marked with '${M}'.
|
|
14
8
|
- Your completion must start exactly at the cursor position.
|
|
15
9
|
- Do not repeat any code that appears before or after the cursor.
|
|
16
10
|
- Ensure your completion does not introduce any syntactical or logical errors.
|
|
17
|
-
`,n==="fill-in-the-middle"?l+=` - If filling in the middle, replace '${
|
|
18
|
-
`:n==="completion"&&(l+=` - If completing the code, start from '${
|
|
11
|
+
`,n==="fill-in-the-middle"?l+=` - If filling in the middle, replace '${M}' entirely with your completion.
|
|
12
|
+
`:n==="completion"&&(l+=` - If completing the code, start from '${M}' and provide a logical continuation.
|
|
19
13
|
`),l+=` - Optimize for readability and performance where possible.
|
|
20
14
|
|
|
21
15
|
Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
|
|
@@ -23,16 +17,16 @@ Here are the details about how the completion should be generated:
|
|
|
23
17
|
Here's the code snippet for completion:
|
|
24
18
|
|
|
25
19
|
<code>
|
|
26
|
-
${i}${
|
|
20
|
+
${i}${M}${a}
|
|
27
21
|
</code>`,s&&s.length>0&&(l+=`
|
|
28
22
|
|
|
29
23
|
Additional context from related files:
|
|
30
24
|
|
|
31
|
-
`,l+=s.map(
|
|
32
|
-
${
|
|
25
|
+
`,l+=s.map(c=>`// Path: ${c.path}
|
|
26
|
+
${c.content}
|
|
33
27
|
`).join(`
|
|
34
|
-
`)),l.endsWith(".")?l:`${l}.`};function
|
|
28
|
+
`)),l.endsWith(".")?l:`${l}.`};function q(e){return{system:xe(e),user:Re(e)}}var ne={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Me={createRequestBody:(e,o)=>{let r=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:o.user}]:[{role:"system",content:o.system},{role:"user",content:o.user}];return{model:F(e),temperature:x,messages:r}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Oe={createRequestBody:(e,o)=>({model:F(e),temperature:x,messages:[{role:"system",content:o.system},{role:"user",content:o.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Ie={createRequestBody:(e,o)=>({model:F(e),temperature:x,system:o.system,messages:[{role:"user",content:o.user}],max_tokens:ve(e)}),createHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),parseCompletion:e=>!e.content||typeof e.content!="string"?null:e.content},$={openai:Me,groq:Oe,anthropic:Ie},ie=(e,o,t)=>$[o].createRequestBody(e,t),se=(e,o)=>$[o].createHeaders(e),le=(e,o)=>$[o].parseCompletion(e),F=e=>Y[e],ae=e=>X[e],ve=e=>ne[e]||4096;var O=class{constructor(o,t={}){if(!o)throw new Error("Please provide an API key.");this.apiKey=o,this.provider=t.provider??K,this.model=t.model??G,this.validateInputs()}validateInputs(){if(!w.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${P(w)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!D[this.provider].includes(this.model)){let o=P(D[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${o}`)}}async complete(o){let{body:t,options:r}=o,{completionMetadata:n}=t,{headers:i={},customPrompt:a}=r??{},s=q(n),p=a?{...s,...a(n)}:s,m=ae(this.provider),l,c=se(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let d=this.model.config(this.apiKey,p);m=d.endpoint??m,l=d.body??{},c={...c,...d.headers}}else l=ie(this.model,this.provider,p);c={...c,...i};try{let d=await R.POST(m,l,{headers:c}),u;return typeof this.model=="object"&&"transformResponse"in this.model?u={completion:this.model.transformResponse(d)}:u={completion:le(d,this.provider)},u}catch(d){return{error:C(d,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var I=class e{constructor(o){this.formattedCompletion="";this.formattedCompletion=o}static create(o){return new e(o)}setCompletion(o){return this.formattedCompletion=o,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(o){let t=/```[\s\S]*?```/g,r=o,n;for(;(n=t.exec(o))!==null;){let i=n[0],a=i.split(`
|
|
35
29
|
`).slice(1,-1).join(`
|
|
36
30
|
`);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
37
31
|
|
|
38
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
32
|
+
`),this}build(){return this.formattedCompletion}};var v=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!ee(this.cursorPosition,this.model)&&!oe(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(r=>this.isCacheItemValid(r,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,r){let n=r.getValueInRange(o.range);return h(t,r).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,n)}isPositionValid(o,t,r){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(r)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-r.length&&t.column<=o.range.endColumn}};L.MAX_CACHE_SIZE=10;var b=L;var be="application/json",V=async({filename:e,endpoint:o,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await R.POST(o,{completionMetadata:Le({filename:e,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":be},error:"Error while fetching completion item"});return s}catch(s){return C(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Le=({filename:e,position:o,model:t,language:r,technologies:n,externalContext:i})=>{let a=Ae(o,t),s=k(o,t),p=H(o,t);return{filename:e,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},Ae=(e,o)=>{let t=k(e,o),r=H(e,o);return t&&r?"fill-in-the-middle":"completion"};var pe=(e,o,t,r)=>{let n=(e.match(/\n/g)||[]).length,i=Z(e),a=y(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function ce(e){return I.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=e=>({items:e,enableForwardStability:!0});var _e=300,Ne=600,we={onTyping:B(V,_e),onIdle:B(V,Ne)},A=new b,De=async({monaco:e,model:o,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new v(t,o).shouldProvideCompletions())return g([]);let m=A.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(m.length>0)return i(),g(m);if(r.isCancellationRequested||n)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=we[l];r.onCancellationRequested(()=>{c.cancel()});let d=await c({...p,text:o.getValue(),model:o,position:t});if(d){let u=ce(d),_=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),W=pe(u,_,t,o);return A.addCompletionCache({completion:u,range:W,textBeforeCursorInLine:h(t,o)}),i(),g([{insertText:u,range:W}])}}catch(l){if(Se(l))return g([]);C(l,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},Se=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),me=De;var E=new WeakMap,T=null,j=(e,o,t)=>{T&&T.deregister();let r=[];E.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,m,l)=>{let c=E.get(o);if(c)return me({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=o.onKeyDown(s=>{let p=E.get(o);if(!p)return;let m=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&m?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),A.clearCompletionCache(),E.delete(o),T=null}};return T=a,a}catch(n){return C(n,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),E.delete(o),T=null}}}},de=j;0&&(module.exports={Copilot,registerCompletion,registerCopilot});
|
package/build/index.mjs
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);return`
|
|
3
|
-
\x1B[1m\x1B[37m[${n}]\x1B[0m${r==="error"?"\x1B[31m":"\x1B[33m"} [${t}]\x1B[0m \x1B[2m${i}\x1B[0m
|
|
4
|
-
${h}
|
|
5
|
-
`}styleStackTrace(e){return e.split(`
|
|
6
|
-
`).map((n,i)=>i===0?`\x1B[31m${n}\x1B[0m`:`\x1B[2m${n}\x1B[0m`).join(`
|
|
7
|
-
`)}getTimestamp(){return new Date().toISOString()}};var E=class E{constructor(){this.logger=O.getInstance()}static getInstance(){return E.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logger.error(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};E.instance=new E;var k=E;var d=(o,e)=>k.getInstance().handleError(o,e);var H=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},T=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var I=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],Q=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),g=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),ee=o=>{let e=o.split(`
|
|
8
|
-
`);return e[e.length-1].length+1};var $=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),q=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var oe=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},ge=(o,e)=>oe(o,"GET",e),he=(o,e,t)=>oe(o,"POST",{...t,body:e}),b={GET:ge,POST:he};var te=(o,e)=>{let t=I(o,e);return!!t&&!Z.has(t)},re=(o,e)=>{let t=Q(o,e).trim(),r=g(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var v="<<CURSOR>>",ne=o=>o==="javascript"?"latest JavaScript":o,ie=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},fe=o=>{let e=ne(o.language),t=ie(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},Ee=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${T(o)}`:"",r=ne(e);return`The code is written${r?` in ${r}`:""}${t}.`},Te=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,p=ie(n),c=e?`the file named "${e}"`:"a larger project",l=`You are tasked with ${p} for a code snippet. The code is part of ${c}.
|
|
1
|
+
var _=["groq","openai","anthropic"],j={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},N={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},W="llama-3-70b",Y="groq",G={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},x=.3;var K=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var f=class f{constructor(){}static getInstance(){return f.instance}handleError(o,t){let r=this.getErrorDetails(o),n=`\x1B[31m[${t}]\x1B[0m \x1B[1m${r.message}\x1B[0m`;return console.error(n),r}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};f.instance=new f;var w=f;var C=(e,o)=>w.getInstance().handleError(e,o);var D=(e,o)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(e(...i)),r=null},o)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},P=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var y=(e,o)=>o.getLineContent(e.lineNumber)[e.column-1],X=(e,o)=>o.getLineContent(e.lineNumber).slice(e.column-1),h=(e,o)=>o.getLineContent(e.lineNumber).slice(0,e.column-1),J=e=>{let o=e.split(`
|
|
2
|
+
`);return o[o.length-1].length+1};var S=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),B=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var z=async(e,o,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},me=(e,o)=>z(e,"GET",o),de=(e,o,t)=>z(e,"POST",{...t,body:o}),R={GET:me,POST:de};var Z=(e,o)=>{let t=y(e,o);return!!t&&!K.has(t)},Q=(e,o)=>{let t=X(e,o).trim(),r=h(e,o).trim();return e.column<=3&&(t!==""||r!=="")};var M="<<CURSOR>>",ee=e=>e==="javascript"?"latest JavaScript":e,oe=e=>{switch(e){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},ue=e=>{let o=ee(e.language),t=oe(e.editorState.completionMode),r=o?` ${o}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},Ce=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${P(e)}`:"",r=ee(o);return`The code is written${r?` in ${r}`:""}${t}.`},ge=e=>{let{filename:o,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=oe(n),m=o?`the file named "${o}"`:"a larger project",l=`You are tasked with ${p} for a code snippet. The code is part of ${m}.
|
|
9
3
|
|
|
10
|
-
`;return l+=
|
|
4
|
+
`;return l+=Ce(r,t),l+=`
|
|
11
5
|
|
|
12
6
|
Here are the details about how the completion should be generated:
|
|
13
|
-
- The cursor position is marked with '${
|
|
7
|
+
- The cursor position is marked with '${M}'.
|
|
14
8
|
- Your completion must start exactly at the cursor position.
|
|
15
9
|
- Do not repeat any code that appears before or after the cursor.
|
|
16
10
|
- Ensure your completion does not introduce any syntactical or logical errors.
|
|
17
|
-
`,n==="fill-in-the-middle"?l+=` - If filling in the middle, replace '${
|
|
18
|
-
`:n==="completion"&&(l+=` - If completing the code, start from '${
|
|
11
|
+
`,n==="fill-in-the-middle"?l+=` - If filling in the middle, replace '${M}' entirely with your completion.
|
|
12
|
+
`:n==="completion"&&(l+=` - If completing the code, start from '${M}' and provide a logical continuation.
|
|
19
13
|
`),l+=` - Optimize for readability and performance where possible.
|
|
20
14
|
|
|
21
15
|
Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
|
|
@@ -23,16 +17,16 @@ Here are the details about how the completion should be generated:
|
|
|
23
17
|
Here's the code snippet for completion:
|
|
24
18
|
|
|
25
19
|
<code>
|
|
26
|
-
${i}${
|
|
20
|
+
${i}${M}${a}
|
|
27
21
|
</code>`,s&&s.length>0&&(l+=`
|
|
28
22
|
|
|
29
23
|
Additional context from related files:
|
|
30
24
|
|
|
31
|
-
`,l+=s.map(
|
|
32
|
-
${
|
|
25
|
+
`,l+=s.map(c=>`// Path: ${c.path}
|
|
26
|
+
${c.content}
|
|
33
27
|
`).join(`
|
|
34
|
-
`)),l.endsWith(".")?l:`${l}.`};function
|
|
28
|
+
`)),l.endsWith(".")?l:`${l}.`};function k(e){return{system:ue(e),user:ge(e)}}var te={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var he={createRequestBody:(e,o)=>{let r=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:o.user}]:[{role:"system",content:o.system},{role:"user",content:o.user}];return{model:q(e),temperature:x,messages:r}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},fe={createRequestBody:(e,o)=>({model:q(e),temperature:x,messages:[{role:"system",content:o.system},{role:"user",content:o.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Pe={createRequestBody:(e,o)=>({model:q(e),temperature:x,system:o.system,messages:[{role:"user",content:o.user}],max_tokens:Ee(e)}),createHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),parseCompletion:e=>!e.content||typeof e.content!="string"?null:e.content},H={openai:he,groq:fe,anthropic:Pe},re=(e,o,t)=>H[o].createRequestBody(e,t),ne=(e,o)=>H[o].createHeaders(e),ie=(e,o)=>H[o].parseCompletion(e),q=e=>j[e],se=e=>G[e],Ee=e=>te[e]||4096;var $=class{constructor(o,t={}){if(!o)throw new Error("Please provide an API key.");this.apiKey=o,this.provider=t.provider??Y,this.model=t.model??W,this.validateInputs()}validateInputs(){if(!_.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${P(_)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!N[this.provider].includes(this.model)){let o=P(N[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${o}`)}}async complete(o){let{body:t,options:r}=o,{completionMetadata:n}=t,{headers:i={},customPrompt:a}=r??{},s=k(n),p=a?{...s,...a(n)}:s,m=se(this.provider),l,c=ne(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let d=this.model.config(this.apiKey,p);m=d.endpoint??m,l=d.body??{},c={...c,...d.headers}}else l=re(this.model,this.provider,p);c={...c,...i};try{let d=await R.POST(m,l,{headers:c}),u;return typeof this.model=="object"&&"transformResponse"in this.model?u={completion:this.model.transformResponse(d)}:u={completion:ie(d,this.provider)},u}catch(d){return{error:C(d,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var O=class e{constructor(o){this.formattedCompletion="";this.formattedCompletion=o}static create(o){return new e(o)}setCompletion(o){return this.formattedCompletion=o,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(o){let t=/```[\s\S]*?```/g,r=o,n;for(;(n=t.exec(o))!==null;){let i=n[0],a=i.split(`
|
|
35
29
|
`).slice(1,-1).join(`
|
|
36
30
|
`);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
37
31
|
|
|
38
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
32
|
+
`),this}build(){return this.formattedCompletion}};var I=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!Z(this.cursorPosition,this.model)&&!Q(this.cursorPosition,this.model)}};var b=class b{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(r=>this.isCacheItemValid(r,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(b.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,r){let n=r.getValueInRange(o.range);return h(t,r).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,n)}isPositionValid(o,t,r){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(r)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-r.length&&t.column<=o.range.endColumn}};b.MAX_CACHE_SIZE=10;var v=b;var Te="application/json",U=async({filename:e,endpoint:o,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await R.POST(o,{completionMetadata:xe({filename:e,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":Te},error:"Error while fetching completion item"});return s}catch(s){return C(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},xe=({filename:e,position:o,model:t,language:r,technologies:n,externalContext:i})=>{let a=ye(o,t),s=S(o,t),p=B(o,t);return{filename:e,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},ye=(e,o)=>{let t=S(e,o),r=B(e,o);return t&&r?"fill-in-the-middle":"completion"};var le=(e,o,t,r)=>{let n=(e.match(/\n/g)||[]).length,i=J(e),a=y(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function ae(e){return O.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=e=>({items:e,enableForwardStability:!0});var Re=300,Me=600,Oe={onTyping:D(U,Re),onIdle:D(U,Me)},L=new v,Ie=async({monaco:e,model:o,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new I(t,o).shouldProvideCompletions())return g([]);let m=L.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(m.length>0)return i(),g(m);if(r.isCancellationRequested||n)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=Oe[l];r.onCancellationRequested(()=>{c.cancel()});let d=await c({...p,text:o.getValue(),model:o,position:t});if(d){let u=ae(d),A=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),V=le(u,A,t,o);return L.addCompletionCache({completion:u,range:V,textBeforeCursorInLine:h(t,o)}),i(),g([{insertText:u,range:V}])}}catch(l){if(ve(l))return g([]);C(l,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},ve=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),pe=Ie;var E=new WeakMap,T=null,ce=(e,o,t)=>{T&&T.deregister();let r=[];E.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,m,l)=>{let c=E.get(o);if(c)return pe({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=o.onKeyDown(s=>{let p=E.get(o);if(!p)return;let m=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&m?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),L.clearCompletionCache(),E.delete(o),T=null}};return T=a,a}catch(n){return C(n,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),E.delete(o),T=null}}}},be=ce;export{$ as Copilot,ce as registerCompletion,be as registerCopilot};
|