monacopilot 0.9.34 → 0.10.0
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 +142 -165
- package/build/index.d.mts +52 -57
- package/build/index.d.ts +52 -57
- package/build/index.js +23 -28
- package/build/index.mjs +23 -28
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
# Monacopilot
|
|
4
4
|
|
|
@@ -7,34 +7,39 @@
|
|
|
7
7
|
## Table of Contents
|
|
8
8
|
|
|
9
9
|
- [Examples](#examples)
|
|
10
|
-
- [
|
|
11
|
-
- [
|
|
10
|
+
- [Inline Completions](#inline-completions)
|
|
11
|
+
- [Installation](#installation)
|
|
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)
|
|
34
35
|
- [Pages Router](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/pages)
|
|
35
36
|
- [Remix](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/remix)
|
|
36
37
|
|
|
37
|
-
##
|
|
38
|
+
## Inline Completions
|
|
39
|
+
|
|
40
|
+
[Inline Completions Demo Video](https://github.com/user-attachments/assets/f2ec4ae1-f658-4002-af9c-c6b1bbad70d9)
|
|
41
|
+
|
|
42
|
+
### Installation
|
|
38
43
|
|
|
39
44
|
To install Monacopilot, run:
|
|
40
45
|
|
|
@@ -42,28 +47,15 @@ To install Monacopilot, run:
|
|
|
42
47
|
npm install monacopilot
|
|
43
48
|
```
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
## Usage
|
|
48
|
-
|
|
49
|
-
#### Setting Up the API Key
|
|
50
|
-
|
|
51
|
-
In this example, we'll use Groq as our provider.
|
|
52
|
-
|
|
53
|
-
Start by obtaining an API key from the [Groq console](https://console.groq.com/keys). Once you have your API key, define it as an environment variable in your project:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
# .env.local
|
|
57
|
-
GROQ_API_KEY=your-api-key
|
|
58
|
-
```
|
|
50
|
+
### Usage
|
|
59
51
|
|
|
60
52
|
#### API Handler
|
|
61
53
|
|
|
62
54
|
Set up an API handler to manage auto-completion requests. An example using Express.js:
|
|
63
55
|
|
|
64
56
|
```javascript
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
import express from 'express';
|
|
58
|
+
import {Copilot} from 'monacopilot';
|
|
67
59
|
|
|
68
60
|
const app = express();
|
|
69
61
|
const port = process.env.PORT || 3000;
|
|
@@ -71,7 +63,7 @@ const copilot = new Copilot(process.env.GROQ_API_KEY);
|
|
|
71
63
|
|
|
72
64
|
app.use(express.json());
|
|
73
65
|
|
|
74
|
-
app.post('/
|
|
66
|
+
app.post('/complete', async (req, res) => {
|
|
75
67
|
const completion = await copilot.complete({
|
|
76
68
|
body: req.body,
|
|
77
69
|
});
|
|
@@ -81,24 +73,24 @@ app.post('/copilot', async (req, res) => {
|
|
|
81
73
|
app.listen(port);
|
|
82
74
|
```
|
|
83
75
|
|
|
84
|
-
|
|
76
|
+
Now, Monacopilot is set up to send completion requests to the `/complete` endpoint and receive completions in response.
|
|
85
77
|
|
|
86
78
|
The `copilot.complete` method processes the request body sent by Monacopilot and returns the corresponding completion.
|
|
87
79
|
|
|
88
|
-
#### Register
|
|
80
|
+
#### Register Completion with the Monaco Editor
|
|
89
81
|
|
|
90
|
-
Now, let's integrate
|
|
82
|
+
Now, let's integrate AI auto-completion into your Monaco editor. Here's how you can do it:
|
|
91
83
|
|
|
92
84
|
```javascript
|
|
93
85
|
import * as monaco from 'monaco-editor';
|
|
94
|
-
import {
|
|
86
|
+
import {registerCompletion} from 'monacopilot';
|
|
95
87
|
|
|
96
88
|
const editor = monaco.editor.create(document.getElementById('container'), {
|
|
97
89
|
language: 'javascript',
|
|
98
90
|
});
|
|
99
91
|
|
|
100
|
-
|
|
101
|
-
endpoint: 'https://api.example.com/
|
|
92
|
+
registerCompletion(monaco, editor, {
|
|
93
|
+
endpoint: 'https://api.example.com/complete',
|
|
102
94
|
language: 'javascript',
|
|
103
95
|
});
|
|
104
96
|
```
|
|
@@ -108,13 +100,80 @@ registerCopilot(monaco, editor, {
|
|
|
108
100
|
| `endpoint` | `string` | The URL of the API endpoint that we created in the previous step. |
|
|
109
101
|
| `language` | `string` | The language of the editor. |
|
|
110
102
|
|
|
111
|
-
🎉
|
|
103
|
+
🎉 Congratulations! The AI auto-completion is now connected to the Monaco Editor. Start typing and see completions in the editor.
|
|
104
|
+
|
|
105
|
+
## Register Completion Options
|
|
106
|
+
|
|
107
|
+
### External Context
|
|
108
|
+
|
|
109
|
+
Enhance the accuracy and relevance of Copilot's completions by providing additional code context from your workspace.
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
registerCompletion(monaco, editor, {
|
|
113
|
+
// ...other options
|
|
114
|
+
externalContext: [
|
|
115
|
+
{
|
|
116
|
+
path: './utils.js',
|
|
117
|
+
content:
|
|
118
|
+
'export const reverse = (str) => str.split("").reverse().join("")',
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
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`.
|
|
125
|
+
|
|
126
|
+
### Filename
|
|
127
|
+
|
|
128
|
+
Specify the name of the file being edited to receive more contextually relevant completions.
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
registerCompletion(monaco, editor, {
|
|
132
|
+
// ...other options
|
|
133
|
+
filename: 'utils.js', // e.g., "index.js", "utils/objects.js"
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Now, the completions will be more relevant to the file's context.
|
|
138
|
+
|
|
139
|
+
### Completions for Specific Technologies
|
|
140
|
+
|
|
141
|
+
Enable completions tailored to specific technologies by using the `technologies` option.
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
registerCompletion(monaco, editor, {
|
|
145
|
+
// ...other options
|
|
146
|
+
technologies: ['react', 'next.js', 'tailwindcss'],
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This configuration will provide completions relevant to React, Next.js, and Tailwind CSS.
|
|
151
|
+
|
|
152
|
+
### Get Completions in Real-Time
|
|
153
|
+
|
|
154
|
+
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.
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
registerCompletion(monaco, editor, {
|
|
158
|
+
// ...other options
|
|
159
|
+
trigger: 'onTyping',
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
| Trigger | Description | Notes |
|
|
164
|
+
| -------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
165
|
+
| `'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. |
|
|
166
|
+
| `'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. |
|
|
167
|
+
|
|
168
|
+
[OnTyping Demo](https://github.com/user-attachments/assets/22c2ce44-334c-4963-b853-01b890b8e39f)
|
|
169
|
+
|
|
170
|
+
> **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
171
|
|
|
113
172
|
## Copilot Options
|
|
114
173
|
|
|
115
174
|
### Changing the Provider and Model
|
|
116
175
|
|
|
117
|
-
You can specify a different provider and model
|
|
176
|
+
You can specify a different provider and model by setting the `provider` and `model` parameters in the `Copilot` instance.
|
|
118
177
|
|
|
119
178
|
```javascript
|
|
120
179
|
const copilot = new Copilot(process.env.OPENAI_API_KEY, {
|
|
@@ -123,7 +182,7 @@ const copilot = new Copilot(process.env.OPENAI_API_KEY, {
|
|
|
123
182
|
});
|
|
124
183
|
```
|
|
125
184
|
|
|
126
|
-
The default provider is `groq
|
|
185
|
+
The default provider is `groq`, and the default model is `llama-3-70b`.
|
|
127
186
|
|
|
128
187
|
There are other providers and models available. Here is a list:
|
|
129
188
|
|
|
@@ -137,13 +196,14 @@ There are other providers and models available. Here is a list:
|
|
|
137
196
|
|
|
138
197
|
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
198
|
|
|
140
|
-
Please
|
|
199
|
+
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.
|
|
141
200
|
|
|
142
201
|
#### Example
|
|
143
202
|
|
|
144
203
|
```javascript
|
|
145
204
|
const copilot = new Copilot(process.env.HUGGINGFACE_API_KEY, {
|
|
146
|
-
//
|
|
205
|
+
// You don't need to set the provider if you are using a custom model.
|
|
206
|
+
// provider: 'huggingface',
|
|
147
207
|
model: {
|
|
148
208
|
config: (apiKey, prompt) => ({
|
|
149
209
|
endpoint:
|
|
@@ -161,18 +221,7 @@ const copilot = new Copilot(process.env.HUGGINGFACE_API_KEY, {
|
|
|
161
221
|
},
|
|
162
222
|
},
|
|
163
223
|
}),
|
|
164
|
-
transformResponse: response =>
|
|
165
|
-
if (response.error) {
|
|
166
|
-
return {
|
|
167
|
-
completion: null,
|
|
168
|
-
error: response.error,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return {
|
|
173
|
-
completion: response[0].generated_text,
|
|
174
|
-
};
|
|
175
|
-
},
|
|
224
|
+
transformResponse: response => response[0].generated_text,
|
|
176
225
|
},
|
|
177
226
|
});
|
|
178
227
|
```
|
|
@@ -181,27 +230,20 @@ const copilot = new Copilot(process.env.HUGGINGFACE_API_KEY, {
|
|
|
181
230
|
|
|
182
231
|
The `model` option accepts an object with two functions:
|
|
183
232
|
|
|
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
|
|
233
|
+
| Function | Description | Type |
|
|
234
|
+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
235
|
+
| `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 }` |
|
|
236
|
+
| `transformResponse` | A function that takes the raw/parsed response from the custom model API and returns an object with the `text` property. | `(response: unknown) => { text: string \| null; }` |
|
|
188
237
|
|
|
189
238
|
The `config` function must return an object with the following properties:
|
|
190
239
|
|
|
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:
|
|
198
|
-
|
|
199
|
-
| Property | Type | Description |
|
|
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. |
|
|
240
|
+
| Property | Type | Description |
|
|
241
|
+
| ---------- | ----------------------- | -------------------------------------------- |
|
|
242
|
+
| `endpoint` | `string` | The URL of the custom model API endpoint. |
|
|
243
|
+
| `body` | `object` or `undefined` | The body of the custom model API request. |
|
|
244
|
+
| `headers` | `object` or `undefined` | The headers of the custom model API request. |
|
|
203
245
|
|
|
204
|
-
|
|
246
|
+
The `transformResponse` function must return an object with the `text` property. This `text` property should contain the text generated by the custom model. If no valid text can be extracted, the function should return `null` for the `text` property.
|
|
205
247
|
|
|
206
248
|
## Completion Request Options
|
|
207
249
|
|
|
@@ -211,7 +253,6 @@ You can add custom headers to the provider's completion requests. For example, i
|
|
|
211
253
|
|
|
212
254
|
```javascript
|
|
213
255
|
copilot.complete({
|
|
214
|
-
body,
|
|
215
256
|
options: {
|
|
216
257
|
// ...other options
|
|
217
258
|
headers: {
|
|
@@ -229,7 +270,6 @@ You can customize the prompt used for generating completions by providing a `cus
|
|
|
229
270
|
|
|
230
271
|
```javascript
|
|
231
272
|
copilot.complete({
|
|
232
|
-
body,
|
|
233
273
|
options: {
|
|
234
274
|
customPrompt: metadata => ({
|
|
235
275
|
system: 'Your custom system prompt here',
|
|
@@ -239,11 +279,10 @@ copilot.complete({
|
|
|
239
279
|
});
|
|
240
280
|
```
|
|
241
281
|
|
|
242
|
-
The `system` and `user` prompts in the `customPrompt` function are optional.
|
|
282
|
+
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
283
|
|
|
244
284
|
```javascript
|
|
245
285
|
copilot.complete({
|
|
246
|
-
body,
|
|
247
286
|
options: {
|
|
248
287
|
customPrompt: metadata => ({
|
|
249
288
|
system:
|
|
@@ -255,34 +294,34 @@ copilot.complete({
|
|
|
255
294
|
|
|
256
295
|
#### Parameters
|
|
257
296
|
|
|
258
|
-
The `customPrompt` function receives a `completionMetadata` object
|
|
297
|
+
The `customPrompt` function receives a `completionMetadata` object, which contains information about the current editor state and can be used to tailor the prompt.
|
|
259
298
|
|
|
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`
|
|
299
|
+
| Property | Type | Description |
|
|
300
|
+
| ------------------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
301
|
+
| `language` | `string` | The programming language of the code. |
|
|
302
|
+
| `cursorPosition` | `{ lineNumber: number; column: number }` | The current cursor position in the editor. |
|
|
303
|
+
| `filename` | `string` or `undefined` | The name of the file being edited. Only available if you have provided the `filename` option in the `registerCompletion` function. |
|
|
304
|
+
| `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. |
|
|
305
|
+
| `externalContext` | `object` or `undefined` | Additional context from related files. Only available if you have provided the `externalContext` option in the `registerCompletion` function. |
|
|
306
|
+
| `textAfterCursor` | `string` | The text that appears after the cursor. |
|
|
307
|
+
| `textBeforeCursor` | `string` | The text that appears before the cursor. |
|
|
308
|
+
| `editorState` | `object` | An object containing the `completionMode` property. |
|
|
270
309
|
|
|
271
310
|
The `editorState.completionMode` can be one of the following:
|
|
272
311
|
|
|
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. |
|
|
312
|
+
| Mode | Description |
|
|
313
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
314
|
+
| `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. |
|
|
315
|
+
| `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
316
|
|
|
278
317
|
For additional `completionMetadata` needs, please [open an issue](https://github.com/arshad-yaseen/monacopilot/issues/new).
|
|
279
318
|
|
|
280
319
|
The `customPrompt` function should return an object with two properties:
|
|
281
320
|
|
|
282
|
-
| Property | Type
|
|
283
|
-
| -------- |
|
|
284
|
-
| system
|
|
285
|
-
| user
|
|
321
|
+
| Property | Type | Description |
|
|
322
|
+
| -------- | ----------------------- | ------------------------------------------------------ |
|
|
323
|
+
| `system` | `string` or `undefined` | A string representing the system prompt for the model. |
|
|
324
|
+
| `user` | `string` or `undefined` | A string representing the user prompt for the model. |
|
|
286
325
|
|
|
287
326
|
#### Example
|
|
288
327
|
|
|
@@ -294,90 +333,28 @@ const customPrompt = ({textBeforeCursor, textAfterCursor}) => ({
|
|
|
294
333
|
'You are an AI assistant specialized in writing React components. Focus on creating clean, reusable, and well-structured components.',
|
|
295
334
|
user: `Please complete the following React component:
|
|
296
335
|
|
|
297
|
-
${textBeforeCursor}
|
|
298
|
-
// Cursor position
|
|
299
|
-
${textAfterCursor}
|
|
336
|
+
${textBeforeCursor}
|
|
337
|
+
// Cursor position
|
|
338
|
+
${textAfterCursor}
|
|
300
339
|
|
|
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.`,
|
|
340
|
+
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
341
|
});
|
|
303
342
|
|
|
304
343
|
copilot.complete({
|
|
305
|
-
body,
|
|
306
344
|
options: {customPrompt},
|
|
307
345
|
});
|
|
308
346
|
```
|
|
309
347
|
|
|
310
348
|
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
349
|
|
|
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
|
-
> **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 is not too costly since most small models are very inexpensive.
|
|
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
|
-
|
|
353
|
-
### Filename
|
|
354
|
-
|
|
355
|
-
Specify the name of the file being edited to receive more contextually relevant completions.
|
|
356
|
-
|
|
357
|
-
```javascript
|
|
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
|
|
350
|
+
## Select and Edit
|
|
367
351
|
|
|
368
|
-
|
|
352
|
+
Select and Edit is a feature that allows you to select code from the editor and edit it inline with AI assistance.
|
|
369
353
|
|
|
370
|
-
|
|
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.
|
|
354
|
+
This feature is coming soon™️.
|
|
378
355
|
|
|
379
356
|
## Contributing
|
|
380
357
|
|
|
381
|
-
For guidelines on contributing,
|
|
358
|
+
For guidelines on contributing, please read the [contributing guide](https://github.com/arshad-yaseen/monacopilot/blob/main/CONTRIBUTING.md).
|
|
382
359
|
|
|
383
|
-
We welcome contributions from the community to enhance Monacopilot's capabilities and make it even more powerful ❤️
|
|
360
|
+
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,25 @@ 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) => {
|
|
76
|
+
/**
|
|
77
|
+
* The text generated by the custom model.
|
|
78
|
+
*/
|
|
79
|
+
text: string | null;
|
|
80
|
+
/**
|
|
81
|
+
* The text generated by the custom model.
|
|
82
|
+
* @deprecated Use `text` instead. This property will be removed in a future version.
|
|
83
|
+
*/
|
|
84
|
+
completion: string | null;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type Monaco = typeof monaco;
|
|
88
|
+
type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
|
89
|
+
type CursorPosition = monaco.IPosition;
|
|
90
|
+
|
|
76
91
|
type Endpoint = string;
|
|
77
92
|
type Filename = string;
|
|
78
93
|
type Technologies = string[];
|
|
@@ -91,7 +106,7 @@ type ExternalContext = {
|
|
|
91
106
|
*/
|
|
92
107
|
content: string;
|
|
93
108
|
}[];
|
|
94
|
-
interface
|
|
109
|
+
interface RegisterCompletionOptions {
|
|
95
110
|
/**
|
|
96
111
|
* Language of the current model
|
|
97
112
|
*/
|
|
@@ -101,11 +116,11 @@ interface RegisterCopilotOptions {
|
|
|
101
116
|
*/
|
|
102
117
|
endpoint: Endpoint;
|
|
103
118
|
/**
|
|
104
|
-
* Specifies when
|
|
119
|
+
* Specifies when the completion service should provide code completions.
|
|
105
120
|
*
|
|
106
121
|
* Options:
|
|
107
|
-
* - `'onIdle'`:
|
|
108
|
-
* - `'onTyping'`:
|
|
122
|
+
* - `'onIdle'`: The completion service provides completions after a brief pause in typing.
|
|
123
|
+
* - `'onTyping'`: The completion service offers completions in real-time as you type.
|
|
109
124
|
* - *Note:* Best suited for models with low response latency (e.g., Groq).
|
|
110
125
|
* - *Consideration:* May initiate additional background requests to deliver real-time suggestions.
|
|
111
126
|
*
|
|
@@ -134,23 +149,13 @@ interface RegisterCopilotOptions {
|
|
|
134
149
|
*/
|
|
135
150
|
externalContext?: ExternalContext;
|
|
136
151
|
}
|
|
137
|
-
interface
|
|
152
|
+
interface CompletionRegistration {
|
|
138
153
|
/**
|
|
139
|
-
* Deregisters the
|
|
140
|
-
* This should be called when the
|
|
154
|
+
* Deregisters the completion from the Monaco editor.
|
|
155
|
+
* This should be called when the completion is no longer needed.
|
|
141
156
|
*/
|
|
142
157
|
deregister: () => void;
|
|
143
158
|
}
|
|
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
159
|
interface CompletionRequest {
|
|
155
160
|
/**
|
|
156
161
|
* The body of the completion request.
|
|
@@ -245,20 +250,6 @@ declare class Copilot {
|
|
|
245
250
|
* Ensures the selected model is supported by the provider.
|
|
246
251
|
*/
|
|
247
252
|
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
253
|
/**
|
|
263
254
|
* Sends a completion request to the API and returns the completion.
|
|
264
255
|
* @param request - The completion request containing the body and options.
|
|
@@ -268,12 +259,16 @@ declare class Copilot {
|
|
|
268
259
|
}
|
|
269
260
|
|
|
270
261
|
/**
|
|
271
|
-
* Registers the
|
|
262
|
+
* Registers the completion with the Monaco editor.
|
|
272
263
|
* @param monaco The Monaco instance.
|
|
273
264
|
* @param editor The editor instance.
|
|
274
|
-
* @param options The options for the
|
|
275
|
-
* @returns
|
|
265
|
+
* @param options The options for the completion.
|
|
266
|
+
* @returns CompletionRegistration object with a deregister method.
|
|
267
|
+
*/
|
|
268
|
+
declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
269
|
+
/**
|
|
270
|
+
* @deprecated Use `registerCompletion` instead. This function will be removed in a future version.
|
|
276
271
|
*/
|
|
277
|
-
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options:
|
|
272
|
+
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
278
273
|
|
|
279
|
-
export { type CompletionMetadata, type
|
|
274
|
+
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,25 @@ 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) => {
|
|
76
|
+
/**
|
|
77
|
+
* The text generated by the custom model.
|
|
78
|
+
*/
|
|
79
|
+
text: string | null;
|
|
80
|
+
/**
|
|
81
|
+
* The text generated by the custom model.
|
|
82
|
+
* @deprecated Use `text` instead. This property will be removed in a future version.
|
|
83
|
+
*/
|
|
84
|
+
completion: string | null;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type Monaco = typeof monaco;
|
|
88
|
+
type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
|
89
|
+
type CursorPosition = monaco.IPosition;
|
|
90
|
+
|
|
76
91
|
type Endpoint = string;
|
|
77
92
|
type Filename = string;
|
|
78
93
|
type Technologies = string[];
|
|
@@ -91,7 +106,7 @@ type ExternalContext = {
|
|
|
91
106
|
*/
|
|
92
107
|
content: string;
|
|
93
108
|
}[];
|
|
94
|
-
interface
|
|
109
|
+
interface RegisterCompletionOptions {
|
|
95
110
|
/**
|
|
96
111
|
* Language of the current model
|
|
97
112
|
*/
|
|
@@ -101,11 +116,11 @@ interface RegisterCopilotOptions {
|
|
|
101
116
|
*/
|
|
102
117
|
endpoint: Endpoint;
|
|
103
118
|
/**
|
|
104
|
-
* Specifies when
|
|
119
|
+
* Specifies when the completion service should provide code completions.
|
|
105
120
|
*
|
|
106
121
|
* Options:
|
|
107
|
-
* - `'onIdle'`:
|
|
108
|
-
* - `'onTyping'`:
|
|
122
|
+
* - `'onIdle'`: The completion service provides completions after a brief pause in typing.
|
|
123
|
+
* - `'onTyping'`: The completion service offers completions in real-time as you type.
|
|
109
124
|
* - *Note:* Best suited for models with low response latency (e.g., Groq).
|
|
110
125
|
* - *Consideration:* May initiate additional background requests to deliver real-time suggestions.
|
|
111
126
|
*
|
|
@@ -134,23 +149,13 @@ interface RegisterCopilotOptions {
|
|
|
134
149
|
*/
|
|
135
150
|
externalContext?: ExternalContext;
|
|
136
151
|
}
|
|
137
|
-
interface
|
|
152
|
+
interface CompletionRegistration {
|
|
138
153
|
/**
|
|
139
|
-
* Deregisters the
|
|
140
|
-
* This should be called when the
|
|
154
|
+
* Deregisters the completion from the Monaco editor.
|
|
155
|
+
* This should be called when the completion is no longer needed.
|
|
141
156
|
*/
|
|
142
157
|
deregister: () => void;
|
|
143
158
|
}
|
|
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
159
|
interface CompletionRequest {
|
|
155
160
|
/**
|
|
156
161
|
* The body of the completion request.
|
|
@@ -245,20 +250,6 @@ declare class Copilot {
|
|
|
245
250
|
* Ensures the selected model is supported by the provider.
|
|
246
251
|
*/
|
|
247
252
|
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
253
|
/**
|
|
263
254
|
* Sends a completion request to the API and returns the completion.
|
|
264
255
|
* @param request - The completion request containing the body and options.
|
|
@@ -268,12 +259,16 @@ declare class Copilot {
|
|
|
268
259
|
}
|
|
269
260
|
|
|
270
261
|
/**
|
|
271
|
-
* Registers the
|
|
262
|
+
* Registers the completion with the Monaco editor.
|
|
272
263
|
* @param monaco The Monaco instance.
|
|
273
264
|
* @param editor The editor instance.
|
|
274
|
-
* @param options The options for the
|
|
275
|
-
* @returns
|
|
265
|
+
* @param options The options for the completion.
|
|
266
|
+
* @returns CompletionRegistration object with a deregister method.
|
|
267
|
+
*/
|
|
268
|
+
declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
269
|
+
/**
|
|
270
|
+
* @deprecated Use `registerCompletion` instead. This function will be removed in a future version.
|
|
276
271
|
*/
|
|
277
|
-
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options:
|
|
272
|
+
declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
278
273
|
|
|
279
|
-
export { type CompletionMetadata, type
|
|
274
|
+
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,38 +1,33 @@
|
|
|
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 w=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var he=(e,o)=>{for(var t in o)w(e,t,{get:o[t],enumerable:!0})},fe=(e,o,t,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of Ce(o))!ge.call(e,r)&&r!==t&&w(e,r,{get:()=>o[r],enumerable:!(n=ue(o,r))||n.enumerable});return e};var Pe=e=>fe(w({},"__esModule",{value:!0}),e);var Be={};he(Be,{Copilot:()=>I,registerCompletion:()=>j,registerCopilot:()=>me});module.exports=Pe(Be);var N=["groq","openai","anthropic"],G={"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"]},K="llama-3-70b",Y="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"},y=.3;var z=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var P=class P{constructor(){}static getInstance(){return P.instance}handleError(o,t){let n=this.getErrorDetails(o),r=`\x1B[31m[${t}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};P.instance=new P;var S=P;var C=(e,o)=>S.getInstance().handleError(e,o);var B=(e,o)=>{let t=null,n=null,r=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),n&&n("Cancelled")),n=s,t=setTimeout(()=>{a(e(...i)),n=null},o)});return r.cancel=()=>{t&&(clearTimeout(t),n&&n("Cancelled"),t=null,n=null)},r},E=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var R=(e,o)=>o.getLineContent(e.lineNumber)[e.column-1],J=(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 n={"Content-Type":"application/json",...t.headers},r=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:n,body:r,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}),M={GET:Ee,POST:Te};var ee=(e,o)=>{let t=R(e,o);return!!t&&!z.has(t)},oe=(e,o)=>{let t=J(e,o).trim(),n=h(e,o).trim();return e.column<=3&&(t!==""||n!=="")};var O="<<CURSOR>>",te=e=>e==="javascript"?"latest JavaScript":e,ne=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=ne(e.editorState.completionMode);return`You are an AI coding assistant with expertise in${o?` ${o}`:""} programming, specializing in ${t}. Your goal is to provide accurate, efficient, and context-aware code completions that align with the existing code and the developer's intent. Provide code that is syntactically correct, follows best practices, and integrates seamlessly with the provided code snippet.`},ye=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${E(e)}`:"",n=te(o);return`The code is written${n?` in ${n}`:""}${t}.`},Re=e=>{let{filename:o,language:t,technologies:n,editorState:{completionMode:r},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=ne(r),d=o?`the file named "${o}"`:"a larger project",l=`Please assist with ${p} for the following code snippet, which is part of ${d}.
|
|
9
3
|
|
|
10
|
-
`;return l+=
|
|
4
|
+
`;return l+=ye(n,t),l+=`
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
Please follow these guidelines when generating the completion:
|
|
7
|
+
- The cursor position is indicated by '${O}' in the code snippet.
|
|
8
|
+
- Begin your completion exactly at the cursor position.
|
|
9
|
+
- Do not duplicate any code that appears before or after the cursor in the provided snippet.
|
|
10
|
+
- Ensure that the completed code is syntactically correct and logically consistent with the surrounding code.
|
|
11
|
+
- Maintain the coding style and conventions used in the existing code.
|
|
12
|
+
- Optimize the code for readability and performance where applicable.
|
|
13
|
+
- Do not include any additional explanations or comments in your output.
|
|
14
|
+
- Output only the code completion, without wrapping it in markdown code syntax (e.g., no triple backticks).`,r==="fill-in-the-middle"?l+=`
|
|
15
|
+
- Since you are filling in the middle, replace '${O}' entirely with your completion.`:r==="completion"&&(l+=`
|
|
16
|
+
- Since you are completing the code, provide a logical continuation starting from '${O}'.`),l+=`
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
Here's the code snippet for completion:
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
${i}${v}${a}
|
|
27
|
-
</code>`,s&&s.length>0&&(l+=`
|
|
20
|
+
<code>
|
|
21
|
+
${i}${O}${a}
|
|
22
|
+
</code>`,s&&s.length>0&&(l+=`
|
|
28
23
|
|
|
29
24
|
Additional context from related files:
|
|
30
25
|
|
|
31
|
-
`,l+=s.map(
|
|
32
|
-
${
|
|
26
|
+
`,l+=s.map(c=>`// Path: ${c.path}
|
|
27
|
+
${c.content}
|
|
33
28
|
`).join(`
|
|
34
|
-
`)),l.endsWith(".")?l:`${l}.`};function
|
|
29
|
+
`)),l.endsWith(".")?l:`${l}.`};function q(e){return{system:xe(e),user:Re(e)}}var re={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Me={createRequestBody:(e,o)=>{let n=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:y,messages:n}},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:y,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:y,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=>G[e],ae=e=>X[e],ve=e=>re[e]||4096;var I=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??K,this.validateInputs()}validateInputs(){if(!N.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${E(N)}. 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=E(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:n}=o,{completionMetadata:r}=t,{headers:i={},customPrompt:a}=n??{},s=q(r),p=a?{...s,...a(r)}:s,d=ae(this.provider),l,c=se(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let m=this.model.config(this.apiKey,p);d=m.endpoint??d,l=m.body??{},c={...c,...m.headers}}else l=ie(this.model,this.provider,p);c={...c,...i};try{let m=await M.POST(d,l,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(m);u={completion:f.text??f.completion}}else u={completion:le(m,this.provider)};return u}catch(m){return{error:C(m,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var v=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,n=o,r;for(;(r=t.exec(o))!==null;){let i=r[0],a=i.split(`
|
|
35
30
|
`).slice(1,-1).join(`
|
|
36
|
-
`);
|
|
31
|
+
`);n=n.replace(i,a)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
37
32
|
|
|
38
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
33
|
+
`),this}build(){return this.formattedCompletion}};var b=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!ee(this.cursorPosition,this.model)&&!oe(this.cursorPosition,this.model)}};var A=class A{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(n=>this.isCacheItemValid(n,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(A.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,n){let r=n.getValueInRange(o.range);return h(t,n).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,r)}isPositionValid(o,t,n){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(n)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-n.length&&t.column<=o.range.endColumn}};A.MAX_CACHE_SIZE=10;var L=A;var be="application/json",V=async({filename:e,endpoint:o,language:t,technologies:n,externalContext:r,model:i,position:a})=>{try{let{completion:s}=await M.POST(o,{completionMetadata:Le({filename:e,position:a,model:i,language:t,technologies:n,externalContext:r})},{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:n,technologies:r,externalContext:i})=>{let a=Ae(o,t),s=k(o,t),p=H(o,t);return{filename:e,language:n,technologies:r,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},Ae=(e,o)=>{let t=k(e,o),n=H(e,o);return t&&n?"fill-in-the-middle":"completion"};var pe=(e,o,t,n)=>{let r=(e.match(/\n/g)||[]).length,i=Z(e),a=R(t,n);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+r,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&r===0?t.column+(i-1):i:t.column}};function ce(e){return v.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=e=>({items:e,enableForwardStability:!0});var _e=300,we=600,Ne={onTyping:B(V,_e),onIdle:B(V,we)},_=new L,De=async({monaco:e,model:o,position:t,token:n,isCompletionAccepted:r,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new b(t,o).shouldProvideCompletions())return g([]);let d=_.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(d.length>0)return i(),g(d);if(n.isCancellationRequested||r)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=Ne[l];n.onCancellationRequested(()=>{c.cancel()});let m=await c({...p,text:o.getValue(),model:o,position:t});if(m){let u=ce(m),f=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),W=pe(u,f,t,o);return _.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"),de=De;var T=new WeakMap,x=null,j=(e,o,t)=>{x&&x.deregister();let n=[];T.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,d,l)=>{let c=T.get(o);if(c)return de({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});n.push(r);let i=o.onKeyDown(s=>{let p=T.get(o);if(!p)return;let d=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&d?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});n.push(i);let a={deregister:()=>{n.forEach(s=>s.dispose()),_.clearCompletionCache(),T.delete(o),x=null}};return x=a,a}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),T.delete(o),x=null}}}},me=j;0&&(module.exports={Copilot,registerCompletion,registerCopilot});
|
package/build/index.mjs
CHANGED
|
@@ -1,38 +1,33 @@
|
|
|
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"},w={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",G="groq",K={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},y=.3;var Y=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var P=class P{constructor(){}static getInstance(){return P.instance}handleError(o,t){let n=this.getErrorDetails(o),r=`\x1B[31m[${t}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};P.instance=new P;var N=P;var C=(e,o)=>N.getInstance().handleError(e,o);var D=(e,o)=>{let t=null,n=null,r=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),n&&n("Cancelled")),n=s,t=setTimeout(()=>{a(e(...i)),n=null},o)});return r.cancel=()=>{t&&(clearTimeout(t),n&&n("Cancelled"),t=null,n=null)},r},E=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var R=(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),z=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 J=async(e,o,t={})=>{let n={"Content-Type":"application/json",...t.headers},r=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:n,body:r,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},de=(e,o)=>J(e,"GET",o),me=(e,o,t)=>J(e,"POST",{...t,body:o}),M={GET:de,POST:me};var Z=(e,o)=>{let t=R(e,o);return!!t&&!Y.has(t)},Q=(e,o)=>{let t=X(e,o).trim(),n=h(e,o).trim();return e.column<=3&&(t!==""||n!=="")};var O="<<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);return`You are an AI coding assistant with expertise in${o?` ${o}`:""} programming, specializing in ${t}. Your goal is to provide accurate, efficient, and context-aware code completions that align with the existing code and the developer's intent. Provide code that is syntactically correct, follows best practices, and integrates seamlessly with the provided code snippet.`},Ce=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${E(e)}`:"",n=ee(o);return`The code is written${n?` in ${n}`:""}${t}.`},ge=e=>{let{filename:o,language:t,technologies:n,editorState:{completionMode:r},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=oe(r),d=o?`the file named "${o}"`:"a larger project",l=`Please assist with ${p} for the following code snippet, which is part of ${d}.
|
|
9
3
|
|
|
10
|
-
`;return l+=
|
|
4
|
+
`;return l+=Ce(n,t),l+=`
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
Please follow these guidelines when generating the completion:
|
|
7
|
+
- The cursor position is indicated by '${O}' in the code snippet.
|
|
8
|
+
- Begin your completion exactly at the cursor position.
|
|
9
|
+
- Do not duplicate any code that appears before or after the cursor in the provided snippet.
|
|
10
|
+
- Ensure that the completed code is syntactically correct and logically consistent with the surrounding code.
|
|
11
|
+
- Maintain the coding style and conventions used in the existing code.
|
|
12
|
+
- Optimize the code for readability and performance where applicable.
|
|
13
|
+
- Do not include any additional explanations or comments in your output.
|
|
14
|
+
- Output only the code completion, without wrapping it in markdown code syntax (e.g., no triple backticks).`,r==="fill-in-the-middle"?l+=`
|
|
15
|
+
- Since you are filling in the middle, replace '${O}' entirely with your completion.`:r==="completion"&&(l+=`
|
|
16
|
+
- Since you are completing the code, provide a logical continuation starting from '${O}'.`),l+=`
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
Here's the code snippet for completion:
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
${i}${v}${a}
|
|
27
|
-
</code>`,s&&s.length>0&&(l+=`
|
|
20
|
+
<code>
|
|
21
|
+
${i}${O}${a}
|
|
22
|
+
</code>`,s&&s.length>0&&(l+=`
|
|
28
23
|
|
|
29
24
|
Additional context from related files:
|
|
30
25
|
|
|
31
|
-
`,l+=s.map(
|
|
32
|
-
${
|
|
26
|
+
`,l+=s.map(c=>`// Path: ${c.path}
|
|
27
|
+
${c.content}
|
|
33
28
|
`).join(`
|
|
34
|
-
`)),l.endsWith(".")?l:`${l}.`};function
|
|
29
|
+
`)),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 n=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:y,messages:n}},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:y,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:y,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},ne=(e,o,t)=>H[o].createRequestBody(e,t),re=(e,o)=>H[o].createHeaders(e),ie=(e,o)=>H[o].parseCompletion(e),q=e=>j[e],se=e=>K[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??G,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: ${E(_)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!w[this.provider].includes(this.model)){let o=E(w[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:n}=o,{completionMetadata:r}=t,{headers:i={},customPrompt:a}=n??{},s=k(r),p=a?{...s,...a(r)}:s,d=se(this.provider),l,c=re(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let m=this.model.config(this.apiKey,p);d=m.endpoint??d,l=m.body??{},c={...c,...m.headers}}else l=ne(this.model,this.provider,p);c={...c,...i};try{let m=await M.POST(d,l,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(m);u={completion:f.text??f.completion}}else u={completion:ie(m,this.provider)};return u}catch(m){return{error:C(m,"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,n=o,r;for(;(r=t.exec(o))!==null;){let i=r[0],a=i.split(`
|
|
35
30
|
`).slice(1,-1).join(`
|
|
36
|
-
`);
|
|
31
|
+
`);n=n.replace(i,a)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
37
32
|
|
|
38
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
33
|
+
`),this}build(){return this.formattedCompletion}};var v=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!Z(this.cursorPosition,this.model)&&!Q(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(n=>this.isCacheItemValid(n,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,n){let r=n.getValueInRange(o.range);return h(t,n).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,r)}isPositionValid(o,t,n){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(n)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-n.length&&t.column<=o.range.endColumn}};L.MAX_CACHE_SIZE=10;var b=L;var Te="application/json",U=async({filename:e,endpoint:o,language:t,technologies:n,externalContext:r,model:i,position:a})=>{try{let{completion:s}=await M.POST(o,{completionMetadata:xe({filename:e,position:a,model:i,language:t,technologies:n,externalContext:r})},{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:n,technologies:r,externalContext:i})=>{let a=ye(o,t),s=S(o,t),p=B(o,t);return{filename:e,language:n,technologies:r,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},ye=(e,o)=>{let t=S(e,o),n=B(e,o);return t&&n?"fill-in-the-middle":"completion"};var le=(e,o,t,n)=>{let r=(e.match(/\n/g)||[]).length,i=z(e),a=R(t,n);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+r,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&r===0?t.column+(i-1):i:t.column}};function ae(e){return I.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)},A=new b,Ie=async({monaco:e,model:o,position:t,token:n,isCompletionAccepted:r,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new v(t,o).shouldProvideCompletions())return g([]);let d=A.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(d.length>0)return i(),g(d);if(n.isCancellationRequested||r)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=Oe[l];n.onCancellationRequested(()=>{c.cancel()});let m=await c({...p,text:o.getValue(),model:o,position:t});if(m){let u=ae(m),f=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),V=le(u,f,t,o);return A.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 T=new WeakMap,x=null,ce=(e,o,t)=>{x&&x.deregister();let n=[];T.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,d,l)=>{let c=T.get(o);if(c)return pe({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});n.push(r);let i=o.onKeyDown(s=>{let p=T.get(o);if(!p)return;let d=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&d?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});n.push(i);let a={deregister:()=>{n.forEach(s=>s.dispose()),A.clearCompletionCache(),T.delete(o),x=null}};return x=a,a}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),T.delete(o),x=null}}}},be=ce;export{$ as Copilot,ce as registerCompletion,be as registerCopilot};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monacopilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "AI auto-completion plugin for Monaco Editor",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.mjs",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
],
|
|
44
44
|
"repository": {
|
|
45
45
|
"type": "git",
|
|
46
|
-
"url": "https://github.com/arshad-yaseen/monacopilot"
|
|
46
|
+
"url": "git+https://github.com/arshad-yaseen/monacopilot.git"
|
|
47
47
|
},
|
|
48
48
|
"maintainers": [
|
|
49
49
|
{
|