monacopilot 0.10.10 → 0.10.11
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 +137 -14
- package/build/index.d.mts +24 -22
- package/build/index.d.ts +24 -22
- package/build/index.js +15 -14
- package/build/index.mjs +16 -15
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -25,12 +25,15 @@
|
|
|
25
25
|
- [Filename](#filename)
|
|
26
26
|
- [Completions for Specific Technologies](#completions-for-specific-technologies)
|
|
27
27
|
- [Max Context Lines](#max-context-lines)
|
|
28
|
+
- [Handling Errors](#handling-errors)
|
|
29
|
+
- [Request Options](#request-options)
|
|
30
|
+
- [Custom Headers](#custom-headers)
|
|
28
31
|
- [Copilot Options](#copilot-options)
|
|
29
32
|
- [Changing the Provider and Model](#changing-the-provider-and-model)
|
|
30
33
|
- [Custom Model](#custom-model)
|
|
31
34
|
- [Completion Request Options](#completion-request-options)
|
|
32
|
-
- [Custom Headers](#custom-headers)
|
|
33
|
-
|
|
35
|
+
- [Custom Headers for AI Model Requests](#custom-headers-for-ai-model-requests)
|
|
36
|
+
- [Using a Different Language for the API Handler](#using-a-different-language-for-the-api-handler)
|
|
34
37
|
- [Select and Edit](#select-and-edit)
|
|
35
38
|
- [Contributing](#contributing)
|
|
36
39
|
|
|
@@ -83,6 +86,8 @@ app.post('/complete', async (req, res) => {
|
|
|
83
86
|
app.listen(port);
|
|
84
87
|
```
|
|
85
88
|
|
|
89
|
+
If you prefer to use a different programming language for your API handler in cases where your backend is not in JavaScript, please refer to the section [Using a Different Language for the API Handler](#using-a-different-language-for-the-api-handler) for guidance on implementing the handler in your chosen language.
|
|
90
|
+
|
|
86
91
|
Now, Monacopilot is set up to send completion requests to the `/complete` endpoint and receive completions in response.
|
|
87
92
|
|
|
88
93
|
The `copilot.complete` method processes the request body sent by Monacopilot and returns the corresponding completion.
|
|
@@ -252,6 +257,39 @@ registerCompletion(monaco, editor, {
|
|
|
252
257
|
|
|
253
258
|
> **Note:** If you're using `Groq` as your provider, it's recommended to set `maxContextLines` to `60` or less due to its low rate limits and lack of pay-as-you-go pricing. However, `Groq` is expected to offer pay-as-you-go pricing in the near future.
|
|
254
259
|
|
|
260
|
+
### Request Options
|
|
261
|
+
|
|
262
|
+
You can customize the `fetch` request made by Monacopilot to the specified endpoint by using the `requestOptions` parameter in the `registerCompletion` function.
|
|
263
|
+
|
|
264
|
+
#### Custom Headers
|
|
265
|
+
|
|
266
|
+
You can include custom headers in the requests sent to the endpoint specified in the `registerCompletion` function.
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
registerCompletion(monaco, editor, {
|
|
270
|
+
endpoint: 'https://api.example.com/complete',
|
|
271
|
+
requestOptions: {
|
|
272
|
+
headers: {
|
|
273
|
+
'X-Custom-Header': 'custom-value',
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Handling Errors
|
|
280
|
+
|
|
281
|
+
You can handle errors that occur during completion requests by providing an `onError` function when calling `registerCompletion`. This allows you to customize error handling and logging based on your application's needs.
|
|
282
|
+
|
|
283
|
+
This will disable the default error handling and logging behavior of Monacopilot.
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
registerCompletion(monaco, editor, {
|
|
287
|
+
onError: error => {
|
|
288
|
+
console.error(error);
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
255
293
|
## Copilot Options
|
|
256
294
|
|
|
257
295
|
### Changing the Provider and Model
|
|
@@ -330,7 +368,7 @@ The `transformResponse` function must return an object with the `text` property.
|
|
|
330
368
|
|
|
331
369
|
## Completion Request Options
|
|
332
370
|
|
|
333
|
-
### Custom Headers
|
|
371
|
+
### Custom Headers for AI Model Requests
|
|
334
372
|
|
|
335
373
|
You can add custom headers to the provider's completion requests. For example, if you select `OpenAI` as your provider, you can add a custom header to the OpenAI completion requests made by Monacopilot.
|
|
336
374
|
|
|
@@ -378,16 +416,18 @@ copilot.complete({
|
|
|
378
416
|
|
|
379
417
|
The `customPrompt` function receives a `completionMetadata` object, which contains information about the current editor state and can be used to tailor the prompt.
|
|
380
418
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
|
384
|
-
|
|
|
385
|
-
| `
|
|
386
|
-
| `
|
|
387
|
-
| `
|
|
388
|
-
| `
|
|
389
|
-
| `
|
|
390
|
-
| `
|
|
419
|
+
##### Completion Metadata
|
|
420
|
+
|
|
421
|
+
| Property | Type | Description |
|
|
422
|
+
| ------------------ | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
423
|
+
| `language` | `string` | The programming language of the code. |
|
|
424
|
+
| `cursorPosition` | `{ lineNumber: number; column: number }` | The current cursor position in the editor. |
|
|
425
|
+
| `filename` | `string` or `undefined` | The name of the file being edited. Only available if you have provided the `filename` option in the `registerCompletion` function. |
|
|
426
|
+
| `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. |
|
|
427
|
+
| `relatedFiles` | `object[]` or `undefined` | An array of objects containing the `path` and `content` of related files. Only available if you have provided the `relatedFiles` option in the `registerCompletion` function. |
|
|
428
|
+
| `textAfterCursor` | `string` | The text that appears after the cursor. |
|
|
429
|
+
| `textBeforeCursor` | `string` | The text that appears before the cursor. |
|
|
430
|
+
| `editorState` | `object` | An object containing the `completionMode` property. |
|
|
391
431
|
|
|
392
432
|
The `editorState.completionMode` can be one of the following:
|
|
393
433
|
|
|
@@ -420,7 +460,7 @@ const customPrompt = ({textBeforeCursor, textAfterCursor}) => ({
|
|
|
420
460
|
// Cursor position
|
|
421
461
|
${textAfterCursor}
|
|
422
462
|
|
|
423
|
-
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
|
|
463
|
+
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 completed part of the code without additional comments or explanations.`,
|
|
424
464
|
});
|
|
425
465
|
|
|
426
466
|
copilot.complete({
|
|
@@ -430,6 +470,89 @@ copilot.complete({
|
|
|
430
470
|
|
|
431
471
|
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.
|
|
432
472
|
|
|
473
|
+
## Using a Different Language for the API Handler
|
|
474
|
+
|
|
475
|
+
While the example in this documentation uses JavaScript/Node.js (which is recommended), you can set up the API handler in any language or framework. For JavaScript, Monacopilot provides a built-in function that handles all the necessary steps, such as generating the prompt, sending it to the model, and processing the response. However, if you're using a different language, you'll need to implement these steps manually. Here's a general approach to implement the handler in your preferred language:
|
|
476
|
+
|
|
477
|
+
1. Create an endpoint that accepts POST requests (e.g., `/complete`).
|
|
478
|
+
2. The endpoint should expect a JSON body containing completion metadata.
|
|
479
|
+
3. Use the metadata to construct a prompt for your AI model.
|
|
480
|
+
4. Send the prompt to your chosen AI model and get the completion.
|
|
481
|
+
5. Return a JSON response with the following structure:
|
|
482
|
+
|
|
483
|
+
```json
|
|
484
|
+
{
|
|
485
|
+
"completion": "Generated completion text"
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Or in case of an error:
|
|
490
|
+
|
|
491
|
+
```json
|
|
492
|
+
{
|
|
493
|
+
"completion": null,
|
|
494
|
+
"error": "Error message"
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Key Considerations
|
|
499
|
+
|
|
500
|
+
- The prompt should instruct the model to return only the completion text, without any additional formatting or explanations.
|
|
501
|
+
- The completion text should be ready for direct insertion into the editor.
|
|
502
|
+
|
|
503
|
+
Check out the [prompt.ts](https://github.com/arshad-yaseen/monacopilot/blob/main/src/helpers/completion/prompt.ts) file to see how Monacopilot generates the prompt. This will give you an idea of how to structure the prompt for your AI model to achieve the best completions.
|
|
504
|
+
|
|
505
|
+
### Metadata Overview
|
|
506
|
+
|
|
507
|
+
The request body's `completionMetadata` object contains essential information for crafting a prompt for the AI model to generate accurate completions. See the [Completion Metadata](#completion-metadata) section for more details.
|
|
508
|
+
|
|
509
|
+
### Example Implementation (Python with FastAPI)
|
|
510
|
+
|
|
511
|
+
Here's a basic example using Python and FastAPI:
|
|
512
|
+
|
|
513
|
+
```python
|
|
514
|
+
from fastapi import FastAPI, Request
|
|
515
|
+
|
|
516
|
+
app = FastAPI()
|
|
517
|
+
|
|
518
|
+
@app.post('/complete')
|
|
519
|
+
async def handle_completion(request: Request):
|
|
520
|
+
try:
|
|
521
|
+
body = await request.json()
|
|
522
|
+
metadata = body['completionMetadata']
|
|
523
|
+
|
|
524
|
+
prompt = f"""Please complete the following {metadata['language']} code:
|
|
525
|
+
|
|
526
|
+
{metadata['textBeforeCursor']}
|
|
527
|
+
<cursor>
|
|
528
|
+
{metadata['textAfterCursor']}
|
|
529
|
+
|
|
530
|
+
Use modern {metadata['language']} practices and hooks where appropriate. Please provide only the completed part of the
|
|
531
|
+
code without additional comments or explanations."""
|
|
532
|
+
|
|
533
|
+
# Simulate a response from a model
|
|
534
|
+
response = "Your model's response here"
|
|
535
|
+
|
|
536
|
+
return {
|
|
537
|
+
'completion': response,
|
|
538
|
+
'error': None
|
|
539
|
+
}
|
|
540
|
+
except Exception as e:
|
|
541
|
+
return {
|
|
542
|
+
'completion': None,
|
|
543
|
+
'error': str(e)
|
|
544
|
+
}
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
Now, Monacopilot is set up to send completion requests to the `/complete` endpoint and receive completions in response.
|
|
548
|
+
|
|
549
|
+
```javascript
|
|
550
|
+
registerCompletion(monaco, editor, {
|
|
551
|
+
endpoint: 'https://my-python-api.com/complete',
|
|
552
|
+
// ... other options
|
|
553
|
+
});
|
|
554
|
+
```
|
|
555
|
+
|
|
433
556
|
## Select and Edit
|
|
434
557
|
|
|
435
558
|
Select and Edit is a feature that allows you to select code from the editor and edit it inline with AI assistance.
|
package/build/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
+
import * as monaco_editor from 'monaco-editor';
|
|
2
3
|
|
|
3
4
|
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
4
5
|
type GroqModel = 'llama-3-70b';
|
|
@@ -78,7 +79,6 @@ type CustomCopilotModelTransformResponse = (response: unknown) => {
|
|
|
78
79
|
*/
|
|
79
80
|
text: string | null;
|
|
80
81
|
/**
|
|
81
|
-
* The text generated by the custom model.
|
|
82
82
|
* @deprecated Use `text` instead. This property will be removed in a future version.
|
|
83
83
|
*/
|
|
84
84
|
completion: string | null;
|
|
@@ -144,11 +144,6 @@ interface RegisterCompletionOptions {
|
|
|
144
144
|
* etc.
|
|
145
145
|
*/
|
|
146
146
|
technologies?: Technologies;
|
|
147
|
-
/**
|
|
148
|
-
* @deprecated
|
|
149
|
-
* Use `relatedFiles` instead.
|
|
150
|
-
*/
|
|
151
|
-
externalContext?: RelatedFile[];
|
|
152
147
|
/**
|
|
153
148
|
* Helps to give more relevant completions based on the full context.
|
|
154
149
|
* You can include things like the contents/codes of other files in the same workspace.
|
|
@@ -163,6 +158,22 @@ interface RegisterCompletionOptions {
|
|
|
163
158
|
* since `Groq` does not implement pay-as-you-go pricing and has only low rate limits.
|
|
164
159
|
*/
|
|
165
160
|
maxContextLines?: number;
|
|
161
|
+
/**
|
|
162
|
+
* Additional options to include in the request sent to the endpoint specified in the `registerCompletion` function.
|
|
163
|
+
*/
|
|
164
|
+
requestOptions?: RegisterCompletionRequestOptions;
|
|
165
|
+
/**
|
|
166
|
+
* Callback function that is called when an error occurs during the completion request.
|
|
167
|
+
* This function allows you to handle errors gracefully and provide appropriate feedback to the user.
|
|
168
|
+
* @param error - The error object containing information about the encountered error.
|
|
169
|
+
*/
|
|
170
|
+
onError?: (error: Error) => void;
|
|
171
|
+
}
|
|
172
|
+
interface RegisterCompletionRequestOptions {
|
|
173
|
+
/**
|
|
174
|
+
* Custom headers to include in the request sent to the endpoint specified in the `registerCompletion` function.
|
|
175
|
+
*/
|
|
176
|
+
headers?: Record<string, string>;
|
|
166
177
|
}
|
|
167
178
|
interface CompletionRegistration {
|
|
168
179
|
/**
|
|
@@ -193,7 +204,7 @@ interface CompletionRequestBody {
|
|
|
193
204
|
}
|
|
194
205
|
interface CompletionRequestOptions {
|
|
195
206
|
/**
|
|
196
|
-
*
|
|
207
|
+
* Custom headers to include in the request to the AI provider.
|
|
197
208
|
*/
|
|
198
209
|
headers?: Record<string, string>;
|
|
199
210
|
/**
|
|
@@ -258,23 +269,14 @@ declare class Copilot {
|
|
|
258
269
|
private readonly apiKey;
|
|
259
270
|
private provider;
|
|
260
271
|
private model;
|
|
261
|
-
/**
|
|
262
|
-
* Initializes the Copilot instance with an API key and optional configuration.
|
|
263
|
-
* @param apiKey - The API key for the chosen provider.
|
|
264
|
-
* @param options - Optional configuration for the Copilot instance.
|
|
265
|
-
*/
|
|
266
272
|
constructor(apiKey: string, options?: CopilotOptions);
|
|
267
|
-
/**
|
|
268
|
-
* Validates the inputs provided to the constructor.
|
|
269
|
-
* Ensures the selected model is supported by the provider.
|
|
270
|
-
*/
|
|
271
273
|
private validateInputs;
|
|
272
|
-
/**
|
|
273
|
-
* Sends a completion request to the API and returns the completion.
|
|
274
|
-
* @param request - The completion request containing the body and options.
|
|
275
|
-
* @returns A promise resolving to the completion response or an error.
|
|
276
|
-
*/
|
|
277
274
|
complete(request: CompletionRequest): Promise<CompletionResponse>;
|
|
275
|
+
private generatePrompt;
|
|
276
|
+
private prepareRequestDetails;
|
|
277
|
+
private sendCompletionRequest;
|
|
278
|
+
private processCompletionResponse;
|
|
279
|
+
private handleCompletionError;
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
/**
|
|
@@ -288,6 +290,6 @@ declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor,
|
|
|
288
290
|
/**
|
|
289
291
|
* @deprecated Use `registerCompletion` instead. This function will be removed in a future version.
|
|
290
292
|
*/
|
|
291
|
-
declare const registerCopilot: (monaco:
|
|
293
|
+
declare const registerCopilot: (monaco: typeof monaco_editor, editor: monaco_editor.editor.IStandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
292
294
|
|
|
293
295
|
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,4 +1,5 @@
|
|
|
1
1
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
+
import * as monaco_editor from 'monaco-editor';
|
|
2
3
|
|
|
3
4
|
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
4
5
|
type GroqModel = 'llama-3-70b';
|
|
@@ -78,7 +79,6 @@ type CustomCopilotModelTransformResponse = (response: unknown) => {
|
|
|
78
79
|
*/
|
|
79
80
|
text: string | null;
|
|
80
81
|
/**
|
|
81
|
-
* The text generated by the custom model.
|
|
82
82
|
* @deprecated Use `text` instead. This property will be removed in a future version.
|
|
83
83
|
*/
|
|
84
84
|
completion: string | null;
|
|
@@ -144,11 +144,6 @@ interface RegisterCompletionOptions {
|
|
|
144
144
|
* etc.
|
|
145
145
|
*/
|
|
146
146
|
technologies?: Technologies;
|
|
147
|
-
/**
|
|
148
|
-
* @deprecated
|
|
149
|
-
* Use `relatedFiles` instead.
|
|
150
|
-
*/
|
|
151
|
-
externalContext?: RelatedFile[];
|
|
152
147
|
/**
|
|
153
148
|
* Helps to give more relevant completions based on the full context.
|
|
154
149
|
* You can include things like the contents/codes of other files in the same workspace.
|
|
@@ -163,6 +158,22 @@ interface RegisterCompletionOptions {
|
|
|
163
158
|
* since `Groq` does not implement pay-as-you-go pricing and has only low rate limits.
|
|
164
159
|
*/
|
|
165
160
|
maxContextLines?: number;
|
|
161
|
+
/**
|
|
162
|
+
* Additional options to include in the request sent to the endpoint specified in the `registerCompletion` function.
|
|
163
|
+
*/
|
|
164
|
+
requestOptions?: RegisterCompletionRequestOptions;
|
|
165
|
+
/**
|
|
166
|
+
* Callback function that is called when an error occurs during the completion request.
|
|
167
|
+
* This function allows you to handle errors gracefully and provide appropriate feedback to the user.
|
|
168
|
+
* @param error - The error object containing information about the encountered error.
|
|
169
|
+
*/
|
|
170
|
+
onError?: (error: Error) => void;
|
|
171
|
+
}
|
|
172
|
+
interface RegisterCompletionRequestOptions {
|
|
173
|
+
/**
|
|
174
|
+
* Custom headers to include in the request sent to the endpoint specified in the `registerCompletion` function.
|
|
175
|
+
*/
|
|
176
|
+
headers?: Record<string, string>;
|
|
166
177
|
}
|
|
167
178
|
interface CompletionRegistration {
|
|
168
179
|
/**
|
|
@@ -193,7 +204,7 @@ interface CompletionRequestBody {
|
|
|
193
204
|
}
|
|
194
205
|
interface CompletionRequestOptions {
|
|
195
206
|
/**
|
|
196
|
-
*
|
|
207
|
+
* Custom headers to include in the request to the AI provider.
|
|
197
208
|
*/
|
|
198
209
|
headers?: Record<string, string>;
|
|
199
210
|
/**
|
|
@@ -258,23 +269,14 @@ declare class Copilot {
|
|
|
258
269
|
private readonly apiKey;
|
|
259
270
|
private provider;
|
|
260
271
|
private model;
|
|
261
|
-
/**
|
|
262
|
-
* Initializes the Copilot instance with an API key and optional configuration.
|
|
263
|
-
* @param apiKey - The API key for the chosen provider.
|
|
264
|
-
* @param options - Optional configuration for the Copilot instance.
|
|
265
|
-
*/
|
|
266
272
|
constructor(apiKey: string, options?: CopilotOptions);
|
|
267
|
-
/**
|
|
268
|
-
* Validates the inputs provided to the constructor.
|
|
269
|
-
* Ensures the selected model is supported by the provider.
|
|
270
|
-
*/
|
|
271
273
|
private validateInputs;
|
|
272
|
-
/**
|
|
273
|
-
* Sends a completion request to the API and returns the completion.
|
|
274
|
-
* @param request - The completion request containing the body and options.
|
|
275
|
-
* @returns A promise resolving to the completion response or an error.
|
|
276
|
-
*/
|
|
277
274
|
complete(request: CompletionRequest): Promise<CompletionResponse>;
|
|
275
|
+
private generatePrompt;
|
|
276
|
+
private prepareRequestDetails;
|
|
277
|
+
private sendCompletionRequest;
|
|
278
|
+
private processCompletionResponse;
|
|
279
|
+
private handleCompletionError;
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
/**
|
|
@@ -288,6 +290,6 @@ declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor,
|
|
|
288
290
|
/**
|
|
289
291
|
* @deprecated Use `registerCompletion` instead. This function will be removed in a future version.
|
|
290
292
|
*/
|
|
291
|
-
declare const registerCopilot: (monaco:
|
|
293
|
+
declare const registerCopilot: (monaco: typeof monaco_editor, editor: monaco_editor.editor.IStandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
292
294
|
|
|
293
295
|
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,9 +1,9 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`),n=r.length;if(t>=n)return e;if(o.from==="end"){let
|
|
3
|
-
`.repeat(t):
|
|
4
|
-
`)}let i=r.slice(0,t);return i.every(
|
|
1
|
+
"use strict";var F=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var ge=(e,t)=>{for(var o in t)F(e,o,{get:t[o],enumerable:!0})},he=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ue(t))!Ce.call(e,n)&&n!==o&&F(e,n,{get:()=>t[n],enumerable:!(r=me(t,n))||r.enumerable});return e};var fe=e=>he(F({},"__esModule",{value:!0}),e);var _e={};ge(_e,{Copilot:()=>L,registerCompletion:()=>Y,registerCopilot:()=>ce});module.exports=fe(_e);var _=["groq","openai","anthropic"],G={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},$={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"]},J="llama-3-70b",X="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"},M=.1;var v=(e,t)=>{let o=null,r=null,n=(...i)=>new Promise((s,a)=>{o&&(clearTimeout(o),r&&r("Cancelled")),r=a,o=setTimeout(()=>{s(e(...i)),r=null},t)});return n.cancel=()=>{o&&(clearTimeout(o),r&&r("Cancelled"),o=null,r=null)},n},x=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var H=(e,t)=>t.getLineContent(e.lineNumber)[e.column-1];var b=(e,t)=>t.getLineContent(e.lineNumber).slice(e.column-1),f=(e,t)=>t.getLineContent(e.lineNumber).slice(0,e.column-1),Z=(e,t)=>t.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),Q=(e,t)=>t.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:t.getLineCount(),endColumn:t.getLineMaxColumn(t.getLineCount())}),U=(e,t,o={})=>{if(t<=0)return"";let r=e.split(`
|
|
2
|
+
`),n=r.length;if(t>=n)return e;if(o.from==="end"){let s=r.slice(-t);return s.every(a=>a==="")?`
|
|
3
|
+
`.repeat(t):s.join(`
|
|
4
|
+
`)}let i=r.slice(0,t);return i.every(s=>s==="")?`
|
|
5
5
|
`.repeat(t):i.join(`
|
|
6
|
-
`)};var
|
|
6
|
+
`)};var ee=async(e,t,o={})=>{let r={"Content-Type":"application/json",...o.headers},n=t==="POST"&&o.body?JSON.stringify(o.body):void 0,i=await fetch(e,{method:t,headers:r,body:n,signal:o.signal});if(!i.ok)throw new Error(`${i.statusText||o.fallbackError||"Network error"}`);return i.json()},Pe=(e,t)=>ee(e,"GET",t),Ee=(e,t,o)=>ee(e,"POST",{...o,body:t}),I={GET:Pe,POST:Ee};var te=(e,t)=>{let o=b(e,t).trim(),r=f(e,t).trim();return e.column<=3&&(o!==""||r!=="")};var Re="<user-current-cursor-position-is-here>",ye=e=>e==="javascript"?"JavaScript (ESNext)":e,xe=e=>`You are an expert ${ye(e.language)||x(e.technologies)} developer assistant with extensive experience in code completion and adhering to best coding practices. Your role is to provide precise and contextually relevant code completions without any errors, including syntax, punctuation, spaces, tabs, and line breaks. Focus on integrating seamlessly with the existing code and follow the user's instructions carefully.`,Te=e=>{let{filename:t="/",textBeforeCursor:o="",textAfterCursor:r="",relatedFiles:n,editorState:i}=e,p=`
|
|
7
7
|
<guidelines>
|
|
8
8
|
<instruction>${{continue:"Continue writing the code from where the cursor is positioned.",insert:"Insert the appropriate code snippet at the cursor position.",complete:"Provide the necessary code to complete the current statement or block."}[i.completionMode]}</instruction>
|
|
9
9
|
<steps>
|
|
@@ -17,29 +17,30 @@
|
|
|
17
17
|
<step>Return <strong>only</strong> the code required at the cursor position.</step>
|
|
18
18
|
</steps>
|
|
19
19
|
</guidelines>
|
|
20
|
-
`,
|
|
20
|
+
`,l=`
|
|
21
21
|
<context>
|
|
22
22
|
<current_file path="${t}">
|
|
23
23
|
<code>
|
|
24
|
-
${o}${
|
|
24
|
+
${o}${Re}${r}
|
|
25
25
|
</code>
|
|
26
26
|
</current_file>
|
|
27
27
|
</context>
|
|
28
|
-
`,m=n?.map(({path:
|
|
29
|
-
<related_file path="${
|
|
28
|
+
`,m=n?.map(({path:c,content:u})=>`
|
|
29
|
+
<related_file path="${c}">
|
|
30
30
|
<code>
|
|
31
|
-
${
|
|
31
|
+
${u}
|
|
32
32
|
</code>
|
|
33
33
|
</related_file>
|
|
34
34
|
`).join(`
|
|
35
35
|
`)||"";return`
|
|
36
36
|
<task>
|
|
37
37
|
${p}
|
|
38
|
-
${
|
|
38
|
+
${l}
|
|
39
39
|
${m}
|
|
40
40
|
</task>
|
|
41
|
-
`};function
|
|
41
|
+
`};function V(e){return{system:xe(e),user:Te(e)}}var oe={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Oe={createRequestBody:(e,t)=>{let r=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:t.user}]:[{role:"system",content:t.system},{role:"user",content:t.user}];return{model:W(e),temperature:M,messages:r}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Me={createRequestBody:(e,t)=>({model:W(e),temperature:M,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},ve={createRequestBody:(e,t)=>({model:W(e),temperature:M,system:t.system,messages:[{role:"user",content:t.user}],max_tokens:be(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},j={openai:Oe,groq:Me,anthropic:ve},re=(e,t,o)=>j[t].createRequestBody(e,o),ne=(e,t)=>j[t].createHeaders(e),ie=(e,t)=>j[t].parseCompletion(e),W=e=>G[e],se=e=>z[e],be=e=>oe[e]||4096;var d=class d{constructor(){}static getInstance(){return d.instance}logError(t){let o,r;t instanceof Error?(o=t.message,r=t.stack):typeof t=="string"?o=t:o="An unknown error occurred";let n=`${d.RED}${d.BOLD}[MONACOPILOT ERROR] ${o}${d.RESET}`;return console.error(n),r&&console.error(`${d.RED}[MONACOPILOT ERROR] Stack trace:${d.RESET}
|
|
42
|
+
${r}`),{message:o,stack:r}}warn(t){console.warn(`${d.YELLOW}${d.BOLD}[MONACOPILOT WARN] ${t}${d.RESET}`)}log(t){console.log(`${d.BOLD}[MONACOPILOT] ${t}${d.RESET}`)}};d.instance=new d,d.RED="\x1B[31m",d.YELLOW="\x1B[33m",d.RESET="\x1B[0m",d.BOLD="\x1B[1m";var K=d,g=K.getInstance();var L=class{constructor(t,o={}){if(!t)throw new Error("Please provide an API key.");this.apiKey=t,this.provider=o.provider??X,this.model=o.model??J,this.validateInputs()}validateInputs(){if(!_.includes(this.provider))throw new Error(`Unsupported provider "${this.provider}". Please choose from: ${x(_)}. For custom models, provider specification is not needed.`);if(typeof this.model=="string"&&!$[this.provider].includes(this.model))throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${x($[this.provider])}`)}async complete(t){let{body:o,options:r}=t,{completionMetadata:n}=o,{headers:i={},customPrompt:s}=r??{},a=this.generatePrompt(n,s),{endpoint:p,requestBody:l,headers:m}=this.prepareRequestDetails(a);try{let c=await this.sendCompletionRequest(p,l,{...m,...i});return this.processCompletionResponse(c)}catch(c){return this.handleCompletionError(c)}}generatePrompt(t,o){let r=V(t);return o?{...r,...o(t)}:r}prepareRequestDetails(t){let o=se(this.provider),r,n=ne(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let i=this.model.config(this.apiKey,t);o=i.endpoint??o,r=i.body??{},n={...n,...i.headers}}else r=re(this.model,this.provider,t);return{endpoint:o,requestBody:r,headers:n}}async sendCompletionRequest(t,o,r){return I.POST(t,o,{headers:r})}processCompletionResponse(t){if(typeof this.model=="object"&&"transformResponse"in this.model){let o=this.model.transformResponse(t);return"completion"in o&&g.warn("The `completion` property in `transformResponse` function is deprecated. Please use `text` instead."),{completion:o.text??o.completion}}else return{completion:ie(t,this.provider)}}handleCompletionError(t){return{error:g.logError(t).message,completion:null}}};var A=class e{constructor(t){this.formattedCompletion="";this.formattedCompletion=t}static create(t){return new e(t)}setCompletion(t){return this.formattedCompletion=t,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(t){let o=/```[\s\S]*?```/g,r=t,n;for(;(n=o.exec(t))!==null;){let i=n[0],s=i.split(`
|
|
42
43
|
`).slice(1,-1).join(`
|
|
43
|
-
`);r=r.replace(i,
|
|
44
|
+
`);r=r.replace(i,s)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
44
45
|
|
|
45
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
46
|
+
`),this}build(){return this.formattedCompletion}};var D=class{constructor(t,o){this.cursorPos=t,this.mdl=o}shouldProvideCompletions(){return!te(this.cursorPos,this.mdl)}};var S=class S{constructor(){this.cache=[]}get(t,o){return this.cache.filter(r=>this.isValidCacheItem(r,t,o))}add(t){let o=[...this.cache.slice(-(S.MAX_CACHE_SIZE-1)),t];this.cache=o}clear(){this.cache=[]}isValidCacheItem(t,o,r){let n=r.getValueInRange(t.range);return f(o,r).startsWith(t.textBeforeCursorInLine)&&this.isPositionValid(t,o,n)}isPositionValid(t,o,r){let{range:n,completion:i}=t,{startLineNumber:s,startColumn:a,endColumn:p}=n,{lineNumber:l,column:m}=o,c=l===s&&m===a,u=i.startsWith(r)&&l===s&&m>=a-r.length&&m<=p+r.length;return c||u}};S.MAX_CACHE_SIZE=10;var N=S;var Ie="application/json",w=async({mdl:e,pos:t,...o})=>{let{endpoint:r,requestOptions:n,onError:i}=o,{headers:s}=n??{};try{let{completion:a,error:p}=await I.POST(r,{completionMetadata:Le({pos:t,mdl:e,options:o})},{headers:{"Content-Type":Ie,...s},fallbackError:"Error while fetching completion item"});if(p)throw new Error(p);return a}catch(a){return i?i(a):g.logError(a),null}},Le=({pos:e,mdl:t,options:o})=>{let{filename:r,language:n,technologies:i,relatedFiles:s,maxContextLines:a}=o,p=Ae(e,t),m=!!s?.length?3:2,c=a?Math.floor(a/m):void 0,u=(R,y,q)=>{let O=R(e,t);return y?U(O,y,q):O},C=(R,y)=>!R||!y?R:R.map(({content:q,...O})=>({...O,content:U(q,y)})),E=u(Z,c,{from:"end"}),k=u(Q,c),de=C(s,c);return{filename:r,language:n,technologies:i,relatedFiles:de,textBeforeCursor:E,textAfterCursor:k,cursorPosition:e,editorState:{completionMode:p}}},Ae=(e,t)=>{let o=H(e,t),r=b(e,t);return o?"insert":r.trim()?"complete":"continue"};var le=(e,t,o)=>{if(!o)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let r=t.getOffsetAt(e),n=t.getValue().substring(r),i=0,s=0,a=0,p=o.length,l=n.length;if(r>=t.getValue().length)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};if(l===0)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let m=Math.min(p,l);for(let C=0;C<m&&o[C]===n[C];C++)i++;for(let C=1;C<=m;C++){let E=o.slice(-C),k=n.slice(0,C);E===k&&(s=C)}if(a=Math.max(i,s),a===0)for(let C=1;C<p;C++){let E=o.substring(C);if(n.startsWith(E)){a=p-C;break}}let c=r+a,u=t.getPositionAt(c);return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:u.lineNumber,endColumn:u.column}},ae=e=>A.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build(),h=e=>({items:e,enableForwardStability:!0});var Ne=300,Se=600,we=0,Be={onTyping:v(w,Ne),onIdle:v(w,Se),onDemand:v(w,we)},B=new N,ke=async({mdl:e,pos:t,token:o,isCompletionAccepted:r,onShowCompletion:n,options:i})=>{let{trigger:s="onIdle",...a}=i;if(!new D(t,e).shouldProvideCompletions())return h([]);let p=B.get(t,e).map(l=>({insertText:l.completion,range:{...l.range,endColumn:t.column}}));if(p.length>0)return n(),h(p);if(o.isCancellationRequested||r)return h([]);try{let l=Be[s];o.onCancellationRequested(()=>{l.cancel()});let m=await l({mdl:e,pos:t,...a});if(m){let c=ae(m),u=le(t,e,c);return B.add({completion:c,range:u,textBeforeCursorInLine:f(t,e)}),n(),h([{insertText:c,range:u}])}}catch(l){return i.onError?i.onError(l):qe(l)||g.logError(l),h([])}return h([])},qe=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),pe=ke;var P=new WeakMap,T=null,Y=(e,t,o)=>{T&&T.deregister();let r=[],n={isCompletionAccepted:!1,isCompletionVisible:!1,isManualTrigger:!1};P.set(t,n),t.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});try{let i=e.languages.registerInlineCompletionsProvider(o.language,{provideInlineCompletions:(p,l,m,c)=>{let u=P.get(t);if(!(!u||o.trigger==="onDemand"&&!u.isManualTrigger))return pe({mdl:p,pos:l,token:c,isCompletionAccepted:u.isCompletionAccepted,onShowCompletion:()=>{u.isCompletionVisible=!0,u.isManualTrigger=!1},options:o})},freeInlineCompletions:()=>{}});r.push(i);let s=t.onKeyDown(p=>{let l=P.get(t);if(!l)return;let m=p.keyCode===e.KeyCode.Tab||p.keyCode===e.KeyCode.RightArrow&&p.metaKey;l.isCompletionVisible&&m?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(s);let a={deregister:()=>{r.forEach(p=>p.dispose()),B.clear(),P.delete(t),T=null},trigger:()=>Fe(t)};return T=a,a}catch(i){return o.onError?o.onError(i):g.logError(i),{deregister:()=>{r.forEach(s=>s.dispose()),P.delete(t),T=null},trigger:()=>{}}}},Fe=e=>{let t=P.get(e);if(!t){g.warn("Completion is not registered. Use `registerCompletion` to register completion first.");return}t.isManualTrigger=!0,e.trigger("keyboard","editor.action.inlineSuggest.trigger",{})},ce=(...e)=>(g.warn("The `registerCopilot` function is deprecated. Use `registerCompletion` instead."),Y(...e));0&&(module.exports={Copilot,registerCompletion,registerCopilot});
|
package/build/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),
|
|
3
|
-
`.repeat(t):
|
|
4
|
-
`)}let
|
|
5
|
-
`.repeat(t):
|
|
6
|
-
`)};var
|
|
1
|
+
var q=["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"},F={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"]},Y="llama-3-70b",G="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"},M=.1;var v=(e,t)=>{let o=null,r=null,i=(...n)=>new Promise((s,a)=>{o&&(clearTimeout(o),r&&r("Cancelled")),r=a,o=setTimeout(()=>{s(e(...n)),r=null},t)});return i.cancel=()=>{o&&(clearTimeout(o),r&&r("Cancelled"),o=null,r=null)},i},x=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var _=(e,t)=>t.getLineContent(e.lineNumber)[e.column-1];var b=(e,t)=>t.getLineContent(e.lineNumber).slice(e.column-1),f=(e,t)=>t.getLineContent(e.lineNumber).slice(0,e.column-1),X=(e,t)=>t.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),z=(e,t)=>t.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:t.getLineCount(),endColumn:t.getLineMaxColumn(t.getLineCount())}),$=(e,t,o={})=>{if(t<=0)return"";let r=e.split(`
|
|
2
|
+
`),i=r.length;if(t>=i)return e;if(o.from==="end"){let s=r.slice(-t);return s.every(a=>a==="")?`
|
|
3
|
+
`.repeat(t):s.join(`
|
|
4
|
+
`)}let n=r.slice(0,t);return n.every(s=>s==="")?`
|
|
5
|
+
`.repeat(t):n.join(`
|
|
6
|
+
`)};var Z=async(e,t,o={})=>{let r={"Content-Type":"application/json",...o.headers},i=t==="POST"&&o.body?JSON.stringify(o.body):void 0,n=await fetch(e,{method:t,headers:r,body:i,signal:o.signal});if(!n.ok)throw new Error(`${n.statusText||o.fallbackError||"Network error"}`);return n.json()},ce=(e,t)=>Z(e,"GET",t),de=(e,t,o)=>Z(e,"POST",{...o,body:t}),I={GET:ce,POST:de};var Q=(e,t)=>{let o=b(e,t).trim(),r=f(e,t).trim();return e.column<=3&&(o!==""||r!=="")};var me="<user-current-cursor-position-is-here>",ue=e=>e==="javascript"?"JavaScript (ESNext)":e,Ce=e=>`You are an expert ${ue(e.language)||x(e.technologies)} developer assistant with extensive experience in code completion and adhering to best coding practices. Your role is to provide precise and contextually relevant code completions without any errors, including syntax, punctuation, spaces, tabs, and line breaks. Focus on integrating seamlessly with the existing code and follow the user's instructions carefully.`,ge=e=>{let{filename:t="/",textBeforeCursor:o="",textAfterCursor:r="",relatedFiles:i,editorState:n}=e,p=`
|
|
7
7
|
<guidelines>
|
|
8
|
-
<instruction>${{continue:"Continue writing the code from where the cursor is positioned.",insert:"Insert the appropriate code snippet at the cursor position.",complete:"Provide the necessary code to complete the current statement or block."}[
|
|
8
|
+
<instruction>${{continue:"Continue writing the code from where the cursor is positioned.",insert:"Insert the appropriate code snippet at the cursor position.",complete:"Provide the necessary code to complete the current statement or block."}[n.completionMode]}</instruction>
|
|
9
9
|
<steps>
|
|
10
10
|
<step>Analyze the provided code and any related files thoroughly.</step>
|
|
11
11
|
<step>Ensure the generated code integrates seamlessly with the existing code.</step>
|
|
@@ -17,7 +17,7 @@ var B=["groq","openai","anthropic"],W={"llama-3-70b":"llama3-70b-8192","gpt-4o":
|
|
|
17
17
|
<step>Return <strong>only</strong> the code required at the cursor position.</step>
|
|
18
18
|
</steps>
|
|
19
19
|
</guidelines>
|
|
20
|
-
`,
|
|
20
|
+
`,l=`
|
|
21
21
|
<context>
|
|
22
22
|
<current_file path="${t}">
|
|
23
23
|
<code>
|
|
@@ -25,21 +25,22 @@ ${o}${me}${r}
|
|
|
25
25
|
</code>
|
|
26
26
|
</current_file>
|
|
27
27
|
</context>
|
|
28
|
-
`,m=
|
|
29
|
-
<related_file path="${
|
|
28
|
+
`,m=i?.map(({path:c,content:u})=>`
|
|
29
|
+
<related_file path="${c}">
|
|
30
30
|
<code>
|
|
31
|
-
${
|
|
31
|
+
${u}
|
|
32
32
|
</code>
|
|
33
33
|
</related_file>
|
|
34
34
|
`).join(`
|
|
35
35
|
`)||"";return`
|
|
36
36
|
<task>
|
|
37
37
|
${p}
|
|
38
|
-
${
|
|
38
|
+
${l}
|
|
39
39
|
${m}
|
|
40
40
|
</task>
|
|
41
|
-
`};function
|
|
41
|
+
`};function H(e){return{system:Ce(e),user:ge(e)}}var ee={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var he={createRequestBody:(e,t)=>{let r=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:t.user}]:[{role:"system",content:t.system},{role:"user",content:t.user}];return{model:V(e),temperature:M,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,t)=>({model:V(e),temperature:M,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Pe={createRequestBody:(e,t)=>({model:V(e),temperature:M,system:t.system,messages:[{role:"user",content:t.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},U={openai:he,groq:fe,anthropic:Pe},te=(e,t,o)=>U[t].createRequestBody(e,o),oe=(e,t)=>U[t].createHeaders(e),re=(e,t)=>U[t].parseCompletion(e),V=e=>K[e],ne=e=>J[e],Ee=e=>ee[e]||4096;var d=class d{constructor(){}static getInstance(){return d.instance}logError(t){let o,r;t instanceof Error?(o=t.message,r=t.stack):typeof t=="string"?o=t:o="An unknown error occurred";let i=`${d.RED}${d.BOLD}[MONACOPILOT ERROR] ${o}${d.RESET}`;return console.error(i),r&&console.error(`${d.RED}[MONACOPILOT ERROR] Stack trace:${d.RESET}
|
|
42
|
+
${r}`),{message:o,stack:r}}warn(t){console.warn(`${d.YELLOW}${d.BOLD}[MONACOPILOT WARN] ${t}${d.RESET}`)}log(t){console.log(`${d.BOLD}[MONACOPILOT] ${t}${d.RESET}`)}};d.instance=new d,d.RED="\x1B[31m",d.YELLOW="\x1B[33m",d.RESET="\x1B[0m",d.BOLD="\x1B[1m";var j=d,g=j.getInstance();var W=class{constructor(t,o={}){if(!t)throw new Error("Please provide an API key.");this.apiKey=t,this.provider=o.provider??G,this.model=o.model??Y,this.validateInputs()}validateInputs(){if(!q.includes(this.provider))throw new Error(`Unsupported provider "${this.provider}". Please choose from: ${x(q)}. For custom models, provider specification is not needed.`);if(typeof this.model=="string"&&!F[this.provider].includes(this.model))throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${x(F[this.provider])}`)}async complete(t){let{body:o,options:r}=t,{completionMetadata:i}=o,{headers:n={},customPrompt:s}=r??{},a=this.generatePrompt(i,s),{endpoint:p,requestBody:l,headers:m}=this.prepareRequestDetails(a);try{let c=await this.sendCompletionRequest(p,l,{...m,...n});return this.processCompletionResponse(c)}catch(c){return this.handleCompletionError(c)}}generatePrompt(t,o){let r=H(t);return o?{...r,...o(t)}:r}prepareRequestDetails(t){let o=ne(this.provider),r,i=oe(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let n=this.model.config(this.apiKey,t);o=n.endpoint??o,r=n.body??{},i={...i,...n.headers}}else r=te(this.model,this.provider,t);return{endpoint:o,requestBody:r,headers:i}}async sendCompletionRequest(t,o,r){return I.POST(t,o,{headers:r})}processCompletionResponse(t){if(typeof this.model=="object"&&"transformResponse"in this.model){let o=this.model.transformResponse(t);return"completion"in o&&g.warn("The `completion` property in `transformResponse` function is deprecated. Please use `text` instead."),{completion:o.text??o.completion}}else return{completion:re(t,this.provider)}}handleCompletionError(t){return{error:g.logError(t).message,completion:null}}};var L=class e{constructor(t){this.formattedCompletion="";this.formattedCompletion=t}static create(t){return new e(t)}setCompletion(t){return this.formattedCompletion=t,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(t){let o=/```[\s\S]*?```/g,r=t,i;for(;(i=o.exec(t))!==null;){let n=i[0],s=n.split(`
|
|
42
43
|
`).slice(1,-1).join(`
|
|
43
|
-
`);r=r.replace(
|
|
44
|
+
`);r=r.replace(n,s)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
44
45
|
|
|
45
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
46
|
+
`),this}build(){return this.formattedCompletion}};var A=class{constructor(t,o){this.cursorPos=t,this.mdl=o}shouldProvideCompletions(){return!Q(this.cursorPos,this.mdl)}};var N=class N{constructor(){this.cache=[]}get(t,o){return this.cache.filter(r=>this.isValidCacheItem(r,t,o))}add(t){let o=[...this.cache.slice(-(N.MAX_CACHE_SIZE-1)),t];this.cache=o}clear(){this.cache=[]}isValidCacheItem(t,o,r){let i=r.getValueInRange(t.range);return f(o,r).startsWith(t.textBeforeCursorInLine)&&this.isPositionValid(t,o,i)}isPositionValid(t,o,r){let{range:i,completion:n}=t,{startLineNumber:s,startColumn:a,endColumn:p}=i,{lineNumber:l,column:m}=o,c=l===s&&m===a,u=n.startsWith(r)&&l===s&&m>=a-r.length&&m<=p+r.length;return c||u}};N.MAX_CACHE_SIZE=10;var D=N;var Re="application/json",S=async({mdl:e,pos:t,...o})=>{let{endpoint:r,requestOptions:i,onError:n}=o,{headers:s}=i??{};try{let{completion:a,error:p}=await I.POST(r,{completionMetadata:ye({pos:t,mdl:e,options:o})},{headers:{"Content-Type":Re,...s},fallbackError:"Error while fetching completion item"});if(p)throw new Error(p);return a}catch(a){return n?n(a):g.logError(a),null}},ye=({pos:e,mdl:t,options:o})=>{let{filename:r,language:i,technologies:n,relatedFiles:s,maxContextLines:a}=o,p=xe(e,t),m=!!s?.length?3:2,c=a?Math.floor(a/m):void 0,u=(R,y,k)=>{let O=R(e,t);return y?$(O,y,k):O},C=(R,y)=>!R||!y?R:R.map(({content:k,...O})=>({...O,content:$(k,y)})),E=u(X,c,{from:"end"}),B=u(z,c),pe=C(s,c);return{filename:r,language:i,technologies:n,relatedFiles:pe,textBeforeCursor:E,textAfterCursor:B,cursorPosition:e,editorState:{completionMode:p}}},xe=(e,t)=>{let o=_(e,t),r=b(e,t);return o?"insert":r.trim()?"complete":"continue"};var ie=(e,t,o)=>{if(!o)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let r=t.getOffsetAt(e),i=t.getValue().substring(r),n=0,s=0,a=0,p=o.length,l=i.length;if(r>=t.getValue().length)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};if(l===0)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let m=Math.min(p,l);for(let C=0;C<m&&o[C]===i[C];C++)n++;for(let C=1;C<=m;C++){let E=o.slice(-C),B=i.slice(0,C);E===B&&(s=C)}if(a=Math.max(n,s),a===0)for(let C=1;C<p;C++){let E=o.substring(C);if(i.startsWith(E)){a=p-C;break}}let c=r+a,u=t.getPositionAt(c);return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:u.lineNumber,endColumn:u.column}},se=e=>L.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build(),h=e=>({items:e,enableForwardStability:!0});var Oe=300,Me=600,ve=0,be={onTyping:v(S,Oe),onIdle:v(S,Me),onDemand:v(S,ve)},w=new D,Ie=async({mdl:e,pos:t,token:o,isCompletionAccepted:r,onShowCompletion:i,options:n})=>{let{trigger:s="onIdle",...a}=n;if(!new A(t,e).shouldProvideCompletions())return h([]);let p=w.get(t,e).map(l=>({insertText:l.completion,range:{...l.range,endColumn:t.column}}));if(p.length>0)return i(),h(p);if(o.isCancellationRequested||r)return h([]);try{let l=be[s];o.onCancellationRequested(()=>{l.cancel()});let m=await l({mdl:e,pos:t,...a});if(m){let c=se(m),u=ie(t,e,c);return w.add({completion:c,range:u,textBeforeCursorInLine:f(t,e)}),i(),h([{insertText:c,range:u}])}}catch(l){return n.onError?n.onError(l):Le(l)||g.logError(l),h([])}return h([])},Le=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),le=Ie;var P=new WeakMap,T=null,ae=(e,t,o)=>{T&&T.deregister();let r=[],i={isCompletionAccepted:!1,isCompletionVisible:!1,isManualTrigger:!1};P.set(t,i),t.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});try{let n=e.languages.registerInlineCompletionsProvider(o.language,{provideInlineCompletions:(p,l,m,c)=>{let u=P.get(t);if(!(!u||o.trigger==="onDemand"&&!u.isManualTrigger))return le({mdl:p,pos:l,token:c,isCompletionAccepted:u.isCompletionAccepted,onShowCompletion:()=>{u.isCompletionVisible=!0,u.isManualTrigger=!1},options:o})},freeInlineCompletions:()=>{}});r.push(n);let s=t.onKeyDown(p=>{let l=P.get(t);if(!l)return;let m=p.keyCode===e.KeyCode.Tab||p.keyCode===e.KeyCode.RightArrow&&p.metaKey;l.isCompletionVisible&&m?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(s);let a={deregister:()=>{r.forEach(p=>p.dispose()),w.clear(),P.delete(t),T=null},trigger:()=>Ae(t)};return T=a,a}catch(n){return o.onError?o.onError(n):g.logError(n),{deregister:()=>{r.forEach(s=>s.dispose()),P.delete(t),T=null},trigger:()=>{}}}},Ae=e=>{let t=P.get(e);if(!t){g.warn("Completion is not registered. Use `registerCompletion` to register completion first.");return}t.isManualTrigger=!0,e.trigger("keyboard","editor.action.inlineSuggest.trigger",{})},De=(...e)=>(g.warn("The `registerCopilot` function is deprecated. Use `registerCompletion` instead."),ae(...e));export{W as Copilot,ae as registerCompletion,De as registerCopilot};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monacopilot",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.11",
|
|
4
4
|
"description": "AI auto-completion plugin for Monaco Editor",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.mjs",
|
|
@@ -16,29 +16,32 @@
|
|
|
16
16
|
"type-check": "tsc --noEmit",
|
|
17
17
|
"lint": "eslint . --ext .ts,.tsx --fix",
|
|
18
18
|
"lint:test-ui": "pnpm -C tests/ui lint",
|
|
19
|
+
"validate": "pnpm build && pnpm format && pnpm type-check && pnpm lint && pnpm lint:test-ui",
|
|
19
20
|
"format": "prettier --write .",
|
|
20
|
-
"pre-commit": "pnpm build && pnpm format && pnpm type-check && pnpm lint && pnpm lint:test-ui",
|
|
21
21
|
"release": "release-it"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@anthropic-ai/sdk": "^0.27.3",
|
|
25
25
|
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
|
|
26
26
|
"@typescript-eslint/eslint-plugin": "^7.3.1",
|
|
27
|
+
"auto-changelog": "^2.5.0",
|
|
27
28
|
"eslint": "^8.57.0",
|
|
28
29
|
"groq-sdk": "^0.3.2",
|
|
29
30
|
"monaco-editor": "^0.52.0",
|
|
30
31
|
"openai": "^4.60.1",
|
|
31
32
|
"prettier": "^3.2.5",
|
|
32
|
-
"release-it": "^17.
|
|
33
|
+
"release-it": "^17.6.0",
|
|
33
34
|
"tsup": "^8.0.2",
|
|
34
35
|
"typescript": "^5.4.3",
|
|
35
36
|
"vitest": "^2.0.5"
|
|
36
37
|
},
|
|
37
38
|
"keywords": [
|
|
38
39
|
"monaco-editor",
|
|
40
|
+
"monaco",
|
|
39
41
|
"ai",
|
|
40
42
|
"auto-completion",
|
|
41
43
|
"code-completion",
|
|
44
|
+
"copilot",
|
|
42
45
|
"github-copilot"
|
|
43
46
|
],
|
|
44
47
|
"repository": {
|
|
@@ -53,5 +56,5 @@
|
|
|
53
56
|
}
|
|
54
57
|
],
|
|
55
58
|
"license": "MIT",
|
|
56
|
-
"author": "Arshad Yaseen <m@arshadyaseen.com>"
|
|
59
|
+
"author": "Arshad Yaseen <m@arshadyaseen.com> (https://arshadyaseen.com)"
|
|
57
60
|
}
|