monacopilot 0.18.2 → 0.18.4
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 +159 -151
- package/build/index.d.mts +15 -12
- package/build/index.d.ts +15 -12
- package/build/index.js +9 -14
- package/build/index.mjs +9 -11
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
[](https://github.com/arshad-yaseen/monacopilot/blob/main/LICENSE)
|
|
3
3
|
[](https://bundlephobia.com/package/monacopilot)
|
|
4
4
|
|
|
5
|
-

|
|
6
|
-
|
|
7
5
|
# Monacopilot
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
Add GitHub Copilot-style AI completions to your Monaco Editor in minutes! 🚀
|
|
8
|
+
|
|
9
|
+

|
|
10
10
|
|
|
11
11
|
### Features
|
|
12
12
|
|
|
@@ -19,161 +19,117 @@
|
|
|
19
19
|
- 🔌 Custom Model Support
|
|
20
20
|
- 🎮 Manual Trigger Support
|
|
21
21
|
|
|
22
|
-
###
|
|
23
|
-
|
|
24
|
-

|
|
22
|
+
### Quick Start (3 Simple Steps)
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- [Examples](#examples)
|
|
29
|
-
- [Demo](#demo)
|
|
30
|
-
- [Installation](#installation)
|
|
31
|
-
- [Usage](#usage)
|
|
32
|
-
- [API Handler](#api-handler)
|
|
33
|
-
- [Register Completion with the Monaco Editor](#register-completion-with-the-monaco-editor)
|
|
34
|
-
- [Register Completion Options](#register-completion-options)
|
|
35
|
-
- [Trigger Mode](#trigger-mode)
|
|
36
|
-
- [Manually Trigger Completions](#manually-trigger-completions)
|
|
37
|
-
- [Trigger Completions with a Keyboard Shortcut](#trigger-completions-with-a-keyboard-shortcut)
|
|
38
|
-
- [Trigger Completions with an Editor Action](#trigger-completions-with-an-editor-action)
|
|
39
|
-
- [Multi-File Context](#multi-file-context)
|
|
40
|
-
- [Filename](#filename)
|
|
41
|
-
- [Completions for Specific Technologies](#completions-for-specific-technologies)
|
|
42
|
-
- [Max Context Lines](#max-context-lines)
|
|
43
|
-
- [Caching Completions](#caching-completions)
|
|
44
|
-
- [Handling Errors](#handling-errors)
|
|
45
|
-
- [Custom Request Handler](#custom-request-handler)
|
|
46
|
-
- [Completion Event Handlers](#completion-event-handlers)
|
|
47
|
-
- [onCompletionShown](#oncompletionshown)
|
|
48
|
-
- [onCompletionAccepted](#oncompletionaccepted)
|
|
49
|
-
- [onCompletionRejected](#oncompletionrejected)
|
|
50
|
-
- [Copilot Options](#copilot-options)
|
|
51
|
-
- [Changing the Provider and Model](#changing-the-provider-and-model)
|
|
52
|
-
- [Custom Model](#custom-model)
|
|
53
|
-
- [Completion Request Options](#completion-request-options)
|
|
54
|
-
- [Custom Headers for LLM Requests](#custom-headers-for-llm-requests)
|
|
55
|
-
- [Custom Prompt](#custom-prompt)
|
|
56
|
-
- [Cross-Language API Handler Implementation](#cross-language-api-handler-implementation)
|
|
57
|
-
- [Security](#security)
|
|
58
|
-
- [Contributing](#contributing)
|
|
59
|
-
|
|
60
|
-
### Examples
|
|
61
|
-
|
|
62
|
-
Here are some examples of how to integrate Monacopilot into your project:
|
|
63
|
-
|
|
64
|
-
- Next.js
|
|
65
|
-
- [App Router](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/app)
|
|
66
|
-
- [Pages Router](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/pages)
|
|
67
|
-
- [Remix](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/remix)
|
|
68
|
-
- [Vue](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/vue)
|
|
69
|
-
|
|
70
|
-
### Demo
|
|
71
|
-
|
|
72
|
-
[Inline Completions Demo Video](https://github.com/user-attachments/assets/f2ec4ae1-f658-4002-af9c-c6b1bbad70d9)
|
|
73
|
-
|
|
74
|
-
In the demo, we are using the `onTyping` trigger mode with the Groq model, which is why you see such quick and fast completions. Groq provides very fast response times.
|
|
75
|
-
|
|
76
|
-
### Installation
|
|
77
|
-
|
|
78
|
-
To install Monacopilot, run:
|
|
24
|
+
1. **Install the package**
|
|
79
25
|
|
|
80
26
|
```bash
|
|
81
27
|
npm install monacopilot
|
|
82
28
|
```
|
|
83
29
|
|
|
84
|
-
|
|
30
|
+
2. **Register the AI completion to your editor**
|
|
85
31
|
|
|
86
|
-
|
|
32
|
+
```javascript
|
|
33
|
+
// In your frontend code
|
|
34
|
+
import * as monaco from 'monaco-editor';
|
|
35
|
+
import {registerCompletion} from 'monacopilot';
|
|
36
|
+
|
|
37
|
+
const editor = monaco.editor.create(document.getElementById('container'), {
|
|
38
|
+
language: 'javascript',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
registerCompletion(monaco, editor, {
|
|
42
|
+
endpoint: '/api/complete',
|
|
43
|
+
language: 'javascript',
|
|
44
|
+
});
|
|
45
|
+
```
|
|
87
46
|
|
|
88
|
-
|
|
47
|
+
3. **Create your completion API handler**
|
|
89
48
|
|
|
90
49
|
```javascript
|
|
91
|
-
|
|
50
|
+
// Create an API handler for the `/api/complete` endpoint (e.g. using Express.js)
|
|
51
|
+
// to handle completion requests from the editor
|
|
52
|
+
|
|
92
53
|
import {Copilot} from 'monacopilot';
|
|
93
54
|
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
const copilot = new Copilot(process.env.GROQ_API_KEY, {
|
|
97
|
-
provider: 'groq',
|
|
98
|
-
model: 'llama-3-70b',
|
|
55
|
+
const copilot = new Copilot(OPENAI_API_KEY, {
|
|
56
|
+
provider: 'openai', // or 'anthropic', 'google', etc.
|
|
99
57
|
});
|
|
100
58
|
|
|
101
|
-
|
|
59
|
+
// Handle completion requests
|
|
60
|
+
app.post('/api/complete', async (req, res) => {
|
|
61
|
+
const {completion, error, raw} = await copilot.complete({body: req.body});
|
|
102
62
|
|
|
103
|
-
|
|
104
|
-
const {completion, error, raw} = await copilot.complete({
|
|
105
|
-
body: req.body,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Process raw LLM response if needed
|
|
109
|
-
// `raw` can be undefined if an error occurred, which happens when `error` is present
|
|
63
|
+
// Optional: Use raw response for analytics or token counting
|
|
110
64
|
if (raw) {
|
|
111
65
|
calculateCost(raw.usage.input_tokens);
|
|
112
66
|
}
|
|
113
67
|
|
|
114
|
-
// Handle errors
|
|
68
|
+
// Handle any errors gracefully
|
|
115
69
|
if (error) {
|
|
116
|
-
|
|
117
|
-
res.status(500).json({completion: null, error});
|
|
70
|
+
return res.status(500).json({completion: null, error});
|
|
118
71
|
}
|
|
119
72
|
|
|
120
|
-
res.
|
|
73
|
+
res.json({completion});
|
|
121
74
|
});
|
|
122
|
-
|
|
123
|
-
app.listen(port);
|
|
124
75
|
```
|
|
125
76
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
```json
|
|
129
|
-
{
|
|
130
|
-
"completion": "Generated completion text"
|
|
131
|
-
}
|
|
132
|
-
```
|
|
77
|
+
You can use any backend framework or programming language for your API handler, as long as the endpoint is accessible from the browser. For non-JavaScript implementations, see [Cross-Language API Handler Implementation](#cross-language-api-handler-implementation).
|
|
133
78
|
|
|
134
|
-
|
|
79
|
+
That's it! Your Monaco Editor now has AI-powered completions! 🎉
|
|
135
80
|
|
|
136
|
-
|
|
137
|
-
{
|
|
138
|
-
"completion": null,
|
|
139
|
-
"error": "Error message"
|
|
140
|
-
}
|
|
141
|
-
```
|
|
81
|
+
### Examples
|
|
142
82
|
|
|
143
|
-
|
|
83
|
+
Here are some examples of how to integrate Monacopilot into your project:
|
|
144
84
|
|
|
145
|
-
|
|
85
|
+
- Next.js
|
|
86
|
+
- [App Router](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/app)
|
|
87
|
+
- [Pages Router](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/nextjs/pages)
|
|
88
|
+
- [Remix](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/remix)
|
|
89
|
+
- [Vue](https://github.com/arshad-yaseen/monacopilot/tree/main/examples/vue)
|
|
146
90
|
|
|
147
|
-
|
|
91
|
+
### See it in action
|
|
148
92
|
|
|
149
|
-
|
|
93
|
+
[Inline Completions Demo Video](https://github.com/user-attachments/assets/f2ec4ae1-f658-4002-af9c-c6b1bbad70d9)
|
|
150
94
|
|
|
151
|
-
|
|
95
|
+
In the demo, we are using the `onTyping` trigger mode with the Groq model, which is why you see such quick and fast completions. Groq provides very fast response times.
|
|
152
96
|
|
|
153
|
-
|
|
154
|
-
import * as monaco from 'monaco-editor';
|
|
155
|
-
import {registerCompletion} from 'monacopilot';
|
|
97
|
+
---
|
|
156
98
|
|
|
157
|
-
|
|
158
|
-
language: 'javascript',
|
|
159
|
-
});
|
|
99
|
+
The above is all you need to get started with Monacopilot. Read the rest of the documentation for more advanced features.
|
|
160
100
|
|
|
161
|
-
|
|
162
|
-
// Examples:
|
|
163
|
-
// - '/api/complete' if you're using the Next.js (API handler) or similar frameworks.
|
|
164
|
-
// - 'https://api.example.com/complete' for a separate API server
|
|
165
|
-
// Ensure this can be accessed from the browser.
|
|
166
|
-
endpoint: 'https://api.example.com/complete',
|
|
167
|
-
// The language of the editor.
|
|
168
|
-
language: 'javascript',
|
|
169
|
-
});
|
|
170
|
-
```
|
|
101
|
+
Expand the table of contents below to navigate to your desired section.
|
|
171
102
|
|
|
172
|
-
>
|
|
173
|
-
>
|
|
174
|
-
> For example, in a React component, you can call `completion.deregister()` within the `useEffect` cleanup function to ensure proper disposal when the component unmounts.
|
|
103
|
+
<details>
|
|
104
|
+
<summary>Table of Contents</summary>
|
|
175
105
|
|
|
176
|
-
|
|
106
|
+
- [Register Completion Options](#register-completion-options)
|
|
107
|
+
- [Trigger Mode](#trigger-mode)
|
|
108
|
+
- [Manually Trigger Completions](#manually-trigger-completions)
|
|
109
|
+
- [Trigger Completions with a Keyboard Shortcut](#trigger-completions-with-a-keyboard-shortcut)
|
|
110
|
+
- [Trigger Completions with an Editor Action](#trigger-completions-with-an-editor-action)
|
|
111
|
+
- [Multi-File Context](#multi-file-context)
|
|
112
|
+
- [Filename](#filename)
|
|
113
|
+
- [Completions for Specific Technologies](#completions-for-specific-technologies)
|
|
114
|
+
- [Max Context Lines](#max-context-lines)
|
|
115
|
+
- [Caching Completions](#caching-completions)
|
|
116
|
+
- [Handling Errors](#handling-errors)
|
|
117
|
+
- [Custom Request Handler](#custom-request-handler)
|
|
118
|
+
- [Request Handler Example](#request-handler-example)
|
|
119
|
+
- [Completion Event Handlers](#completion-event-handlers)
|
|
120
|
+
- [onCompletionShown](#oncompletionshown)
|
|
121
|
+
- [onCompletionAccepted](#oncompletionaccepted)
|
|
122
|
+
- [onCompletionRejected](#oncompletionrejected)
|
|
123
|
+
- [Copilot Options](#copilot-options)
|
|
124
|
+
- [Changing the Provider and Model](#changing-the-provider-and-model)
|
|
125
|
+
- [Custom Model](#custom-model)
|
|
126
|
+
- [Completion Request Options](#completion-request-options)
|
|
127
|
+
- [Custom Headers for LLM Requests](#custom-headers-for-llm-requests)
|
|
128
|
+
- [Custom Prompt](#custom-prompt)
|
|
129
|
+
- [Cross-Language API Handler Implementation](#cross-language-api-handler-implementation)
|
|
130
|
+
- [Security](#security)
|
|
131
|
+
- [Contributing](#contributing)
|
|
132
|
+
</details>
|
|
177
133
|
|
|
178
134
|
## Register Completion Options
|
|
179
135
|
|
|
@@ -383,48 +339,100 @@ The `requestHandler` should return an object with the following property:
|
|
|
383
339
|
| ------------ | ------------------ | ------------------------------------------------------------------------------------------------ |
|
|
384
340
|
| `completion` | `string` or `null` | The completion text to be inserted into the editor. Return `null` if no completion is available. |
|
|
385
341
|
|
|
386
|
-
#### Example
|
|
342
|
+
#### Request Handler Example
|
|
343
|
+
|
|
344
|
+
Here's a practical example demonstrating how to let users select different models for AI auto-completion, We use the `requestHandler` option to attach the selected model to the request body and use it in the server-side API handler.
|
|
387
345
|
|
|
388
|
-
|
|
346
|
+
Client-side implementation:
|
|
389
347
|
|
|
390
348
|
```javascript
|
|
349
|
+
const selectedModel = 'gpt-4'; // Example of model selected by user via UI (e.g. dropdown, settings panel)
|
|
350
|
+
|
|
391
351
|
registerCompletion(monaco, editor, {
|
|
392
352
|
endpoint: 'https://api.example.com/complete',
|
|
393
|
-
// ... other options
|
|
394
353
|
requestHandler: async ({endpoint, body}) => {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
354
|
+
const response = await fetch(endpoint, {
|
|
355
|
+
method: 'POST',
|
|
356
|
+
headers: {
|
|
357
|
+
'Content-Type': 'application/json',
|
|
358
|
+
},
|
|
359
|
+
body: JSON.stringify({
|
|
360
|
+
...body,
|
|
361
|
+
model: selectedModel, // Attach selected model to request body
|
|
362
|
+
}),
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
const data = await response.json();
|
|
366
|
+
return {
|
|
367
|
+
completion: data.completion,
|
|
368
|
+
};
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Server-side implementation (Example using Express.js): This is the server-side API handler that the `endpoint` parameter points to in the `registerCompletion` function.
|
|
407
374
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
375
|
+
```javascript
|
|
376
|
+
import express from 'express';
|
|
377
|
+
import {Copilot} from 'monacopilot';
|
|
411
378
|
|
|
412
|
-
|
|
379
|
+
const app = express();
|
|
413
380
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
381
|
+
// Initialize different copilot instances for different models
|
|
382
|
+
const copilotInstances = {
|
|
383
|
+
'gpt-4o': new Copilot(process.env.OPENAI_API_KEY, {
|
|
384
|
+
provider: 'openai',
|
|
385
|
+
model: 'gpt-4o',
|
|
386
|
+
}),
|
|
387
|
+
'sonnet-3.5': new Copilot(process.env.ANTHROPIC_API_KEY, {
|
|
388
|
+
provider: 'anthropic',
|
|
389
|
+
model: 'claude-3-5-sonnet',
|
|
390
|
+
}),
|
|
391
|
+
'llama-3': new Copilot(process.env.GROQ_API_KEY, {
|
|
392
|
+
provider: 'groq',
|
|
393
|
+
model: 'llama-3-70b',
|
|
394
|
+
}),
|
|
395
|
+
};
|
|
418
396
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
397
|
+
app.post('/complete', async (req, res) => {
|
|
398
|
+
try {
|
|
399
|
+
// Get the selected model from the request body
|
|
400
|
+
const {model, ...completionBody} = req.body;
|
|
401
|
+
|
|
402
|
+
// Use the appropriate copilot instance based on selected model
|
|
403
|
+
const copilot = copilotInstances[model];
|
|
404
|
+
if (!copilot) {
|
|
405
|
+
return res.status(400).json({
|
|
406
|
+
completion: null,
|
|
407
|
+
error: 'Invalid model selected',
|
|
408
|
+
});
|
|
423
409
|
}
|
|
424
|
-
|
|
410
|
+
|
|
411
|
+
const {completion, error} = await copilot.complete({
|
|
412
|
+
body: completionBody,
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
if (error) {
|
|
416
|
+
return res.status(500).json({
|
|
417
|
+
completion: null,
|
|
418
|
+
error,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
res.json({completion});
|
|
423
|
+
} catch (err) {
|
|
424
|
+
res.status(500).json({
|
|
425
|
+
completion: null,
|
|
426
|
+
error: err.message,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
425
429
|
});
|
|
430
|
+
|
|
431
|
+
app.listen(3000);
|
|
426
432
|
```
|
|
427
433
|
|
|
434
|
+
The server maintains a map of Copilot instances configured with different providers and models, allowing for flexible model selection while keeping API keys secure on the server side.
|
|
435
|
+
|
|
428
436
|
### Completion Event Handlers
|
|
429
437
|
|
|
430
438
|
The editor provides several events to handle completion suggestions. These events allow you to respond to different stages of the completion process, such as when a suggestion is shown or accepted by the user.
|
|
@@ -444,8 +452,8 @@ registerCompletion(monaco, editor, {
|
|
|
444
452
|
|
|
445
453
|
**Parameters:**
|
|
446
454
|
|
|
447
|
-
- `completion
|
|
448
|
-
- `range
|
|
455
|
+
- `completion`: The completion text that is being shown
|
|
456
|
+
- `range`: The editor range object where the completion will be inserted
|
|
449
457
|
|
|
450
458
|
#### onCompletionAccepted
|
|
451
459
|
|
package/build/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MessageCreateParams, Message } from '@anthropic-ai/sdk/resources';
|
|
2
2
|
import { GenerateContentRequest, GenerateContentResponse } from '@google/generative-ai';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { ChatCompletionCreateParamsBase as ChatCompletionCreateParamsBase$1, ChatCompletion as ChatCompletion$1 } from 'groq-sdk/resources/chat/completions';
|
|
4
|
+
import { ChatCompletionCreateParamsBase, ChatCompletion } from 'openai/resources/chat/completions';
|
|
5
5
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
6
6
|
|
|
7
7
|
declare const MODEL_IDS: Record<Model, string>;
|
|
@@ -58,6 +58,8 @@ interface ProviderImplementationMap {
|
|
|
58
58
|
type OpenAIModel = ProviderImplementationMap['openai']['Model'];
|
|
59
59
|
type GroqModel = ProviderImplementationMap['groq']['Model'];
|
|
60
60
|
type AnthropicModel = ProviderImplementationMap['anthropic']['Model'];
|
|
61
|
+
type GoogleModel = ProviderImplementationMap['google']['Model'];
|
|
62
|
+
type DeepSeekModel = ProviderImplementationMap['deepseek']['Model'];
|
|
61
63
|
/**
|
|
62
64
|
* Union of all predefined Copilot models
|
|
63
65
|
*/
|
|
@@ -114,6 +116,15 @@ type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
|
|
114
116
|
type CursorPosition = monaco.IPosition;
|
|
115
117
|
type EditorRange = monaco.IRange;
|
|
116
118
|
|
|
119
|
+
type FetchCompletionItemHandler = (params: FetchCompletionItemParams) => Promise<FetchCompletionItemReturn>;
|
|
120
|
+
type FetchCompletionItemReturn = {
|
|
121
|
+
completion: string | null;
|
|
122
|
+
};
|
|
123
|
+
interface FetchCompletionItemParams {
|
|
124
|
+
endpoint: string;
|
|
125
|
+
body: CompletionRequestBody;
|
|
126
|
+
}
|
|
127
|
+
|
|
117
128
|
type Endpoint = string;
|
|
118
129
|
type Filename = string;
|
|
119
130
|
type Technologies = string[];
|
|
@@ -324,14 +335,6 @@ interface CompletionMetadata {
|
|
|
324
335
|
completionMode: CompletionMode;
|
|
325
336
|
};
|
|
326
337
|
}
|
|
327
|
-
type FetchCompletionItemHandler = (params: FetchCompletionItemParams) => Promise<FetchCompletionItemReturn>;
|
|
328
|
-
type FetchCompletionItemReturn = {
|
|
329
|
-
completion: string | null;
|
|
330
|
-
};
|
|
331
|
-
interface FetchCompletionItemParams {
|
|
332
|
-
endpoint: string;
|
|
333
|
-
body: CompletionRequestBody;
|
|
334
|
-
}
|
|
335
338
|
|
|
336
339
|
/**
|
|
337
340
|
* Registers completion functionality with the Monaco editor.
|
|
@@ -355,4 +358,4 @@ declare class Copilot {
|
|
|
355
358
|
private handleCompletionError;
|
|
356
359
|
}
|
|
357
360
|
|
|
358
|
-
export { type AnthropicChatCompletion, type AnthropicModel, type CompletionMetadata, type CompletionRegistration, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, Copilot, type CopilotOptions, type CustomCopilotModel, type CustomCopilotModelConfig, type CustomCopilotModelTransformResponse, type DeepSeekChatCompletion, type GroqChatCompletion, type GroqModel, type Model, type Monaco, type OpenAIChatCompletion, type OpenAIModel, type Provider, type RegisterCompletionOptions, type StandaloneCodeEditor, registerCompletion };
|
|
361
|
+
export { type AnthropicChatCompletion, type AnthropicModel, type CompletionMetadata, type CompletionRegistration, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, Copilot, type CopilotOptions, type CustomCopilotModel, type CustomCopilotModelConfig, type CustomCopilotModelTransformResponse, type DeepSeekChatCompletion, type DeepSeekModel, type GoogleModel, type GroqChatCompletion, type GroqModel, type Model, type Monaco, type OpenAIChatCompletion, type OpenAIModel, type Provider, type RegisterCompletionOptions, type StandaloneCodeEditor, registerCompletion };
|
package/build/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MessageCreateParams, Message } from '@anthropic-ai/sdk/resources';
|
|
2
2
|
import { GenerateContentRequest, GenerateContentResponse } from '@google/generative-ai';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { ChatCompletionCreateParamsBase as ChatCompletionCreateParamsBase$1, ChatCompletion as ChatCompletion$1 } from 'groq-sdk/resources/chat/completions';
|
|
4
|
+
import { ChatCompletionCreateParamsBase, ChatCompletion } from 'openai/resources/chat/completions';
|
|
5
5
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
6
6
|
|
|
7
7
|
declare const MODEL_IDS: Record<Model, string>;
|
|
@@ -58,6 +58,8 @@ interface ProviderImplementationMap {
|
|
|
58
58
|
type OpenAIModel = ProviderImplementationMap['openai']['Model'];
|
|
59
59
|
type GroqModel = ProviderImplementationMap['groq']['Model'];
|
|
60
60
|
type AnthropicModel = ProviderImplementationMap['anthropic']['Model'];
|
|
61
|
+
type GoogleModel = ProviderImplementationMap['google']['Model'];
|
|
62
|
+
type DeepSeekModel = ProviderImplementationMap['deepseek']['Model'];
|
|
61
63
|
/**
|
|
62
64
|
* Union of all predefined Copilot models
|
|
63
65
|
*/
|
|
@@ -114,6 +116,15 @@ type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
|
|
114
116
|
type CursorPosition = monaco.IPosition;
|
|
115
117
|
type EditorRange = monaco.IRange;
|
|
116
118
|
|
|
119
|
+
type FetchCompletionItemHandler = (params: FetchCompletionItemParams) => Promise<FetchCompletionItemReturn>;
|
|
120
|
+
type FetchCompletionItemReturn = {
|
|
121
|
+
completion: string | null;
|
|
122
|
+
};
|
|
123
|
+
interface FetchCompletionItemParams {
|
|
124
|
+
endpoint: string;
|
|
125
|
+
body: CompletionRequestBody;
|
|
126
|
+
}
|
|
127
|
+
|
|
117
128
|
type Endpoint = string;
|
|
118
129
|
type Filename = string;
|
|
119
130
|
type Technologies = string[];
|
|
@@ -324,14 +335,6 @@ interface CompletionMetadata {
|
|
|
324
335
|
completionMode: CompletionMode;
|
|
325
336
|
};
|
|
326
337
|
}
|
|
327
|
-
type FetchCompletionItemHandler = (params: FetchCompletionItemParams) => Promise<FetchCompletionItemReturn>;
|
|
328
|
-
type FetchCompletionItemReturn = {
|
|
329
|
-
completion: string | null;
|
|
330
|
-
};
|
|
331
|
-
interface FetchCompletionItemParams {
|
|
332
|
-
endpoint: string;
|
|
333
|
-
body: CompletionRequestBody;
|
|
334
|
-
}
|
|
335
338
|
|
|
336
339
|
/**
|
|
337
340
|
* Registers completion functionality with the Monaco editor.
|
|
@@ -355,4 +358,4 @@ declare class Copilot {
|
|
|
355
358
|
private handleCompletionError;
|
|
356
359
|
}
|
|
357
360
|
|
|
358
|
-
export { type AnthropicChatCompletion, type AnthropicModel, type CompletionMetadata, type CompletionRegistration, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, Copilot, type CopilotOptions, type CustomCopilotModel, type CustomCopilotModelConfig, type CustomCopilotModelTransformResponse, type DeepSeekChatCompletion, type GroqChatCompletion, type GroqModel, type Model, type Monaco, type OpenAIChatCompletion, type OpenAIModel, type Provider, type RegisterCompletionOptions, type StandaloneCodeEditor, registerCompletion };
|
|
361
|
+
export { type AnthropicChatCompletion, type AnthropicModel, type CompletionMetadata, type CompletionRegistration, type CompletionRequest, type CompletionRequestBody, type CompletionRequestOptions, Copilot, type CopilotOptions, type CustomCopilotModel, type CustomCopilotModelConfig, type CustomCopilotModelTransformResponse, type DeepSeekChatCompletion, type DeepSeekModel, type GoogleModel, type GroqChatCompletion, type GroqModel, type Model, type Monaco, type OpenAIChatCompletion, type OpenAIModel, type Provider, type RegisterCompletionOptions, type StandaloneCodeEditor, registerCompletion };
|
package/build/index.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var ve="\x1B[91m",re="\x1B[93m",W="\x1B[0m",G="\x1B[1m",ne=o=>o instanceof Error?o.message:typeof o=="string"?o:"An unknown error occurred",S=o=>{let e=ne(o),t=`${ve}${G}[MONACOPILOT ERROR] ${e}${W}`;return console.error(t),{message:e}},v=(o,e)=>{console.warn(`${re}${G}[MONACOPILOT WARN] ${o}${e?`
|
|
4
|
-
${ne(e)}`:""}${W}`);};var ie=(o,e,t)=>console.warn(`${re}${G}[MONACOPILOT DEPRECATED] "${o}" is deprecated${` in ${t}`}. Please use "${e}" instead. It will be removed in a future version.${W}`);var w=class{constructor(e,t,r){this.formattedCompletion="";this.currentColumn=0;this.textBeforeCursorInLine="";this.formattedCompletion=e,this.currentColumn=t,this.textBeforeCursorInLine=r;}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}indentByColumn(){let e=this.formattedCompletion.split(`
|
|
1
|
+
'use strict';var Oe="\x1B[91m",re="\x1B[93m",W="\x1B[0m",G="\x1B[1m",ne=o=>o instanceof Error?o.message:typeof o=="string"?o:"An unknown error occurred",S=o=>{let e=ne(o),t=`${Oe}${G}[MONACOPILOT ERROR] ${e}${W}`;return console.error(t),{message:e}},v=(o,e)=>{console.warn(`${re}${G}[MONACOPILOT WARN] ${o}${e?`
|
|
2
|
+
${ne(e)}`:""}${W}`);};var ie=(o,e,t)=>console.warn(`${re}${G}[MONACOPILOT DEPRECATED] "${o}" is deprecated${` in ${t}`}. Please use "${e}" instead. It will be removed in a future version.${W}`);var se=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1];var ae=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),O=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),X=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var w=class{constructor(e){this.capacity=e;this.head=0;this.tail=0;this.size=0;this.buffer=new Array(e);}enqueue(e){let t;return this.size===this.capacity&&(t=this.dequeue()),this.buffer[this.tail]=e,this.tail=(this.tail+1)%this.capacity,this.size++,t}dequeue(){if(this.size===0)return;let e=this.buffer[this.head];return this.buffer[this.head]=undefined,this.head=(this.head+1)%this.capacity,this.size--,e}getAll(){return this.buffer.filter(e=>e!==undefined)}clear(){this.buffer=new Array(this.capacity),this.head=0,this.tail=0,this.size=0;}getSize(){return this.size}isEmpty(){return this.size===0}isFull(){return this.size===this.capacity}};var _=class _{constructor(){this.cache=new w(_.MAX_CACHE_SIZE);}get(e,t){return this.cache.getAll().filter(r=>this.isValidCacheItem(r,e,t))}add(e){this.cache.enqueue(e);}clear(){this.cache.clear();}isValidCacheItem(e,t,r){let n=r.getValueInRange(e.range),i=O(t,r);return i.length<e.textBeforeCursor.length||!i.startsWith(e.textBeforeCursor)?false:this.isPositionValid(e,t,n)}isPositionValid(e,t,r){let{range:n,completion:i}=e,{startLineNumber:s,startColumn:l,endLineNumber:p,endColumn:d}=n,{lineNumber:c,column:a}=t;if(!i.startsWith(r))return false;let u=c===s&&a===l;if(s===p)return u||c===s&&a>=l&&a<=d;let f=c>s&&c<p?true:c===s&&a>=l||c===p&&a<=d;return u||f}};_.MAX_CACHE_SIZE=10;var L=_;var N=class{constructor(e,t,r){this.formattedCompletion="";this.currentColumn=0;this.textBeforeCursorInLine="";this.formattedCompletion=e,this.currentColumn=t,this.textBeforeCursorInLine=r;}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}indentByColumn(){let e=this.formattedCompletion.split(`
|
|
5
3
|
`);if(e.length<=1||this.textBeforeCursorInLine.trim()!=="")return this;let t=" ".repeat(this.currentColumn-1);return this.formattedCompletion=e[0]+`
|
|
6
4
|
`+e.slice(1).map(r=>t+r).join(`
|
|
7
5
|
`),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],s=i.split(`
|
|
8
6
|
`).slice(1,-1).join(`
|
|
9
7
|
`);r=r.replace(i,s);}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
10
8
|
|
|
11
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
12
|
-
`),s=i.length-1,l=r+s,p=s===0?n+i[0].length:i[s].length+1;return new this.monaco.Range(r,n,l,p)}};var
|
|
9
|
+
`),this}build(){return this.formattedCompletion}};var B=class{constructor(e){this.monaco=e;}computeInsertionRange(e,t,r){if(!t)return new this.monaco.Range(e.lineNumber,e.column,e.lineNumber,e.column);let n=r.getOffsetAt(e),i=r.getValue().substring(0,n),s=r.getValue().substring(n),l=0,p=0,d=0,c=0,a=t.length,u=i.length,f=s.length;if(n>=r.getValue().length)return new this.monaco.Range(e.lineNumber,e.column,e.lineNumber,e.column);if(f===0)return new this.monaco.Range(e.lineNumber,e.column,e.lineNumber,e.column);let T=Math.min(a,u);for(let m=1;m<=T;m++){let b=t.substring(0,m),ve=i.slice(-m);b===ve&&(c=m);}let C=Math.min(a,f);for(let m=0;m<C&&t[m]===s[m];m++)l++;for(let m=1;m<=C;m++)t.slice(-m)===s.slice(0,m)&&(p=m);if(d=Math.max(l,p),d===0){for(let m=1;m<a;m++)if(s.startsWith(t.substring(m))){d=a-m;break}}let x=c>0?r.getPositionAt(n-c):e,y=n+d,h=r.getPositionAt(y);return new this.monaco.Range(x.lineNumber,x.column,h.lineNumber,h.column)}computeCacheRange(e,t){let r=e.lineNumber,n=e.column,i=t.split(`
|
|
10
|
+
`),s=i.length-1,l=r+s,p=s===0?n+i[0].length:i[s].length+1;return new this.monaco.Range(r,n,l,p)}};var le="application/json";var pe=async(o,e,t={})=>{let r=t.timeout??3e4,n=AbortSignal.timeout(r),i=t.signal?AbortSignal.any([n,t.signal]):n,s={"Content-Type":"application/json",...t.headers},l=e==="POST"&&t.body?JSON.stringify(t.body):undefined,p=await fetch(o,{method:e,headers:s,body:l,signal:i});if(!p.ok){let d=await p.json().catch(()=>null),c=d?`
|
|
11
|
+
${JSON.stringify(d,null,2)}`:"",a=t.fallbackError||"Network request failed";throw new Error(`${a} (${p.status})${c}`)}return p.json()},Ie=(o,e)=>pe(o,"GET",e),Ae=(o,e,t)=>pe(o,"POST",{...t,body:e}),q={GET:Ie,POST:Ae};var A=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`,me=o=>o.charAt(0).toUpperCase()+o.slice(1),Y=(o,e,t={})=>{if(e<=0)return "";let r=o.split(`
|
|
13
12
|
`),n=r.length;if(e>=n)return o;if(t.from==="end"){let s=r.slice(-e);return s.every(l=>l==="")?`
|
|
14
13
|
`.repeat(e):s.join(`
|
|
15
14
|
`)}let i=r.slice(0,e);return i.every(s=>s==="")?`
|
|
16
15
|
`.repeat(e):i.join(`
|
|
17
|
-
`)};var
|
|
18
|
-
${JSON.stringify(d,null,2)}`:"",a=t.fallbackError||"Network request failed";throw new Error(`${a} (${p.status})${c}`)}return p.json()},Oe=(o,e)=>pe(o,"GET",e),Ie=(o,e,t)=>pe(o,"POST",{...t,body:e}),F={GET:Oe,POST:Ie};var q=(o,e=600,t=200)=>{let r=null,n=0,i=null,s=null,l=!1,p=(...d)=>{if(l)return Promise.resolve(void 0);i=d;let c=Date.now(),a=c-n;n=c,r&&(clearTimeout(r),r=null);let u=a<t?e:t;return s=new Promise((f,x)=>{r=setTimeout(async()=>{l=!0;try{if(i){let C=await o(...i);f(C);}else f(void 0);}catch(C){x(C);}finally{l=!1,r=null,i=null;}},u);}),s};return p.cancel=()=>{r&&(clearTimeout(r),r=null),i=null;},p};var Ae="application/json",me=async o=>{let{endpoint:e,body:t}=o,{completion:r,error:n}=await F.POST(e,t,{headers:{"Content-Type":Ae},fallbackError:"Error while fetching completion item"});if(n)throw new Error(n);return {completion:r}},ce=({pos:o,mdl:e,options:t})=>{let{filename:r,language:n,technologies:i,relatedFiles:s,maxContextLines:l}=t,p=ke(o,e),c=!!s?.length?3:2,a=l?Math.floor(l/c):void 0,u=(R,h,m)=>{let b=R(o,e);return h?Y(b,h,m):b},f=(R,h)=>!R||!h?R:R.map(({content:m,...b})=>({...b,content:Y(m,h)})),x=u(O,a,{from:"end"}),C=u(X,a),T=f(s,a);return {filename:r,language:n,technologies:i,relatedFiles:T,textBeforeCursor:x,textAfterCursor:C,cursorPosition:o,editorState:{completionMode:p}}},ke=(o,e)=>{let t=se(o,e),r=X(o,e);return t?"insert":r.trim()?"complete":"continue"};var I=o=>({items:o,enableForwardStability:!0,suppressSuggestions:!0});var Se=o=>({onTyping:q(o,600,200),onIdle:q(o,600,400),onDemand:q(o,0,0)}),$=new _,de=async({monaco:o,mdl:e,pos:t,token:r,isCompletionAccepted:n,options:i})=>{let{trigger:s="onIdle",endpoint:l,enableCaching:p=!0,onError:d,requestHandler:c}=i;if(p){let a=$.get(t,e).map(u=>({insertText:u.completion,range:u.range}));if(a.length>0)return I(a)}if(r.isCancellationRequested||n)return I([]);try{let u=Se(c??me)[s];r.onCancellationRequested(()=>{u.cancel();});let f=ce({pos:t,mdl:e,options:i}),{completion:x}=await u({endpoint:l,body:{completionMetadata:f}});if(x){let C=new w(x,t.column,ae(t,e)).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().indentByColumn().build(),T=new L(o),R=T.computeInsertionRange(t,C,e),h=T.computeCacheRange(t,C);return p&&$.add({completion:C,range:h,textBeforeCursor:O(t,e)}),I([{insertText:C,range:R}])}}catch(a){if(we(a))return I([]);d?d(a):v("Cannot provide completion",a);}return I([])},we=o=>typeof o=="string"?o==="Cancelled"||o==="AbortError":o instanceof Error?o.message==="Cancelled"||o.name==="AbortError":!1;var J=new WeakMap,k=o=>J.get(o),ue=(o,e)=>{J.set(o,e);},Z=o=>{J.delete(o);},Ce=()=>({isCompletionAccepted:!1,isCompletionVisible:!1,isExplicitlyTriggered:!1,hasRejectedCurrentCompletion:!1});var ge=(o,e,t)=>{let r=k(e);return r?o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(n,i,s,l)=>{if(!(t.trigger==="onDemand"&&!r.isExplicitlyTriggered))return de({monaco:o,mdl:n,pos:i,token:l,isCompletionAccepted:r.isCompletionAccepted,options:t})},handleItemDidShow:(n,i,s)=>{r.isExplicitlyTriggered=!1,r.hasRejectedCurrentCompletion=!1,!r.isCompletionAccepted&&(r.isCompletionVisible=!0,t.onCompletionShown?.(s,i.range));},freeInlineCompletions:()=>{}}):null},fe=o=>{let e=k(o);if(!e){v("Completion is not registered. Use `registerCompletion` to register completion first.");return}e.isExplicitlyTriggered=!0,o.trigger("keyboard","editor.action.inlineSuggest.trigger",{});};var Le={TAB:(o,e)=>e.keyCode===o.KeyCode.Tab,CMD_RIGHT_ARROW:(o,e)=>e.keyCode===o.KeyCode.RightArrow&&e.metaKey},Q=class{constructor(e,t,r){this.monaco=e;this.state=t;this.options=r;}handleKeyEvent(e){let t={monaco:this.monaco,event:e,state:this.state,options:this.options};this.handleCompletionAcceptance(t),this.handleCompletionRejection(t);}handleCompletionAcceptance(e){return e.state.isCompletionVisible&&this.isAcceptanceKey(e.event)?(e.options.onCompletionAccepted?.(),e.state.isCompletionAccepted=!0,e.state.isCompletionVisible=!1,!0):(e.state.isCompletionAccepted=!1,!1)}handleCompletionRejection(e){return this.shouldRejectCompletion(e)?(e.options.onCompletionRejected?.(),e.state.hasRejectedCurrentCompletion=!0,!0):!1}shouldRejectCompletion(e){return e.state.isCompletionVisible&&!e.state.hasRejectedCurrentCompletion&&!e.state.isCompletionAccepted&&!this.isAcceptanceKey(e.event)}isAcceptanceKey(e){return Object.values(Le).some(t=>t(this.monaco,e))}},he=(o,e,t,r)=>{let n=new Q(o,t,r);return e.onKeyDown(i=>n.handleKeyEvent(i))};var D=null,Ne=(o,e,t)=>{D&&D.deregister();let r=[];ue(e,Ce()),e.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});try{let n=k(e);if(!n)return v("Completion is not registered properly. State not found."),_e();let i=ge(o,e,t);i&&r.push(i);let s=he(o,e,n,t);r.push(s);let l={deregister:()=>{r.forEach(p=>p.dispose()),$.clear(),Z(e),D=null;},trigger:()=>fe(e)};return D=l,l}catch(n){return t.onError?t.onError(n):S(n),{deregister:()=>{r.forEach(i=>i.dispose()),Z(e),D=null;},trigger:()=>{}}}},_e=()=>({deregister:()=>{},trigger:()=>{}});var Be=o=>!o||o.length===0?"":o.map(({path:e,content:t})=>`
|
|
16
|
+
`)};var ce=async o=>{let{endpoint:e,body:t}=o,{completion:r,error:n}=await q.POST(e,t,{headers:{"Content-Type":le},fallbackError:"Error while fetching completion item"});if(n)throw new Error(n);return {completion:r}},de=({pos:o,mdl:e,options:t})=>{let{filename:r,language:n,technologies:i,relatedFiles:s,maxContextLines:l}=t,p=ke(o,e),c=!!s?.length?3:2,a=l?Math.floor(l/c):undefined,u=(y,h,m)=>{let b=y(o,e);return h?Y(b,h,m):b},f=(y,h)=>!y||!h?y:y.map(({content:m,...b})=>({...b,content:Y(m,h)})),T=u(O,a,{from:"end"}),C=u(X,a),x=f(s,a);return {filename:r,language:n,technologies:i,relatedFiles:x,textBeforeCursor:T,textAfterCursor:C,cursorPosition:o,editorState:{completionMode:p}}},ke=(o,e)=>{let t=se(o,e),r=X(o,e);return t?"insert":r.trim()?"complete":"continue"};var I=o=>({items:o,enableForwardStability:true,suppressSuggestions:true});var F=(o,e=600,t=200)=>{let r=null,n=0,i=null,s=null,l=false,p=(...d)=>{if(l)return Promise.resolve(undefined);i=d;let c=Date.now(),a=c-n;n=c,r&&(clearTimeout(r),r=null);let u=a<t?e:t;return s=new Promise((f,T)=>{r=setTimeout(async()=>{l=true;try{if(i){let C=await o(...i);f(C);}else f(void 0);}catch(C){T(C);}finally{l=false,r=null,i=null;}},u);}),s};return p.cancel=()=>{r&&(clearTimeout(r),r=null),i=null;},p};var Se=o=>({onTyping:F(o,600,200),onIdle:F(o,600,400),onDemand:F(o,0,0)}),$=new L,ue=async({monaco:o,mdl:e,pos:t,token:r,isCompletionAccepted:n,options:i})=>{let{trigger:s="onIdle",endpoint:l,enableCaching:p=true,onError:d,requestHandler:c}=i;if(p){let a=$.get(t,e).map(u=>({insertText:u.completion,range:u.range}));if(a.length>0)return I(a)}if(r.isCancellationRequested||n)return I([]);try{let u=Se(c??ce)[s];r.onCancellationRequested(()=>{u.cancel();});let f=de({pos:t,mdl:e,options:i}),{completion:T}=await u({endpoint:l,body:{completionMetadata:f}});if(T){let C=new N(T,t.column,ae(t,e)).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().indentByColumn().build(),x=new B(o),y=x.computeInsertionRange(t,C,e),h=x.computeCacheRange(t,C);return p&&$.add({completion:C,range:h,textBeforeCursor:O(t,e)}),I([{insertText:C,range:y}])}}catch(a){if(we(a))return I([]);d?d(a):v("Cannot provide completion",a);}return I([])},we=o=>typeof o=="string"?o==="Cancelled"||o==="AbortError":o instanceof Error?o.message==="Cancelled"||o.name==="AbortError":false;var J=new WeakMap,k=o=>J.get(o),Ce=(o,e)=>{J.set(o,e);},Z=o=>{J.delete(o);},ge=()=>({isCompletionAccepted:false,isCompletionVisible:false,isExplicitlyTriggered:false,hasRejectedCurrentCompletion:false});var fe=(o,e,t)=>{let r=k(e);return r?o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(n,i,s,l)=>{if(!(t.trigger==="onDemand"&&!r.isExplicitlyTriggered))return ue({monaco:o,mdl:n,pos:i,token:l,isCompletionAccepted:r.isCompletionAccepted,options:t})},handleItemDidShow:(n,i,s)=>{r.isExplicitlyTriggered=false,r.hasRejectedCurrentCompletion=false,!r.isCompletionAccepted&&(r.isCompletionVisible=true,t.onCompletionShown?.(s,i.range));},freeInlineCompletions:()=>{}}):null},he=o=>{let e=k(o);if(!e){v("Completion is not registered. Use `registerCompletion` to register completion first.");return}e.isExplicitlyTriggered=true,o.trigger("keyboard","editor.action.inlineSuggest.trigger",{});};var Le={TAB:(o,e)=>e.keyCode===o.KeyCode.Tab,CMD_RIGHT_ARROW:(o,e)=>e.keyCode===o.KeyCode.RightArrow&&e.metaKey},Q=class{constructor(e,t,r){this.monaco=e;this.state=t;this.options=r;}handleKeyEvent(e){let t={monaco:this.monaco,event:e,state:this.state,options:this.options};this.handleCompletionAcceptance(t),this.handleCompletionRejection(t);}handleCompletionAcceptance(e){return e.state.isCompletionVisible&&this.isAcceptanceKey(e.event)?(e.options.onCompletionAccepted?.(),e.state.isCompletionAccepted=true,e.state.isCompletionVisible=false,true):(e.state.isCompletionAccepted=false,false)}handleCompletionRejection(e){return this.shouldRejectCompletion(e)?(e.options.onCompletionRejected?.(),e.state.hasRejectedCurrentCompletion=true,true):false}shouldRejectCompletion(e){return e.state.isCompletionVisible&&!e.state.hasRejectedCurrentCompletion&&!e.state.isCompletionAccepted&&!this.isAcceptanceKey(e.event)}isAcceptanceKey(e){return Object.values(Le).some(t=>t(this.monaco,e))}},Pe=(o,e,t,r)=>{let n=new Q(o,t,r);return e.onKeyDown(i=>n.handleKeyEvent(i))};var D=null,_e=(o,e,t)=>{D&&D.deregister();let r=[];Ce(e,ge()),e.updateOptions({inlineSuggest:{enabled:true,mode:"subwordSmart"}});try{let n=k(e);if(!n)return v("Completion is not registered properly. State not found."),Ne();let i=fe(o,e,t);i&&r.push(i);let s=Pe(o,e,n,t);r.push(s);let l={deregister:()=>{r.forEach(p=>p.dispose()),$.clear(),Z(e),D=null;},trigger:()=>he(e)};return D=l,l}catch(n){return t.onError?t.onError(n):S(n),{deregister:()=>{r.forEach(i=>i.dispose()),Z(e),D=null;},trigger:()=>{}}}},Ne=()=>({deregister:()=>{},trigger:()=>{}});var ee=["groq","openai","anthropic","google","deepseek"],P={"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-20241022","claude-3-haiku":"claude-3-haiku-20240307","claude-3-5-haiku":"claude-3-5-haiku-20241022","o1-mini":"o1-mini","gemini-1.5-flash-8b":"gemini-1.5-flash-8b","gemini-1.5-flash":"gemini-1.5-flash","gemini-1.5-pro":"gemini-1.5-pro",v3:"deepseek-chat"},te={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-mini"],anthropic:["claude-3-5-sonnet","claude-3-haiku","claude-3-5-haiku"],google:["gemini-1.5-flash-8b","gemini-1.5-pro","gemini-1.5-flash"],deepseek:["v3"]},E={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages",google:"https://generativelanguage.googleapis.com/v1beta/models",deepseek:"https://api.deepseek.com/beta/completions"};var g=class{};var j=class extends g{createEndpoint(){return E.anthropic}createRequestBody(e,t){return {model:P[e],temperature:.1,system:t.system,messages:[{role:"user",content:t.user}],max_tokens:500}}createHeaders(e){return {"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}}parseCompletion(e){let t=e.content?.[0];return t&&"text"in t?t.text:null}};var H=class extends g{createEndpoint(){return E.deepseek}createRequestBody(e,t,r){return {model:P[e],prompt:r.textBeforeCursor,suffix:r.textAfterCursor,temperature:.1,max_tokens:500}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return typeof e.choices?.[0]?.text=="string"?e.choices[0].text:null}};var K=class extends g{createEndpoint(e,t){return `${E.google}/${P[e]}:generateContent?key=${t}`}createRequestBody(e,t){return {systemInstruction:{role:"system",parts:[{text:t.system}]},generationConfig:{temperature:.1,maxOutputTokens:500},contents:[{role:"user",parts:[{text:t.user}]}]}}createHeaders(){return {"Content-Type":"application/json"}}parseCompletion(e){return e.candidates?.[0]?.content?.parts?.[0]?.text??null}};var V=class extends g{createEndpoint(){return E.groq}createRequestBody(e,t){return {model:P[e],temperature:.1,max_tokens:500,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return e.choices?.[0]?.message.content??null}};var U=class extends g{createEndpoint(){return E.openai}createRequestBody(e,t){let r=e==="o1-mini";return {model:P[e],...!r&&{temperature:.1},max_completion_tokens:500,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return e.choices?.[0]?.message.content??null}};var z={openai:new U,groq:new V,anthropic:new j,google:new K,deepseek:new H},Ee=(o,e,t)=>z[t].createEndpoint(o,e),ye=(o,e,t,r)=>z[e].createRequestBody(o,t,r),Re=(o,e)=>z[e].createHeaders(o),Me=(o,e)=>z[e].parseCompletion(o);var Be=o=>!o||o.length===0?"":o.map(({path:e,content:t})=>`
|
|
19
17
|
<related_file>
|
|
20
18
|
<filePath>${e}</filePath>
|
|
21
19
|
<fileContent>
|
|
@@ -25,7 +23,7 @@ ${t}
|
|
|
25
23
|
</fileContent>
|
|
26
24
|
</related_file>`.trim()).join(`
|
|
27
25
|
|
|
28
|
-
`),
|
|
26
|
+
`),Te=o=>{let{technologies:e=[],filename:t,relatedFiles:r,language:n,textBeforeCursor:i="",textAfterCursor:s="",editorState:{completionMode:l}}=o,p=A([n,...e].filter(a=>typeof a=="string"&&!!a)),d=`
|
|
29
27
|
You are an expert code completion assistant.
|
|
30
28
|
|
|
31
29
|
**Context:**
|
|
@@ -41,9 +39,6 @@ ${Be(r)}
|
|
|
41
39
|
${i}<cursor>${s}
|
|
42
40
|
\`\`\`
|
|
43
41
|
|
|
44
|
-
${
|
|
45
|
-
|
|
46
|
-
Output only the raw code to be inserted at the cursor location without any additional text or comments.`;return {system:d,user:c}};var ee=["groq","openai","anthropic","google","deepseek"],P={"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-20241022","claude-3-haiku":"claude-3-haiku-20240307","claude-3-5-haiku":"claude-3-5-haiku-20241022","o1-mini":"o1-mini","gemini-1.5-flash-8b":"gemini-1.5-flash-8b","gemini-1.5-flash":"gemini-1.5-flash","gemini-1.5-pro":"gemini-1.5-pro",v3:"deepseek-chat"},te={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-mini"],anthropic:["claude-3-5-sonnet","claude-3-haiku","claude-3-5-haiku"],google:["gemini-1.5-flash-8b","gemini-1.5-pro","gemini-1.5-flash"],deepseek:["v3"]},E={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages",google:"https://generativelanguage.googleapis.com/v1beta/models",deepseek:"https://api.deepseek.com/beta/completions"};var g=class{};var j=class extends g{createEndpoint(){return E.anthropic}createRequestBody(e,t){return {model:P[e],temperature:.1,system:t.system,messages:[{role:"user",content:t.user}],max_tokens:500}}createHeaders(e){return {"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}}parseCompletion(e){let t=e.content?.[0];return t&&"text"in t?t.text:null}};var H=class extends g{createEndpoint(){return E.deepseek}createRequestBody(e,t,r){return {model:P[e],prompt:r.textBeforeCursor,suffix:r.textAfterCursor,temperature:.1,max_tokens:500}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return typeof e.choices?.[0]?.text=="string"?e.choices[0].text:null}};var K=class extends g{createEndpoint(e,t){return `${E.google}/${P[e]}:generateContent?key=${t}`}createRequestBody(e,t){return {systemInstruction:{role:"system",parts:[{text:t.system}]},generationConfig:{temperature:.1,maxOutputTokens:500},contents:[{role:"user",parts:[{text:t.user}]}]}}createHeaders(){return {"Content-Type":"application/json"}}parseCompletion(e){return e.candidates?.[0]?.content?.parts?.[0]?.text??null}};var V=class extends g{createEndpoint(){return E.groq}createRequestBody(e,t){return {model:P[e],temperature:.1,max_tokens:500,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return e.choices?.[0]?.message.content??null}};var U=class extends g{createEndpoint(){return E.openai}createRequestBody(e,t){let r=e==="o1-mini";return {model:P[e],...!r&&{temperature:.1},max_completion_tokens:500,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return e.choices?.[0]?.message.content??null}};var z={openai:new U,groq:new V,anthropic:new j,google:new K,deepseek:new H},Ee=(o,e,t)=>z[t].createEndpoint(o,e),Re=(o,e,t,r)=>z[e].createRequestBody(o,t,r),ye=(o,e)=>z[e].createHeaders(o),Me=(o,e)=>z[e].parseCompletion(o);var xe=(o,e)=>{if(!o)throw new Error("Please provide an API key.");if(!e||typeof e=="object"&&Object.keys(e).length===0)throw new Error("Please provide options.")},Te=(o,e)=>{if(typeof o=="object"){if(e!==void 0)throw new Error("Provider should not be specified when using a custom model.");if(!("config"in o)||!("transformResponse"in o))throw new Error("Please ensure both config and transformResponse are provided for custom model.");return}if(!e||!ee.includes(e))throw new Error(`Provider must be specified and supported when using built-in models. Please choose from: ${A(ee)}`);if(typeof o=="string"&&!te[e].includes(o))throw new Error(`Model "${o}" is not supported by the "${e}" provider. Supported models: ${A(te[e])}`)};var oe=class{constructor(e,t){xe(e,t),this.apiKey=e,this.provider=t.provider,this.model=t.model,Te(this.model,this.provider);}async complete(e){let{body:t,options:r}=e,{completionMetadata:n}=t,{headers:i={},customPrompt:s}=r??{},l=this.generatePrompt(n,s),{endpoint:p,requestBody:d,headers:c}=this.prepareRequestDetails(l,n);try{let a=await this.sendCompletionRequest(p,d,{...c,...i});return this.processCompletionResponse(a)}catch(a){return this.handleCompletionError(a)}}generatePrompt(e,t){let r=Pe(e);return t?{...r,...t(e)}:r}prepareRequestDetails(e,t){if(typeof this.model=="object"&&"config"in this.model){let r=this.model.config(this.apiKey,e),n=r.endpoint,i=r.body??{},s=r.headers??{};return {endpoint:n,requestBody:i,headers:s}}else {if(!this.provider)throw new Error("Provider is required for non-custom models");let r=Ee(this.model,this.apiKey,this.provider),n=ye(this.apiKey,this.provider),i=Re(this.model,this.provider,e,t);return {endpoint:r,requestBody:i,headers:n}}}async sendCompletionRequest(e,t,r){return F.POST(e,t,{headers:r})}processCompletionResponse(e){if(typeof this.model=="object"&&"transformResponse"in this.model){let t=this.model.transformResponse(e);return "completion"in t&&ie("completion","text","Copilot.options.model.transformResponse"),{completion:t.text??t.completion??null,raw:e}}else {if(!this.provider)throw new Error("Provider is required for non-custom models");return {completion:Me(e,this.provider),raw:e}}}handleCompletionError(e){return {error:S(e).message,completion:null}}};
|
|
42
|
+
${me(l)} the code at <cursor>.
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
exports.registerCompletion = Ne;
|
|
44
|
+
Output only the raw code to be inserted at the cursor location without any additional text or comments.`;return {system:d,user:c}};var xe=(o,e)=>{if(!o)throw new Error("Please provide an API key.");if(!e||typeof e=="object"&&Object.keys(e).length===0)throw new Error("Please provide options.")},be=(o,e)=>{if(typeof o=="object"){if(e!==undefined)throw new Error("Provider should not be specified when using a custom model.");if(!("config"in o)||!("transformResponse"in o))throw new Error("Please ensure both config and transformResponse are provided for custom model.");return}if(!e||!ee.includes(e))throw new Error(`Provider must be specified and supported when using built-in models. Please choose from: ${A(ee)}`);if(typeof o=="string"&&!te[e].includes(o))throw new Error(`Model "${o}" is not supported by the "${e}" provider. Supported models: ${A(te[e])}`)};var oe=class{constructor(e,t){xe(e,t),this.apiKey=e,this.provider=t.provider,this.model=t.model,be(this.model,this.provider);}async complete(e){let{body:t,options:r}=e,{completionMetadata:n}=t,{headers:i={},customPrompt:s}=r??{},l=this.generatePrompt(n,s),{endpoint:p,requestBody:d,headers:c}=this.prepareRequestDetails(l,n);try{let a=await this.sendCompletionRequest(p,d,{...c,...i});return this.processCompletionResponse(a)}catch(a){return this.handleCompletionError(a)}}generatePrompt(e,t){let r=Te(e);return t?{...r,...t(e)}:r}prepareRequestDetails(e,t){if(typeof this.model=="object"&&"config"in this.model){let r=this.model.config(this.apiKey,e),n=r.endpoint,i=r.body??{},s=r.headers??{};return {endpoint:n,requestBody:i,headers:s}}else {if(!this.provider)throw new Error("Provider is required for non-custom models");let r=Ee(this.model,this.apiKey,this.provider),n=Re(this.apiKey,this.provider),i=ye(this.model,this.provider,e,t);return {endpoint:r,requestBody:i,headers:n}}}async sendCompletionRequest(e,t,r){return q.POST(e,t,{headers:r})}processCompletionResponse(e){if(typeof this.model=="object"&&"transformResponse"in this.model){let t=this.model.transformResponse(e);return "completion"in t&&ie("completion","text","Copilot.options.model.transformResponse"),{completion:t.text??t.completion??null,raw:e}}else {if(!this.provider)throw new Error("Provider is required for non-custom models");return {completion:Me(e,this.provider),raw:e}}}handleCompletionError(e){return {error:S(e).message,completion:null}}};exports.Copilot=oe;exports.registerCompletion=_e;
|
package/build/index.mjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var
|
|
2
|
-
${ne(e)}`:""}${W}`);};var ie=(o,e,t)=>console.warn(`${re}${G}[MONACOPILOT DEPRECATED] "${o}" is deprecated${` in ${t}`}. Please use "${e}" instead. It will be removed in a future version.${W}`);var w=class{constructor(e,t,r){this.formattedCompletion="";this.currentColumn=0;this.textBeforeCursorInLine="";this.formattedCompletion=e,this.currentColumn=t,this.textBeforeCursorInLine=r;}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}indentByColumn(){let e=this.formattedCompletion.split(`
|
|
1
|
+
var Oe="\x1B[91m",re="\x1B[93m",W="\x1B[0m",G="\x1B[1m",ne=o=>o instanceof Error?o.message:typeof o=="string"?o:"An unknown error occurred",S=o=>{let e=ne(o),t=`${Oe}${G}[MONACOPILOT ERROR] ${e}${W}`;return console.error(t),{message:e}},v=(o,e)=>{console.warn(`${re}${G}[MONACOPILOT WARN] ${o}${e?`
|
|
2
|
+
${ne(e)}`:""}${W}`);};var ie=(o,e,t)=>console.warn(`${re}${G}[MONACOPILOT DEPRECATED] "${o}" is deprecated${` in ${t}`}. Please use "${e}" instead. It will be removed in a future version.${W}`);var se=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1];var ae=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),O=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),X=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var w=class{constructor(e){this.capacity=e;this.head=0;this.tail=0;this.size=0;this.buffer=new Array(e);}enqueue(e){let t;return this.size===this.capacity&&(t=this.dequeue()),this.buffer[this.tail]=e,this.tail=(this.tail+1)%this.capacity,this.size++,t}dequeue(){if(this.size===0)return;let e=this.buffer[this.head];return this.buffer[this.head]=undefined,this.head=(this.head+1)%this.capacity,this.size--,e}getAll(){return this.buffer.filter(e=>e!==undefined)}clear(){this.buffer=new Array(this.capacity),this.head=0,this.tail=0,this.size=0;}getSize(){return this.size}isEmpty(){return this.size===0}isFull(){return this.size===this.capacity}};var _=class _{constructor(){this.cache=new w(_.MAX_CACHE_SIZE);}get(e,t){return this.cache.getAll().filter(r=>this.isValidCacheItem(r,e,t))}add(e){this.cache.enqueue(e);}clear(){this.cache.clear();}isValidCacheItem(e,t,r){let n=r.getValueInRange(e.range),i=O(t,r);return i.length<e.textBeforeCursor.length||!i.startsWith(e.textBeforeCursor)?false:this.isPositionValid(e,t,n)}isPositionValid(e,t,r){let{range:n,completion:i}=e,{startLineNumber:s,startColumn:l,endLineNumber:p,endColumn:d}=n,{lineNumber:c,column:a}=t;if(!i.startsWith(r))return false;let u=c===s&&a===l;if(s===p)return u||c===s&&a>=l&&a<=d;let f=c>s&&c<p?true:c===s&&a>=l||c===p&&a<=d;return u||f}};_.MAX_CACHE_SIZE=10;var L=_;var N=class{constructor(e,t,r){this.formattedCompletion="";this.currentColumn=0;this.textBeforeCursorInLine="";this.formattedCompletion=e,this.currentColumn=t,this.textBeforeCursorInLine=r;}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}indentByColumn(){let e=this.formattedCompletion.split(`
|
|
3
3
|
`);if(e.length<=1||this.textBeforeCursorInLine.trim()!=="")return this;let t=" ".repeat(this.currentColumn-1);return this.formattedCompletion=e[0]+`
|
|
4
4
|
`+e.slice(1).map(r=>t+r).join(`
|
|
5
5
|
`),this}removeMarkdownCodeBlocks(e){let t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],s=i.split(`
|
|
6
6
|
`).slice(1,-1).join(`
|
|
7
7
|
`);r=r.replace(i,s);}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
8
8
|
|
|
9
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
10
|
-
`),s=i.length-1,l=r+s,p=s===0?n+i[0].length:i[s].length+1;return new this.monaco.Range(r,n,l,p)}};var
|
|
9
|
+
`),this}build(){return this.formattedCompletion}};var B=class{constructor(e){this.monaco=e;}computeInsertionRange(e,t,r){if(!t)return new this.monaco.Range(e.lineNumber,e.column,e.lineNumber,e.column);let n=r.getOffsetAt(e),i=r.getValue().substring(0,n),s=r.getValue().substring(n),l=0,p=0,d=0,c=0,a=t.length,u=i.length,f=s.length;if(n>=r.getValue().length)return new this.monaco.Range(e.lineNumber,e.column,e.lineNumber,e.column);if(f===0)return new this.monaco.Range(e.lineNumber,e.column,e.lineNumber,e.column);let T=Math.min(a,u);for(let m=1;m<=T;m++){let b=t.substring(0,m),ve=i.slice(-m);b===ve&&(c=m);}let C=Math.min(a,f);for(let m=0;m<C&&t[m]===s[m];m++)l++;for(let m=1;m<=C;m++)t.slice(-m)===s.slice(0,m)&&(p=m);if(d=Math.max(l,p),d===0){for(let m=1;m<a;m++)if(s.startsWith(t.substring(m))){d=a-m;break}}let x=c>0?r.getPositionAt(n-c):e,y=n+d,h=r.getPositionAt(y);return new this.monaco.Range(x.lineNumber,x.column,h.lineNumber,h.column)}computeCacheRange(e,t){let r=e.lineNumber,n=e.column,i=t.split(`
|
|
10
|
+
`),s=i.length-1,l=r+s,p=s===0?n+i[0].length:i[s].length+1;return new this.monaco.Range(r,n,l,p)}};var le="application/json";var pe=async(o,e,t={})=>{let r=t.timeout??3e4,n=AbortSignal.timeout(r),i=t.signal?AbortSignal.any([n,t.signal]):n,s={"Content-Type":"application/json",...t.headers},l=e==="POST"&&t.body?JSON.stringify(t.body):undefined,p=await fetch(o,{method:e,headers:s,body:l,signal:i});if(!p.ok){let d=await p.json().catch(()=>null),c=d?`
|
|
11
|
+
${JSON.stringify(d,null,2)}`:"",a=t.fallbackError||"Network request failed";throw new Error(`${a} (${p.status})${c}`)}return p.json()},Ie=(o,e)=>pe(o,"GET",e),Ae=(o,e,t)=>pe(o,"POST",{...t,body:e}),q={GET:Ie,POST:Ae};var A=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`,me=o=>o.charAt(0).toUpperCase()+o.slice(1),Y=(o,e,t={})=>{if(e<=0)return "";let r=o.split(`
|
|
11
12
|
`),n=r.length;if(e>=n)return o;if(t.from==="end"){let s=r.slice(-e);return s.every(l=>l==="")?`
|
|
12
13
|
`.repeat(e):s.join(`
|
|
13
14
|
`)}let i=r.slice(0,e);return i.every(s=>s==="")?`
|
|
14
15
|
`.repeat(e):i.join(`
|
|
15
|
-
`)};var
|
|
16
|
-
${JSON.stringify(d,null,2)}`:"",a=t.fallbackError||"Network request failed";throw new Error(`${a} (${p.status})${c}`)}return p.json()},Oe=(o,e)=>pe(o,"GET",e),Ie=(o,e,t)=>pe(o,"POST",{...t,body:e}),F={GET:Oe,POST:Ie};var q=(o,e=600,t=200)=>{let r=null,n=0,i=null,s=null,l=!1,p=(...d)=>{if(l)return Promise.resolve(void 0);i=d;let c=Date.now(),a=c-n;n=c,r&&(clearTimeout(r),r=null);let u=a<t?e:t;return s=new Promise((f,x)=>{r=setTimeout(async()=>{l=!0;try{if(i){let C=await o(...i);f(C);}else f(void 0);}catch(C){x(C);}finally{l=!1,r=null,i=null;}},u);}),s};return p.cancel=()=>{r&&(clearTimeout(r),r=null),i=null;},p};var Ae="application/json",me=async o=>{let{endpoint:e,body:t}=o,{completion:r,error:n}=await F.POST(e,t,{headers:{"Content-Type":Ae},fallbackError:"Error while fetching completion item"});if(n)throw new Error(n);return {completion:r}},ce=({pos:o,mdl:e,options:t})=>{let{filename:r,language:n,technologies:i,relatedFiles:s,maxContextLines:l}=t,p=ke(o,e),c=!!s?.length?3:2,a=l?Math.floor(l/c):void 0,u=(R,h,m)=>{let b=R(o,e);return h?Y(b,h,m):b},f=(R,h)=>!R||!h?R:R.map(({content:m,...b})=>({...b,content:Y(m,h)})),x=u(O,a,{from:"end"}),C=u(X,a),T=f(s,a);return {filename:r,language:n,technologies:i,relatedFiles:T,textBeforeCursor:x,textAfterCursor:C,cursorPosition:o,editorState:{completionMode:p}}},ke=(o,e)=>{let t=se(o,e),r=X(o,e);return t?"insert":r.trim()?"complete":"continue"};var I=o=>({items:o,enableForwardStability:!0,suppressSuggestions:!0});var Se=o=>({onTyping:q(o,600,200),onIdle:q(o,600,400),onDemand:q(o,0,0)}),$=new _,de=async({monaco:o,mdl:e,pos:t,token:r,isCompletionAccepted:n,options:i})=>{let{trigger:s="onIdle",endpoint:l,enableCaching:p=!0,onError:d,requestHandler:c}=i;if(p){let a=$.get(t,e).map(u=>({insertText:u.completion,range:u.range}));if(a.length>0)return I(a)}if(r.isCancellationRequested||n)return I([]);try{let u=Se(c??me)[s];r.onCancellationRequested(()=>{u.cancel();});let f=ce({pos:t,mdl:e,options:i}),{completion:x}=await u({endpoint:l,body:{completionMetadata:f}});if(x){let C=new w(x,t.column,ae(t,e)).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().indentByColumn().build(),T=new L(o),R=T.computeInsertionRange(t,C,e),h=T.computeCacheRange(t,C);return p&&$.add({completion:C,range:h,textBeforeCursor:O(t,e)}),I([{insertText:C,range:R}])}}catch(a){if(we(a))return I([]);d?d(a):v("Cannot provide completion",a);}return I([])},we=o=>typeof o=="string"?o==="Cancelled"||o==="AbortError":o instanceof Error?o.message==="Cancelled"||o.name==="AbortError":!1;var J=new WeakMap,k=o=>J.get(o),ue=(o,e)=>{J.set(o,e);},Z=o=>{J.delete(o);},Ce=()=>({isCompletionAccepted:!1,isCompletionVisible:!1,isExplicitlyTriggered:!1,hasRejectedCurrentCompletion:!1});var ge=(o,e,t)=>{let r=k(e);return r?o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(n,i,s,l)=>{if(!(t.trigger==="onDemand"&&!r.isExplicitlyTriggered))return de({monaco:o,mdl:n,pos:i,token:l,isCompletionAccepted:r.isCompletionAccepted,options:t})},handleItemDidShow:(n,i,s)=>{r.isExplicitlyTriggered=!1,r.hasRejectedCurrentCompletion=!1,!r.isCompletionAccepted&&(r.isCompletionVisible=!0,t.onCompletionShown?.(s,i.range));},freeInlineCompletions:()=>{}}):null},fe=o=>{let e=k(o);if(!e){v("Completion is not registered. Use `registerCompletion` to register completion first.");return}e.isExplicitlyTriggered=!0,o.trigger("keyboard","editor.action.inlineSuggest.trigger",{});};var Le={TAB:(o,e)=>e.keyCode===o.KeyCode.Tab,CMD_RIGHT_ARROW:(o,e)=>e.keyCode===o.KeyCode.RightArrow&&e.metaKey},Q=class{constructor(e,t,r){this.monaco=e;this.state=t;this.options=r;}handleKeyEvent(e){let t={monaco:this.monaco,event:e,state:this.state,options:this.options};this.handleCompletionAcceptance(t),this.handleCompletionRejection(t);}handleCompletionAcceptance(e){return e.state.isCompletionVisible&&this.isAcceptanceKey(e.event)?(e.options.onCompletionAccepted?.(),e.state.isCompletionAccepted=!0,e.state.isCompletionVisible=!1,!0):(e.state.isCompletionAccepted=!1,!1)}handleCompletionRejection(e){return this.shouldRejectCompletion(e)?(e.options.onCompletionRejected?.(),e.state.hasRejectedCurrentCompletion=!0,!0):!1}shouldRejectCompletion(e){return e.state.isCompletionVisible&&!e.state.hasRejectedCurrentCompletion&&!e.state.isCompletionAccepted&&!this.isAcceptanceKey(e.event)}isAcceptanceKey(e){return Object.values(Le).some(t=>t(this.monaco,e))}},he=(o,e,t,r)=>{let n=new Q(o,t,r);return e.onKeyDown(i=>n.handleKeyEvent(i))};var D=null,Ne=(o,e,t)=>{D&&D.deregister();let r=[];ue(e,Ce()),e.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});try{let n=k(e);if(!n)return v("Completion is not registered properly. State not found."),_e();let i=ge(o,e,t);i&&r.push(i);let s=he(o,e,n,t);r.push(s);let l={deregister:()=>{r.forEach(p=>p.dispose()),$.clear(),Z(e),D=null;},trigger:()=>fe(e)};return D=l,l}catch(n){return t.onError?t.onError(n):S(n),{deregister:()=>{r.forEach(i=>i.dispose()),Z(e),D=null;},trigger:()=>{}}}},_e=()=>({deregister:()=>{},trigger:()=>{}});var Be=o=>!o||o.length===0?"":o.map(({path:e,content:t})=>`
|
|
16
|
+
`)};var ce=async o=>{let{endpoint:e,body:t}=o,{completion:r,error:n}=await q.POST(e,t,{headers:{"Content-Type":le},fallbackError:"Error while fetching completion item"});if(n)throw new Error(n);return {completion:r}},de=({pos:o,mdl:e,options:t})=>{let{filename:r,language:n,technologies:i,relatedFiles:s,maxContextLines:l}=t,p=ke(o,e),c=!!s?.length?3:2,a=l?Math.floor(l/c):undefined,u=(y,h,m)=>{let b=y(o,e);return h?Y(b,h,m):b},f=(y,h)=>!y||!h?y:y.map(({content:m,...b})=>({...b,content:Y(m,h)})),T=u(O,a,{from:"end"}),C=u(X,a),x=f(s,a);return {filename:r,language:n,technologies:i,relatedFiles:x,textBeforeCursor:T,textAfterCursor:C,cursorPosition:o,editorState:{completionMode:p}}},ke=(o,e)=>{let t=se(o,e),r=X(o,e);return t?"insert":r.trim()?"complete":"continue"};var I=o=>({items:o,enableForwardStability:true,suppressSuggestions:true});var F=(o,e=600,t=200)=>{let r=null,n=0,i=null,s=null,l=false,p=(...d)=>{if(l)return Promise.resolve(undefined);i=d;let c=Date.now(),a=c-n;n=c,r&&(clearTimeout(r),r=null);let u=a<t?e:t;return s=new Promise((f,T)=>{r=setTimeout(async()=>{l=true;try{if(i){let C=await o(...i);f(C);}else f(void 0);}catch(C){T(C);}finally{l=false,r=null,i=null;}},u);}),s};return p.cancel=()=>{r&&(clearTimeout(r),r=null),i=null;},p};var Se=o=>({onTyping:F(o,600,200),onIdle:F(o,600,400),onDemand:F(o,0,0)}),$=new L,ue=async({monaco:o,mdl:e,pos:t,token:r,isCompletionAccepted:n,options:i})=>{let{trigger:s="onIdle",endpoint:l,enableCaching:p=true,onError:d,requestHandler:c}=i;if(p){let a=$.get(t,e).map(u=>({insertText:u.completion,range:u.range}));if(a.length>0)return I(a)}if(r.isCancellationRequested||n)return I([]);try{let u=Se(c??ce)[s];r.onCancellationRequested(()=>{u.cancel();});let f=de({pos:t,mdl:e,options:i}),{completion:T}=await u({endpoint:l,body:{completionMetadata:f}});if(T){let C=new N(T,t.column,ae(t,e)).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().indentByColumn().build(),x=new B(o),y=x.computeInsertionRange(t,C,e),h=x.computeCacheRange(t,C);return p&&$.add({completion:C,range:h,textBeforeCursor:O(t,e)}),I([{insertText:C,range:y}])}}catch(a){if(we(a))return I([]);d?d(a):v("Cannot provide completion",a);}return I([])},we=o=>typeof o=="string"?o==="Cancelled"||o==="AbortError":o instanceof Error?o.message==="Cancelled"||o.name==="AbortError":false;var J=new WeakMap,k=o=>J.get(o),Ce=(o,e)=>{J.set(o,e);},Z=o=>{J.delete(o);},ge=()=>({isCompletionAccepted:false,isCompletionVisible:false,isExplicitlyTriggered:false,hasRejectedCurrentCompletion:false});var fe=(o,e,t)=>{let r=k(e);return r?o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(n,i,s,l)=>{if(!(t.trigger==="onDemand"&&!r.isExplicitlyTriggered))return ue({monaco:o,mdl:n,pos:i,token:l,isCompletionAccepted:r.isCompletionAccepted,options:t})},handleItemDidShow:(n,i,s)=>{r.isExplicitlyTriggered=false,r.hasRejectedCurrentCompletion=false,!r.isCompletionAccepted&&(r.isCompletionVisible=true,t.onCompletionShown?.(s,i.range));},freeInlineCompletions:()=>{}}):null},he=o=>{let e=k(o);if(!e){v("Completion is not registered. Use `registerCompletion` to register completion first.");return}e.isExplicitlyTriggered=true,o.trigger("keyboard","editor.action.inlineSuggest.trigger",{});};var Le={TAB:(o,e)=>e.keyCode===o.KeyCode.Tab,CMD_RIGHT_ARROW:(o,e)=>e.keyCode===o.KeyCode.RightArrow&&e.metaKey},Q=class{constructor(e,t,r){this.monaco=e;this.state=t;this.options=r;}handleKeyEvent(e){let t={monaco:this.monaco,event:e,state:this.state,options:this.options};this.handleCompletionAcceptance(t),this.handleCompletionRejection(t);}handleCompletionAcceptance(e){return e.state.isCompletionVisible&&this.isAcceptanceKey(e.event)?(e.options.onCompletionAccepted?.(),e.state.isCompletionAccepted=true,e.state.isCompletionVisible=false,true):(e.state.isCompletionAccepted=false,false)}handleCompletionRejection(e){return this.shouldRejectCompletion(e)?(e.options.onCompletionRejected?.(),e.state.hasRejectedCurrentCompletion=true,true):false}shouldRejectCompletion(e){return e.state.isCompletionVisible&&!e.state.hasRejectedCurrentCompletion&&!e.state.isCompletionAccepted&&!this.isAcceptanceKey(e.event)}isAcceptanceKey(e){return Object.values(Le).some(t=>t(this.monaco,e))}},Pe=(o,e,t,r)=>{let n=new Q(o,t,r);return e.onKeyDown(i=>n.handleKeyEvent(i))};var D=null,_e=(o,e,t)=>{D&&D.deregister();let r=[];Ce(e,ge()),e.updateOptions({inlineSuggest:{enabled:true,mode:"subwordSmart"}});try{let n=k(e);if(!n)return v("Completion is not registered properly. State not found."),Ne();let i=fe(o,e,t);i&&r.push(i);let s=Pe(o,e,n,t);r.push(s);let l={deregister:()=>{r.forEach(p=>p.dispose()),$.clear(),Z(e),D=null;},trigger:()=>he(e)};return D=l,l}catch(n){return t.onError?t.onError(n):S(n),{deregister:()=>{r.forEach(i=>i.dispose()),Z(e),D=null;},trigger:()=>{}}}},Ne=()=>({deregister:()=>{},trigger:()=>{}});var ee=["groq","openai","anthropic","google","deepseek"],P={"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-20241022","claude-3-haiku":"claude-3-haiku-20240307","claude-3-5-haiku":"claude-3-5-haiku-20241022","o1-mini":"o1-mini","gemini-1.5-flash-8b":"gemini-1.5-flash-8b","gemini-1.5-flash":"gemini-1.5-flash","gemini-1.5-pro":"gemini-1.5-pro",v3:"deepseek-chat"},te={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-mini"],anthropic:["claude-3-5-sonnet","claude-3-haiku","claude-3-5-haiku"],google:["gemini-1.5-flash-8b","gemini-1.5-pro","gemini-1.5-flash"],deepseek:["v3"]},E={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages",google:"https://generativelanguage.googleapis.com/v1beta/models",deepseek:"https://api.deepseek.com/beta/completions"};var g=class{};var j=class extends g{createEndpoint(){return E.anthropic}createRequestBody(e,t){return {model:P[e],temperature:.1,system:t.system,messages:[{role:"user",content:t.user}],max_tokens:500}}createHeaders(e){return {"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}}parseCompletion(e){let t=e.content?.[0];return t&&"text"in t?t.text:null}};var H=class extends g{createEndpoint(){return E.deepseek}createRequestBody(e,t,r){return {model:P[e],prompt:r.textBeforeCursor,suffix:r.textAfterCursor,temperature:.1,max_tokens:500}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return typeof e.choices?.[0]?.text=="string"?e.choices[0].text:null}};var K=class extends g{createEndpoint(e,t){return `${E.google}/${P[e]}:generateContent?key=${t}`}createRequestBody(e,t){return {systemInstruction:{role:"system",parts:[{text:t.system}]},generationConfig:{temperature:.1,maxOutputTokens:500},contents:[{role:"user",parts:[{text:t.user}]}]}}createHeaders(){return {"Content-Type":"application/json"}}parseCompletion(e){return e.candidates?.[0]?.content?.parts?.[0]?.text??null}};var V=class extends g{createEndpoint(){return E.groq}createRequestBody(e,t){return {model:P[e],temperature:.1,max_tokens:500,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return e.choices?.[0]?.message.content??null}};var U=class extends g{createEndpoint(){return E.openai}createRequestBody(e,t){let r=e==="o1-mini";return {model:P[e],...!r&&{temperature:.1},max_completion_tokens:500,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}}createHeaders(e){return {"Content-Type":"application/json",Authorization:`Bearer ${e}`}}parseCompletion(e){return e.choices?.[0]?.message.content??null}};var z={openai:new U,groq:new V,anthropic:new j,google:new K,deepseek:new H},Ee=(o,e,t)=>z[t].createEndpoint(o,e),ye=(o,e,t,r)=>z[e].createRequestBody(o,t,r),Re=(o,e)=>z[e].createHeaders(o),Me=(o,e)=>z[e].parseCompletion(o);var Be=o=>!o||o.length===0?"":o.map(({path:e,content:t})=>`
|
|
17
17
|
<related_file>
|
|
18
18
|
<filePath>${e}</filePath>
|
|
19
19
|
<fileContent>
|
|
@@ -23,7 +23,7 @@ ${t}
|
|
|
23
23
|
</fileContent>
|
|
24
24
|
</related_file>`.trim()).join(`
|
|
25
25
|
|
|
26
|
-
`),
|
|
26
|
+
`),Te=o=>{let{technologies:e=[],filename:t,relatedFiles:r,language:n,textBeforeCursor:i="",textAfterCursor:s="",editorState:{completionMode:l}}=o,p=A([n,...e].filter(a=>typeof a=="string"&&!!a)),d=`
|
|
27
27
|
You are an expert code completion assistant.
|
|
28
28
|
|
|
29
29
|
**Context:**
|
|
@@ -39,8 +39,6 @@ ${Be(r)}
|
|
|
39
39
|
${i}<cursor>${s}
|
|
40
40
|
\`\`\`
|
|
41
41
|
|
|
42
|
-
${
|
|
42
|
+
${me(l)} the code at <cursor>.
|
|
43
43
|
|
|
44
|
-
Output only the raw code to be inserted at the cursor location without any additional text or comments.`;return {system:d,user:c}};var
|
|
45
|
-
|
|
46
|
-
export { oe as Copilot, Ne as registerCompletion };
|
|
44
|
+
Output only the raw code to be inserted at the cursor location without any additional text or comments.`;return {system:d,user:c}};var xe=(o,e)=>{if(!o)throw new Error("Please provide an API key.");if(!e||typeof e=="object"&&Object.keys(e).length===0)throw new Error("Please provide options.")},be=(o,e)=>{if(typeof o=="object"){if(e!==undefined)throw new Error("Provider should not be specified when using a custom model.");if(!("config"in o)||!("transformResponse"in o))throw new Error("Please ensure both config and transformResponse are provided for custom model.");return}if(!e||!ee.includes(e))throw new Error(`Provider must be specified and supported when using built-in models. Please choose from: ${A(ee)}`);if(typeof o=="string"&&!te[e].includes(o))throw new Error(`Model "${o}" is not supported by the "${e}" provider. Supported models: ${A(te[e])}`)};var oe=class{constructor(e,t){xe(e,t),this.apiKey=e,this.provider=t.provider,this.model=t.model,be(this.model,this.provider);}async complete(e){let{body:t,options:r}=e,{completionMetadata:n}=t,{headers:i={},customPrompt:s}=r??{},l=this.generatePrompt(n,s),{endpoint:p,requestBody:d,headers:c}=this.prepareRequestDetails(l,n);try{let a=await this.sendCompletionRequest(p,d,{...c,...i});return this.processCompletionResponse(a)}catch(a){return this.handleCompletionError(a)}}generatePrompt(e,t){let r=Te(e);return t?{...r,...t(e)}:r}prepareRequestDetails(e,t){if(typeof this.model=="object"&&"config"in this.model){let r=this.model.config(this.apiKey,e),n=r.endpoint,i=r.body??{},s=r.headers??{};return {endpoint:n,requestBody:i,headers:s}}else {if(!this.provider)throw new Error("Provider is required for non-custom models");let r=Ee(this.model,this.apiKey,this.provider),n=Re(this.apiKey,this.provider),i=ye(this.model,this.provider,e,t);return {endpoint:r,requestBody:i,headers:n}}}async sendCompletionRequest(e,t,r){return q.POST(e,t,{headers:r})}processCompletionResponse(e){if(typeof this.model=="object"&&"transformResponse"in this.model){let t=this.model.transformResponse(e);return "completion"in t&&ie("completion","text","Copilot.options.model.transformResponse"),{completion:t.text??t.completion??null,raw:e}}else {if(!this.provider)throw new Error("Provider is required for non-custom models");return {completion:Me(e,this.provider),raw:e}}}handleCompletionError(e){return {error:S(e).message,completion:null}}};export{oe as Copilot,_e as registerCompletion};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monacopilot",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.4",
|
|
4
4
|
"description": "AI auto-completion plugin for Monaco Editor",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.mjs",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"release-it": "^17.6.0",
|
|
39
39
|
"tsup": "^8.0.2",
|
|
40
40
|
"typescript": "^5.4.3",
|
|
41
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
41
42
|
"vitest": "^2.0.5"
|
|
42
43
|
},
|
|
43
44
|
"keywords": [
|
|
@@ -61,6 +62,5 @@
|
|
|
61
62
|
}
|
|
62
63
|
],
|
|
63
64
|
"license": "MIT",
|
|
64
|
-
"author": "Arshad Yaseen <m@arshadyaseen.com> (https://arshadyaseen.com)"
|
|
65
|
-
"dependencies": {}
|
|
65
|
+
"author": "Arshad Yaseen <m@arshadyaseen.com> (https://arshadyaseen.com)"
|
|
66
66
|
}
|