monacopilot 0.9.33 → 0.9.35

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