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 CHANGED
@@ -1,4 +1,4 @@
1
- ![Hero Image](https://i.postimg.cc/GhpGVjVG/monacopilot-banner.png)
1
+ ![Monacopilot Banner](https://i.postimg.cc/GhpGVjVG/monacopilot-banner.png)
2
2
 
3
3
  # Monacopilot
4
4
 
@@ -7,34 +7,39 @@
7
7
  ## Table of Contents
8
8
 
9
9
  - [Examples](#examples)
10
- - [Installation](#installation)
11
- - [Usage](#usage)
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
- - [Configuration Options](#configuration-options)
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
- [Demo Video](https://github.com/user-attachments/assets/4af4e24a-1b05-4bee-84aa-1521ad7098cd)
29
+ ### Examples
27
30
 
28
- ## Examples
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
- ## Installation
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
- 🧩 For TypeScript users, You can import most of the types from `monacopilot` package.
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
- const express = require('express');
66
- const {Copilot} = require('monacopilot');
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('/copilot', async (req, res) => {
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
- Great! Now Monacopilot is all set up to send completion requests to the `/copilot` endpoint and get those completions back. It's like a high-five between your code and the AI!
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 Copilot with the Monaco Editor
80
+ #### Register Completion with the Monaco Editor
89
81
 
90
- Now, let's integrate Copilot with the Monaco editor. Here's how you can do it:
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 {registerCopilot} from 'monacopilot';
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
- registerCopilot(monaco, editor, {
101
- endpoint: 'https://api.example.com/copilot',
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
- 🎉 Hurray! Monacopilot is now connected to the Monaco Editor. Start typing and see completions in the editor.
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 for completions by setting the `provider` and `model` parameters in the `Copilot` instance.
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` and the default model is `llama-3-70b`.
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 make sure you are using a better model, especially for coding tasks, to get the best and most accurate completions. Also, use a model with very low response latency (I suggest at least under 1.5 s) to enjoy a great experience or utilize the full power of Monacopilot. Otherwise, you may experience poor performance or inaccurate completions.
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
- // provider: 'huggingface', You don't need to set the provider if you are using a custom model.
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 | Type |
185
- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
186
- | `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 }` |
187
- | `transformResponse` | A function that takes the raw/parsed response from the custom model API and converts it into an object with the following structure: | `(response: unknown) => { completion: string \| null, error?: string }` |
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 | Description |
192
- | ---------- | --------------------- | -------------------------------------------- |
193
- | `endpoint` | `string` | The URL of the custom model API endpoint. |
194
- | `body` | `object \| undefined` | The body of the custom model API request. |
195
- | `headers` | `object \| undefined` | The headers of the custom model API request. |
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
- 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.
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. Omitting either uses the default prompt for that field. Example of customizing only the system prompt:
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 with the following properties:
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 | Type | Description |
261
- | ---------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
262
- | language | `string` | The programming language of the code |
263
- | cursorPosition | `{lineNumber: number, column: number}` | The current cursor position in the editor |
264
- | filename | `string \| undefined` | The name of the file being edited. Only available if you have provided the `filename` option in the `registerCopilot` function. |
265
- | technologies | `string[] \| undefined` | An array of technologies used in the project. Only available if you have provided the `technologies` option in the `registerCopilot` function. |
266
- | externalContext | `object \| undefined` | Additional context from related files. Only available if you have provided the `externalContext` option in the `registerCopilot` function. |
267
- | textAfterCursor | `string` | The text that appears after the cursor |
268
- | textBeforeCursor | `string` | The text that appears before the cursor |
269
- | editorState | `object` | An object containing the `completionMode` property |
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 | Description |
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 | Description |
283
- | -------- | --------------------- | ----------------------------------------------------- |
284
- | system | `string \| undefined` | A string representing the system prompt for the model |
285
- | user | `string \| undefined` | A string representing the user prompt for the model |
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
- ## Configuration Options
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
- Enable completions tailored to specific technologies by using the `technologies` option.
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
- ```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.
354
+ This feature is coming soon™️.
378
355
 
379
356
  ## Contributing
380
357
 
381
- For guidelines on contributing, Please read the [contributing guide](https://github.com/arshad-yaseen/monacopilot/blob/main/CONTRIBUTING.md).
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 Monaco = typeof monaco;
4
- type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
5
- type CursorPosition = monaco.IPosition;
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 completion provider to use (e.g., 'openai', 'anthropic', 'groq').
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?: CompletionProvider;
20
+ provider?: CopilotProvider;
16
21
  /**
17
- * The model to use for generating completions.
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?: CompletionModel | CustomModel;
30
+ model?: CopilotModel | CustomCopilotModel;
26
31
  }
27
- type CustomModel = {
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: CustomModelConfig;
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 converts it into a CompletionResponse object.
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 A CompletionResponse object containing the completion text
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: CustomModelTransformResponse;
55
+ transformResponse: CustomCopilotModelTransformResponse;
54
56
  };
55
- type CustomModelConfig = (apiKey: string, prompt: {
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: 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 CustomModelTransformResponse = (response: unknown) => CompletionResponse;
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 RegisterCopilotOptions {
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 Copilot should provide code completions.
119
+ * Specifies when the completion service should provide code completions.
105
120
  *
106
121
  * Options:
107
- * - `'onIdle'`: Copilot provides completions after a brief pause in typing.
108
- * - `'onTyping'`: Copilot offers completions in real-time as you type.
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 CopilotRegistration {
152
+ interface CompletionRegistration {
138
153
  /**
139
- * Deregisters the Copilot from the Monaco editor.
140
- * This should be called when the Copilot is no longer needed.
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 Copilot with the Monaco editor.
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 Copilot.
275
- * @returns CopilotRegistration object with a deregister method.
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: RegisterCopilotOptions) => CopilotRegistration;
272
+ declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
278
273
 
279
- export { type CompletionMetadata, type CompletionModel, type CompletionProvider, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, type CompletionResponse, Copilot, type CopilotOptions, type CopilotRegistration, type CustomModel, type CustomModelConfig, type CustomModelTransformResponse, type Monaco, type RegisterCopilotOptions, type StandaloneCodeEditor, registerCopilot };
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 Monaco = typeof monaco;
4
- type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
5
- type CursorPosition = monaco.IPosition;
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 completion provider to use (e.g., 'openai', 'anthropic', 'groq').
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?: CompletionProvider;
20
+ provider?: CopilotProvider;
16
21
  /**
17
- * The model to use for generating completions.
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?: CompletionModel | CustomModel;
30
+ model?: CopilotModel | CustomCopilotModel;
26
31
  }
27
- type CustomModel = {
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: CustomModelConfig;
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 converts it into a CompletionResponse object.
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 A CompletionResponse object containing the completion text
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: CustomModelTransformResponse;
55
+ transformResponse: CustomCopilotModelTransformResponse;
54
56
  };
55
- type CustomModelConfig = (apiKey: string, prompt: {
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: 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 CustomModelTransformResponse = (response: unknown) => CompletionResponse;
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 RegisterCopilotOptions {
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 Copilot should provide code completions.
119
+ * Specifies when the completion service should provide code completions.
105
120
  *
106
121
  * Options:
107
- * - `'onIdle'`: Copilot provides completions after a brief pause in typing.
108
- * - `'onTyping'`: Copilot offers completions in real-time as you type.
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 CopilotRegistration {
152
+ interface CompletionRegistration {
138
153
  /**
139
- * Deregisters the Copilot from the Monaco editor.
140
- * This should be called when the Copilot is no longer needed.
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 Copilot with the Monaco editor.
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 Copilot.
275
- * @returns CopilotRegistration object with a deregister method.
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: RegisterCopilotOptions) => CopilotRegistration;
272
+ declare const registerCopilot: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
278
273
 
279
- export { type CompletionMetadata, type CompletionModel, type CompletionProvider, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, type CompletionResponse, Copilot, type CopilotOptions, type CopilotRegistration, type CustomModel, type CustomModelConfig, type CustomModelTransformResponse, type Monaco, type RegisterCopilotOptions, type StandaloneCodeEditor, registerCopilot };
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 B=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Te=Object.prototype.hasOwnProperty;var Pe=(o,e)=>{for(var t in e)B(o,t,{get:e[t],enumerable:!0})},ye=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ee(e))!Te.call(o,n)&&n!==t&&B(o,n,{get:()=>e[n],enumerable:!(r=fe(e,n))||r.enumerable});return o};var xe=o=>ye(B({},"__esModule",{value:!0}),o);var qe={};Pe(qe,{Copilot:()=>L,registerCopilot:()=>ge});module.exports=xe(qe);var k=["groq","openai","anthropic"],X={"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"},H={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"]},z="llama-3-70b",J="groq",Z={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},R=.3;var Q=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var O=class o{constructor(){}static getInstance(){return o.instance||(o.instance=new o),o.instance}error(e,t){console.error(this.styleMessage(t.message,e,"error")),t.stack&&console.error(this.styleStackTrace(t.stack))}warn(e,t){console.warn(this.styleMessage(t,e,"warning"))}styleMessage(e,t,r){let n=this.getTimestamp(),i="Please create an issue on GitHub if the issue persists.",a=100,s="\u2500".repeat(a-2),p=`\u250C${s}\u2510`,c=`\u2514${s}\u2518`,m=((f,M)=>{let he=f.split(" "),S=[],C="";return he.forEach(K=>{(C+K).length>M&&(S.push(C.trim()),C=""),C+=K+" "}),C.trim()&&S.push(C.trim()),S})(e,a-4),h=[p,...m.map(f=>`\u2502 ${f.padEnd(a-4)} \u2502`),c].join(`
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+=Ie(r,t),l+=`
4
+ `;return l+=ye(n,t),l+=`
11
5
 
12
- Here are the details about how the completion should be generated:
13
- - The cursor position is marked with '${v}'.
14
- - Your completion must start exactly at the cursor position.
15
- - Do not repeat any code that appears before or after the cursor.
16
- - Ensure your completion does not introduce any syntactical or logical errors.
17
- `,n==="fill-in-the-middle"?l+=` - If filling in the middle, replace '${v}' entirely with your completion.
18
- `:n==="completion"&&(l+=` - If completing the code, start from '${v}' and provide a logical continuation.
19
- `),l+=` - Optimize for readability and performance where possible.
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
- Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
18
+ Here's the code snippet for completion:
22
19
 
23
- Here's the code snippet for completion:
24
-
25
- <code>
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(m=>`// Path: ${m.path}
32
- ${m.content}
26
+ `,l+=s.map(c=>`// Path: ${c.path}
27
+ ${c.content}
33
28
  `).join(`
34
- `)),l.endsWith(".")?l:`${l}.`};function V(o){return{system:Oe(o),user:be(o)}}var ae={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var ve={createRequestBody:(o,e)=>{let r=o==="o1-preview"||o==="o1-mini"?[{role:"user",content:e.user}]:[{role:"system",content:e.system},{role:"user",content:e.user}];return{model:Y(o),temperature:R,messages:r}},createHeaders:o=>({"Content-Type":"application/json",Authorization:`Bearer ${o}`}),parseCompletion:o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the OpenAI response"}},Le={createRequestBody:(o,e)=>({model:Y(o),temperature:R,messages:[{role:"system",content:e.system},{role:"user",content:e.user}]}),createHeaders:o=>({"Content-Type":"application/json",Authorization:`Bearer ${o}`}),parseCompletion:o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the Groq response"}},Ne={createRequestBody:(o,e)=>({model:Y(o),temperature:R,system:e.system,messages:[{role:"user",content:e.user}],max_tokens:Ae(o)}),createHeaders:o=>({"Content-Type":"application/json","x-api-key":o,"anthropic-version":"2023-06-01"}),parseCompletion:o=>o.content?typeof o.content!="string"?{completion:null,error:"Completion content is not a string"}:{completion:o.content}:{completion:null,error:"No completion found in the Anthropic response"}},j={openai:ve,groq:Le,anthropic:Ne},le=(o,e,t)=>j[e].createRequestBody(o,t),pe=(o,e)=>j[e].createHeaders(o),me=(o,e)=>j[e].parseCompletion(o),Y=o=>X[o],ce=o=>Z[o],Ae=o=>ae[o]||4096;var L=class{constructor(e,t={}){if(!e)throw new Error("Please provide an API key.");this.apiKey=e,this.provider=t.provider??J,this.model=t.model??z,this.validateInputs()}validateInputs(){if(!k.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${T(k)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!H[this.provider].includes(this.model)){let e=T(H[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${e}`)}}generatePrompt(e,t){let r=V(e);return t?{...r,...t(e)}:r}prepareRequest(e,t){let r=ce(this.provider),n,i=pe(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let s=this.model.config(this.apiKey,e);r=s.endpoint??r,n=s.body??{},i={...i,...s.headers}}else n=le(this.model,this.provider,e);let a={...i,...t};return{endpoint:r,requestBody:n,headers:a}}async complete(e){let{body:t,options:r}=e,{completionMetadata:n}=t,{headers:i={},customPrompt:a}=r??{},s=this.generatePrompt(n,a),{endpoint:p,requestBody:c,headers:l}=this.prepareRequest(s,i);try{let m=await b.POST(p,c,{headers:l});return typeof this.model=="object"&&"transformResponse"in this.model?this.model.transformResponse(m):me(m,this.provider)}catch(m){return{error:d(m,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var N=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
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
- `);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
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 A=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!re(this.cursorPosition,this.model)&&!ne(this.cursorPosition,this.model)}};var _=class _{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(_.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return g(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};_.MAX_CACHE_SIZE=10;var w=_;var we="application/json",W=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await b.POST(e,{completionMetadata:_e({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":we},error:"Error while fetching completion item"});return s}catch(s){return d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},_e=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=De(e,t),s=F(e,t),p=U(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:e,editorState:{completionMode:a}}},De=(o,e)=>{let t=F(o,e),r=U(o,e);return t&&r?"fill-in-the-middle":"completion"};var de=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=oe(o),a=I(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function ue(o){return N.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var Se=300,Be=600,ke={onTyping:q(W,Se),onIdle:q(W,Be)},D=new w,He=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new A(t,e).shouldProvideCompletions())return u([]);let c=D.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(c.length>0)return i(),u(c);if(r.isCancellationRequested||n)return u([]);try{let l=s==="onTyping"?"onTyping":"onIdle",m=ke[l];r.onCancellationRequested(()=>{m.cancel()});let h=await m({...p,text:e.getValue(),model:e,position:t});if(h){let x=ue(h),f=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),M=de(x,f,t,e);return D.addCompletionCache({completion:x,range:M,textBeforeCursorInLine:g(t,e)}),i(),u([{insertText:x,range:M}])}}catch(l){if($e(l))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},$e=o=>typeof o=="string"&&(o==="Cancelled"||o==="AbortError")||o instanceof Error&&(o.message==="Cancelled"||o.name==="AbortError"),Ce=He;var P=new WeakMap,y=null,ge=(o,e,t)=>{y&&y.deregister();let r=[];P.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,c,l)=>{let m=P.get(e);if(m)return Ce({monaco:o,model:s,position:p,token:l,isCompletionAccepted:m.isCompletionAccepted,onShowCompletion:()=>{m.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let p=P.get(e);if(!p)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&c?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),D.clearCompletionCache(),P.delete(e),y=null}};return y=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),P.delete(e),y=null}}}};0&&(module.exports={Copilot,registerCopilot});
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 S=["groq","openai","anthropic"],K={"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"},B={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"]},X="llama-3-70b",z="groq",J={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},R=.3;var Z=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var O=class o{constructor(){}static getInstance(){return o.instance||(o.instance=new o),o.instance}error(e,t){console.error(this.styleMessage(t.message,e,"error")),t.stack&&console.error(this.styleStackTrace(t.stack))}warn(e,t){console.warn(this.styleMessage(t,e,"warning"))}styleMessage(e,t,r){let n=this.getTimestamp(),i="Please create an issue on GitHub if the issue persists.",a=100,s="\u2500".repeat(a-2),p=`\u250C${s}\u2510`,c=`\u2514${s}\u2518`,m=((f,M)=>{let Ce=f.split(" "),D=[],C="";return Ce.forEach(W=>{(C+W).length>M&&(D.push(C.trim()),C=""),C+=W+" "}),C.trim()&&D.push(C.trim()),D})(e,a-4),h=[p,...m.map(f=>`\u2502 ${f.padEnd(a-4)} \u2502`),c].join(`
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+=Ee(r,t),l+=`
4
+ `;return l+=Ce(n,t),l+=`
11
5
 
12
- Here are the details about how the completion should be generated:
13
- - The cursor position is marked with '${v}'.
14
- - Your completion must start exactly at the cursor position.
15
- - Do not repeat any code that appears before or after the cursor.
16
- - Ensure your completion does not introduce any syntactical or logical errors.
17
- `,n==="fill-in-the-middle"?l+=` - If filling in the middle, replace '${v}' entirely with your completion.
18
- `:n==="completion"&&(l+=` - If completing the code, start from '${v}' and provide a logical continuation.
19
- `),l+=` - Optimize for readability and performance where possible.
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
- Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
18
+ Here's the code snippet for completion:
22
19
 
23
- Here's the code snippet for completion:
24
-
25
- <code>
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(m=>`// Path: ${m.path}
32
- ${m.content}
26
+ `,l+=s.map(c=>`// Path: ${c.path}
27
+ ${c.content}
33
28
  `).join(`
34
- `)),l.endsWith(".")?l:`${l}.`};function F(o){return{system:fe(o),user:Te(o)}}var se={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Pe={createRequestBody:(o,e)=>{let r=o==="o1-preview"||o==="o1-mini"?[{role:"user",content:e.user}]:[{role:"system",content:e.system},{role:"user",content:e.user}];return{model:V(o),temperature:R,messages:r}},createHeaders:o=>({"Content-Type":"application/json",Authorization:`Bearer ${o}`}),parseCompletion:o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the OpenAI response"}},ye={createRequestBody:(o,e)=>({model:V(o),temperature:R,messages:[{role:"system",content:e.system},{role:"user",content:e.user}]}),createHeaders:o=>({"Content-Type":"application/json",Authorization:`Bearer ${o}`}),parseCompletion:o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the Groq response"}},xe={createRequestBody:(o,e)=>({model:V(o),temperature:R,system:e.system,messages:[{role:"user",content:e.user}],max_tokens:Me(o)}),createHeaders:o=>({"Content-Type":"application/json","x-api-key":o,"anthropic-version":"2023-06-01"}),parseCompletion:o=>o.content?typeof o.content!="string"?{completion:null,error:"Completion content is not a string"}:{completion:o.content}:{completion:null,error:"No completion found in the Anthropic response"}},U={openai:Pe,groq:ye,anthropic:xe},ae=(o,e,t)=>U[e].createRequestBody(o,t),le=(o,e)=>U[e].createHeaders(o),pe=(o,e)=>U[e].parseCompletion(o),V=o=>K[o],me=o=>J[o],Me=o=>se[o]||4096;var j=class{constructor(e,t={}){if(!e)throw new Error("Please provide an API key.");this.apiKey=e,this.provider=t.provider??z,this.model=t.model??X,this.validateInputs()}validateInputs(){if(!S.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${T(S)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!B[this.provider].includes(this.model)){let e=T(B[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${e}`)}}generatePrompt(e,t){let r=F(e);return t?{...r,...t(e)}:r}prepareRequest(e,t){let r=me(this.provider),n,i=le(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let s=this.model.config(this.apiKey,e);r=s.endpoint??r,n=s.body??{},i={...i,...s.headers}}else n=ae(this.model,this.provider,e);let a={...i,...t};return{endpoint:r,requestBody:n,headers:a}}async complete(e){let{body:t,options:r}=e,{completionMetadata:n}=t,{headers:i={},customPrompt:a}=r??{},s=this.generatePrompt(n,a),{endpoint:p,requestBody:c,headers:l}=this.prepareRequest(s,i);try{let m=await b.POST(p,c,{headers:l});return typeof this.model=="object"&&"transformResponse"in this.model?this.model.transformResponse(m):pe(m,this.provider)}catch(m){return{error:d(m,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var L=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
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
- `);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
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 N=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!te(this.cursorPosition,this.model)&&!re(this.cursorPosition,this.model)}};var w=class w{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(w.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return g(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};w.MAX_CACHE_SIZE=10;var A=w;var Re="application/json",G=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await b.POST(e,{completionMetadata:Oe({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":Re},error:"Error while fetching completion item"});return s}catch(s){return d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Oe=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=Ie(e,t),s=$(e,t),p=q(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:e,editorState:{completionMode:a}}},Ie=(o,e)=>{let t=$(o,e),r=q(o,e);return t&&r?"fill-in-the-middle":"completion"};var ce=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=ee(o),a=I(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function de(o){return L.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var be=300,ve=600,Le={onTyping:H(G,be),onIdle:H(G,ve)},_=new A,Ne=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new N(t,e).shouldProvideCompletions())return u([]);let c=_.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(c.length>0)return i(),u(c);if(r.isCancellationRequested||n)return u([]);try{let l=s==="onTyping"?"onTyping":"onIdle",m=Le[l];r.onCancellationRequested(()=>{m.cancel()});let h=await m({...p,text:e.getValue(),model:e,position:t});if(h){let x=de(h),f=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),M=ce(x,f,t,e);return _.addCompletionCache({completion:x,range:M,textBeforeCursorInLine:g(t,e)}),i(),u([{insertText:x,range:M}])}}catch(l){if(Ae(l))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},Ae=o=>typeof o=="string"&&(o==="Cancelled"||o==="AbortError")||o instanceof Error&&(o.message==="Cancelled"||o.name==="AbortError"),ue=Ne;var P=new WeakMap,y=null,we=(o,e,t)=>{y&&y.deregister();let r=[];P.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,c,l)=>{let m=P.get(e);if(m)return ue({monaco:o,model:s,position:p,token:l,isCompletionAccepted:m.isCompletionAccepted,onShowCompletion:()=>{m.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let p=P.get(e);if(!p)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&c?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),_.clearCompletionCache(),P.delete(e),y=null}};return y=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),P.delete(e),y=null}}}};export{j as Copilot,we as registerCopilot};
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.9.34",
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
  {