monacopilot 0.10.3 → 0.10.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 +29 -9
- package/build/index.d.mts +15 -6
- package/build/index.d.ts +15 -6
- package/build/index.js +42 -30
- package/build/index.mjs +42 -30
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
- [Filename](#filename)
|
|
22
22
|
- [Completions for Specific Technologies](#completions-for-specific-technologies)
|
|
23
23
|
- [Get Completions in Real-Time](#get-completions-in-real-time)
|
|
24
|
+
- [Max Context Lines](#max-context-lines)
|
|
24
25
|
- [Copilot Options](#copilot-options)
|
|
25
26
|
- [Changing the Provider and Model](#changing-the-provider-and-model)
|
|
26
27
|
- [Custom Model](#custom-model)
|
|
@@ -96,16 +97,19 @@ const editor = monaco.editor.create(document.getElementById('container'), {
|
|
|
96
97
|
});
|
|
97
98
|
|
|
98
99
|
registerCompletion(monaco, editor, {
|
|
100
|
+
// Examples:
|
|
101
|
+
// - '/api/complete' if you're using the Next.js (API handler) or similar frameworks.
|
|
102
|
+
// - 'https://api.example.com/complete' for a separate API server
|
|
103
|
+
// Ensure this can be accessed from the browser.
|
|
99
104
|
endpoint: 'https://api.example.com/complete',
|
|
105
|
+
// The language of the editor.
|
|
100
106
|
language: 'javascript',
|
|
107
|
+
// If you are using Groq as your provider, it's recommended to set `maxContextLines` to `60` or less.
|
|
108
|
+
// This is because Groq has low rate limits and doesn't offer pay-as-you-go pricing.
|
|
109
|
+
maxContextLines: 60,
|
|
101
110
|
});
|
|
102
111
|
```
|
|
103
112
|
|
|
104
|
-
| Parameter | Type | Description |
|
|
105
|
-
| ---------- | -------- | ----------------------------------------------------------------- |
|
|
106
|
-
| `endpoint` | `string` | The URL of the API endpoint that we created in the previous step. |
|
|
107
|
-
| `language` | `string` | The language of the editor. |
|
|
108
|
-
|
|
109
113
|
🎉 Congratulations! The AI auto-completion is now connected to the Monaco Editor. Start typing and see completions in the editor.
|
|
110
114
|
|
|
111
115
|
## Register Completion Options
|
|
@@ -175,6 +179,21 @@ registerCompletion(monaco, editor, {
|
|
|
175
179
|
|
|
176
180
|
> **Note:** If you prefer real-time completions, you can set the `trigger` option to `'onTyping'`. This may increase the number of requests made to the provider and the cost. This should not be too costly since most small models are very inexpensive.
|
|
177
181
|
|
|
182
|
+
### Max Context Lines
|
|
183
|
+
|
|
184
|
+
To manage potentially lengthy code in your editor, you can limit the number of lines included in the completion request using the `maxContextLines` option.
|
|
185
|
+
|
|
186
|
+
For example, if there's a chance that the code in your editor may exceed `500+ lines`, you don't need to provide `500 lines` to the model. This would increase costs due to the huge number of input tokens. Instead, you can set `maxContextLines` to maybe `80` or `100`, depending on how accurate you want the completions to be and how much you're willing to pay for the model.
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
registerCompletion(monaco, editor, {
|
|
190
|
+
// ...other options
|
|
191
|
+
maxContextLines: 80,
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
> **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.
|
|
196
|
+
|
|
178
197
|
## Copilot Options
|
|
179
198
|
|
|
180
199
|
### Changing the Provider and Model
|
|
@@ -315,10 +334,11 @@ The `customPrompt` function receives a `completionMetadata` object, which contai
|
|
|
315
334
|
|
|
316
335
|
The `editorState.completionMode` can be one of the following:
|
|
317
336
|
|
|
318
|
-
| Mode
|
|
319
|
-
|
|
|
320
|
-
| `
|
|
321
|
-
| `
|
|
337
|
+
| Mode | Description |
|
|
338
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
339
|
+
| `insert` | Indicates that there is a character immediately after the cursor. In this mode, the AI will generate content to be inserted at the cursor position. |
|
|
340
|
+
| `complete` | Indicates that there is a character after the cursor but not immediately. In this mode, the AI will generate content to complete the text from the cursor position. |
|
|
341
|
+
| `continue` | Indicates that there is no character after the cursor. In this mode, the AI will generate content to continue the text from the cursor position. |
|
|
322
342
|
|
|
323
343
|
For additional `completionMetadata` needs, please [open an issue](https://github.com/arshad-yaseen/monacopilot/issues/new).
|
|
324
344
|
|
package/build/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as monaco from 'monaco-editor';
|
|
1
|
+
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
2
|
|
|
3
3
|
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
4
4
|
type GroqModel = 'llama-3-70b';
|
|
@@ -105,7 +105,7 @@ type ExternalContext = {
|
|
|
105
105
|
* The content of the external file as a string.
|
|
106
106
|
*/
|
|
107
107
|
content: string;
|
|
108
|
-
}
|
|
108
|
+
};
|
|
109
109
|
interface RegisterCompletionOptions {
|
|
110
110
|
/**
|
|
111
111
|
* Language of the current model
|
|
@@ -147,7 +147,16 @@ interface RegisterCompletionOptions {
|
|
|
147
147
|
* Helps to give more relevant completions based on the full context.
|
|
148
148
|
* You can include things like the contents/codes of other files in the same workspace.
|
|
149
149
|
*/
|
|
150
|
-
externalContext?: ExternalContext;
|
|
150
|
+
externalContext?: ExternalContext[];
|
|
151
|
+
/**
|
|
152
|
+
* The maximum number of lines of code to include in the completion request.
|
|
153
|
+
* This limits the request size to the model to prevent `429 Too Many Requests` errors
|
|
154
|
+
* and reduce costs for long code.
|
|
155
|
+
*
|
|
156
|
+
* It is recommended to set `maxContextLines` to `60` or less if you are using `Groq` as your provider,
|
|
157
|
+
* since `Groq` does not implement pay-as-you-go pricing and has only low rate limits.
|
|
158
|
+
*/
|
|
159
|
+
maxContextLines?: number;
|
|
151
160
|
}
|
|
152
161
|
interface CompletionRegistration {
|
|
153
162
|
/**
|
|
@@ -192,7 +201,7 @@ interface CompletionResponse {
|
|
|
192
201
|
completion: string | null;
|
|
193
202
|
error?: string;
|
|
194
203
|
}
|
|
195
|
-
type CompletionMode = '
|
|
204
|
+
type CompletionMode = 'insert' | 'complete' | 'continue';
|
|
196
205
|
interface CompletionMetadata {
|
|
197
206
|
/**
|
|
198
207
|
* The programming language of the code.
|
|
@@ -209,7 +218,7 @@ interface CompletionMetadata {
|
|
|
209
218
|
/**
|
|
210
219
|
* Additional context from related files.
|
|
211
220
|
*/
|
|
212
|
-
externalContext: ExternalContext | undefined;
|
|
221
|
+
externalContext: ExternalContext[] | undefined;
|
|
213
222
|
/**
|
|
214
223
|
* The text that appears after the cursor.
|
|
215
224
|
*/
|
|
@@ -221,7 +230,7 @@ interface CompletionMetadata {
|
|
|
221
230
|
/**
|
|
222
231
|
* The current cursor position.
|
|
223
232
|
*/
|
|
224
|
-
cursorPosition: CursorPosition
|
|
233
|
+
cursorPosition: CursorPosition;
|
|
225
234
|
/**
|
|
226
235
|
* The current state of the editor.
|
|
227
236
|
*/
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as monaco from 'monaco-editor';
|
|
1
|
+
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
2
|
|
|
3
3
|
type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
4
4
|
type GroqModel = 'llama-3-70b';
|
|
@@ -105,7 +105,7 @@ type ExternalContext = {
|
|
|
105
105
|
* The content of the external file as a string.
|
|
106
106
|
*/
|
|
107
107
|
content: string;
|
|
108
|
-
}
|
|
108
|
+
};
|
|
109
109
|
interface RegisterCompletionOptions {
|
|
110
110
|
/**
|
|
111
111
|
* Language of the current model
|
|
@@ -147,7 +147,16 @@ interface RegisterCompletionOptions {
|
|
|
147
147
|
* Helps to give more relevant completions based on the full context.
|
|
148
148
|
* You can include things like the contents/codes of other files in the same workspace.
|
|
149
149
|
*/
|
|
150
|
-
externalContext?: ExternalContext;
|
|
150
|
+
externalContext?: ExternalContext[];
|
|
151
|
+
/**
|
|
152
|
+
* The maximum number of lines of code to include in the completion request.
|
|
153
|
+
* This limits the request size to the model to prevent `429 Too Many Requests` errors
|
|
154
|
+
* and reduce costs for long code.
|
|
155
|
+
*
|
|
156
|
+
* It is recommended to set `maxContextLines` to `60` or less if you are using `Groq` as your provider,
|
|
157
|
+
* since `Groq` does not implement pay-as-you-go pricing and has only low rate limits.
|
|
158
|
+
*/
|
|
159
|
+
maxContextLines?: number;
|
|
151
160
|
}
|
|
152
161
|
interface CompletionRegistration {
|
|
153
162
|
/**
|
|
@@ -192,7 +201,7 @@ interface CompletionResponse {
|
|
|
192
201
|
completion: string | null;
|
|
193
202
|
error?: string;
|
|
194
203
|
}
|
|
195
|
-
type CompletionMode = '
|
|
204
|
+
type CompletionMode = 'insert' | 'complete' | 'continue';
|
|
196
205
|
interface CompletionMetadata {
|
|
197
206
|
/**
|
|
198
207
|
* The programming language of the code.
|
|
@@ -209,7 +218,7 @@ interface CompletionMetadata {
|
|
|
209
218
|
/**
|
|
210
219
|
* Additional context from related files.
|
|
211
220
|
*/
|
|
212
|
-
externalContext: ExternalContext | undefined;
|
|
221
|
+
externalContext: ExternalContext[] | undefined;
|
|
213
222
|
/**
|
|
214
223
|
* The text that appears after the cursor.
|
|
215
224
|
*/
|
|
@@ -221,7 +230,7 @@ interface CompletionMetadata {
|
|
|
221
230
|
/**
|
|
222
231
|
* The current cursor position.
|
|
223
232
|
*/
|
|
224
|
-
cursorPosition: CursorPosition
|
|
233
|
+
cursorPosition: CursorPosition;
|
|
225
234
|
/**
|
|
226
235
|
* The current state of the editor.
|
|
227
236
|
*/
|
package/build/index.js
CHANGED
|
@@ -1,33 +1,45 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
"use strict";var S=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var ge=(t,e)=>{for(var o in e)S(t,o,{get:e[o],enumerable:!0})},he=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ue(e))!Ce.call(t,r)&&r!==o&&S(t,r,{get:()=>e[r],enumerable:!(n=me(e,r))||n.enumerable});return t};var fe=t=>he(S({},"__esModule",{value:!0}),t);var Se={};ge(Se,{Copilot:()=>b,registerCompletion:()=>W,registerCopilot:()=>ce});module.exports=fe(Se);var B=["groq","openai","anthropic"],Y={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},k={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},X="llama-3-70b",J="groq",z={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},M=.3;var P=class P{constructor(){}static getInstance(){return P.instance}handleError(e,o){let n=this.getErrorDetails(e),r=`\x1B[31m[${o}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};P.instance=new P;var H=P;var C=(t,e)=>H.getInstance().handleError(t,e);var q=(t,e)=>{let o=null,n=null,r=(...i)=>new Promise((s,l)=>{o&&(clearTimeout(o),n&&n("Cancelled")),n=l,o=setTimeout(()=>{s(t(...i)),n=null},e)});return r.cancel=()=>{o&&(clearTimeout(o),n&&n("Cancelled"),o=null,n=null)},r},T=t=>!t||t.length===0?"":t.length===1?t[0]:`${t.slice(0,-1).join(", ")} and ${t.slice(-1)}`;var F=(t,e)=>e.getLineContent(t.lineNumber)[t.column-1];var I=(t,e)=>e.getLineContent(t.lineNumber).slice(t.column-1),h=(t,e)=>e.getLineContent(t.lineNumber).slice(0,t.column-1),Z=(t,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:t.lineNumber,endColumn:t.column}),Q=(t,e)=>e.getValueInRange({startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())}),$=(t,e,o={})=>{if(e<=0)return"";let n=t.split(`
|
|
2
|
+
`),r=n.length;if(e>=r)return t;if(o.from==="end"){let s=n.slice(-e);return s.every(l=>l==="")?`
|
|
3
|
+
`.repeat(e):s.join(`
|
|
4
|
+
`)}let i=n.slice(0,e);return i.every(s=>s==="")?`
|
|
5
|
+
`.repeat(e):i.join(`
|
|
6
|
+
`)};var ee=async(t,e,o={})=>{let n={"Content-Type":"application/json",...o.headers},r=e==="POST"&&o.body?JSON.stringify(o.body):void 0,i=await fetch(t,{method:e,headers:n,body:r,signal:o.signal});if(!i.ok)throw new Error(`${o.error||"Network error"}: ${i.statusText}`);return i.json()},xe=(t,e)=>ee(t,"GET",e),Ee=(t,e,o)=>ee(t,"POST",{...o,body:e}),v={GET:xe,POST:Ee};var te=(t,e)=>{let o=I(t,e).trim(),n=h(t,e).trim();return t.column<=3&&(o!==""||n!=="")};var Pe=t=>t==="javascript"?"JavaScript (ESNext)":t,Te=t=>`You are an expert ${Pe(t.language)||T(t.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.`,ye=t=>{let{filename:e="/",textBeforeCursor:o="",textAfterCursor:n="",externalContext:r,editorState:i}=t,a=`
|
|
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."}[i.completionMode]}</instruction>
|
|
9
|
+
<steps>
|
|
10
|
+
<step>Analyze the provided code and any external files thoroughly.</step>
|
|
11
|
+
<step>Ensure the generated code integrates seamlessly with the existing code.</step>
|
|
12
|
+
<step>Adhere to best practices and maintain consistent coding style.</step>
|
|
13
|
+
<step>Do <strong>not</strong> include the code before the cursor in your response.</step>
|
|
14
|
+
<step>Do <strong>not</strong> wrap your completion with markdown code syntax (\`\`\`) or inline code syntax (\`).</step>
|
|
15
|
+
<step>Focus on correct syntax and language-specific conventions.</step>
|
|
16
|
+
<step>Do <strong>not</strong> add explanations, comments, or placeholders.</step>
|
|
17
|
+
<step>Return <strong>only</strong> the code required at the cursor position.</step>
|
|
18
|
+
</steps>
|
|
19
|
+
</guidelines>
|
|
20
|
+
`,p=`
|
|
21
|
+
<context>
|
|
22
|
+
<current_file path="${e}">
|
|
23
|
+
<code>
|
|
24
|
+
${o}\u2588${n}
|
|
25
|
+
</code>
|
|
26
|
+
</current_file>
|
|
27
|
+
</context>
|
|
28
|
+
`,m=r?.map(({path:c,content:d})=>`
|
|
29
|
+
<external_file path="${c}">
|
|
30
|
+
<code>
|
|
31
|
+
${d}
|
|
32
|
+
</code>
|
|
33
|
+
</external_file>
|
|
28
34
|
`).join(`
|
|
29
|
-
`)
|
|
35
|
+
`)||"";return`
|
|
36
|
+
<task>
|
|
37
|
+
${a}
|
|
38
|
+
${p}
|
|
39
|
+
${m}
|
|
40
|
+
</task>
|
|
41
|
+
`};function V(t){return{system:Te(t),user:ye(t)}}var oe={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Re={createRequestBody:(t,e)=>{let n=t==="o1-preview"||t==="o1-mini"?[{role:"user",content:e.user}]:[{role:"system",content:e.system},{role:"user",content:e.user}];return{model:U(t),temperature:M,messages:n}},createHeaders:t=>({"Content-Type":"application/json",Authorization:`Bearer ${t}`}),parseCompletion:t=>t.choices?.length?t.choices[0].message.content:null},Oe={createRequestBody:(t,e)=>({model:U(t),temperature:M,messages:[{role:"system",content:e.system},{role:"user",content:e.user}]}),createHeaders:t=>({"Content-Type":"application/json",Authorization:`Bearer ${t}`}),parseCompletion:t=>t.choices?.length?t.choices[0].message.content:null},Me={createRequestBody:(t,e)=>({model:U(t),temperature:M,system:e.system,messages:[{role:"user",content:e.user}],max_tokens:Ie(t)}),createHeaders:t=>({"Content-Type":"application/json","x-api-key":t,"anthropic-version":"2023-06-01"}),parseCompletion:t=>!t.content||typeof t.content!="string"?null:t.content},j={openai:Re,groq:Oe,anthropic:Me},ne=(t,e,o)=>j[e].createRequestBody(t,o),re=(t,e)=>j[e].createHeaders(t),ie=(t,e)=>j[e].parseCompletion(t),U=t=>Y[t],se=t=>z[t],Ie=t=>oe[t]||4096;var b=class{constructor(e,o={}){if(!e)throw new Error("Please provide an API key.");this.apiKey=e,this.provider=o.provider??J,this.model=o.model??X,this.validateInputs()}validateInputs(){if(!B.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${T(B)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!k[this.provider].includes(this.model)){let e=T(k[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${e}`)}}async complete(e){let{body:o,options:n}=e,{completionMetadata:r}=o,{headers:i={},customPrompt:s}=n??{},l=V(r),a=s?{...l,...s(r)}:l,p=se(this.provider),m,c=re(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let d=this.model.config(this.apiKey,a);p=d.endpoint??p,m=d.body??{},c={...c,...d.headers}}else m=ne(this.model,this.provider,a);c={...c,...i};try{let d=await v.POST(p,m,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(d);u={completion:f.text??f.completion}}else u={completion:ie(d,this.provider)};return u}catch(d){return{error:C(d,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var L=class t{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new t(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let o=/```[\s\S]*?```/g,n=e,r;for(;(r=o.exec(e))!==null;){let i=r[0],s=i.split(`
|
|
30
42
|
`).slice(1,-1).join(`
|
|
31
|
-
`);n=n.replace(i,
|
|
43
|
+
`);n=n.replace(i,s)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
32
44
|
|
|
33
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
45
|
+
`),this}build(){return this.formattedCompletion}};var A=class{constructor(e,o){this.cursorPos=e,this.mdl=o}shouldProvideCompletions(){return!te(this.cursorPos,this.mdl)}};var N=class N{constructor(){this.cache=[]}getCompletionCache(e,o){return this.cache.filter(n=>this.isCacheItemValid(n,e,o))}addCompletionCache(e){this.cache=[...this.cache.slice(-(N.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,o,n){let r=n.getValueInRange(e.range);return h(o,n).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,o,r)}isPositionValid(e,o,n){return e.range.startLineNumber===o.lineNumber&&o.column===e.range.startColumn||e.completion.startsWith(n)&&e.range.startLineNumber===o.lineNumber&&o.column>=e.range.startColumn-n.length&&o.column<=e.range.endColumn}};N.MAX_CACHE_SIZE=10;var _=N;var ve="application/json",G=async({filename:t,endpoint:e,language:o,technologies:n,externalContext:r,mdl:i,pos:s,maxContextLines:l})=>{try{let{completion:a}=await v.POST(e,{completionMetadata:be({filename:t,pos:s,mdl:i,language:o,technologies:n,externalContext:r,maxContextLines:l})},{headers:{"Content-Type":ve},error:"Error while fetching completion item"});return a}catch(a){return C(a,"FETCH_COMPLETION_ITEM_ERROR"),null}},be=({filename:t,pos:e,mdl:o,language:n,technologies:r,externalContext:i,maxContextLines:s})=>{let l=Le(e,o),p=!!i?.length?3:2,m=s?Math.floor(s/p):void 0,c=(x,E,D)=>{let O=x(e,o);return E?$(O,E,D):O},d=(x,E)=>!x||!E?x:x.map(({content:D,...O})=>({...O,content:$(D,E)})),u=c(Z,m,{from:"end"}),f=c(Q,m),de=d(i,m);return{filename:t,language:n,technologies:r,externalContext:de,textBeforeCursor:u,textAfterCursor:f,cursorPosition:e,editorState:{completionMode:l}}},Le=(t,e)=>{let o=F(t,e),n=I(t,e);return o?"insert":n.trim()?"complete":"continue"};function le(t,e,o){let n=e.getOffsetAt(t),r=e.getValue().slice(n),i=0,s=Math.min(o.length,r.length);for(let p=0;p<s&&o[p]===r[p];p++)i++;let l=n+i,a=e.getPositionAt(l);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:a.lineNumber,endColumn:a.column}}function ae(t){return L.create(t).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=t=>({items:t,enableForwardStability:!0});var Ae=300,_e=600,Ne={onTyping:q(G,Ae),onIdle:q(G,_e)},w=new _,we=async({mdl:t,pos:e,token:o,isCompletionAccepted:n,onShowCompletion:r,options:i})=>{let{trigger:s="onIdle",...l}=i;if(!new A(e,t).shouldProvideCompletions())return g([]);let a=w.getCompletionCache(e,t).map(p=>({insertText:p.completion,range:p.range}));if(a.length>0)return r(),g(a);if(o.isCancellationRequested||n)return g([]);try{let p=s==="onTyping"?"onTyping":"onIdle",m=Ne[p];o.onCancellationRequested(()=>{m.cancel()});let c=await m({...l,text:t.getValue(),mdl:t,pos:e});if(c){let d=ae(c),u=le(e,t,d);return w.addCompletionCache({completion:d,range:{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column},textBeforeCursorInLine:h(e,t)}),r(),g([{insertText:d,range:u}])}}catch(p){if(De(p))return g([]);C(p,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},De=t=>typeof t=="string"&&(t==="Cancelled"||t==="AbortError")||t instanceof Error&&(t.message==="Cancelled"||t.name==="AbortError"),pe=we;var y=new WeakMap,R=null,W=(t,e,o)=>{R&&R.deregister();let n=[];y.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=t.languages.registerInlineCompletionsProvider(o.language,{provideInlineCompletions:(l,a,p,m)=>{let c=y.get(e);if(c)return pe({mdl:l,pos:a,token:m,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:o})},freeInlineCompletions:()=>{}});n.push(r);let i=e.onKeyDown(l=>{let a=y.get(e);if(!a)return;let p=l.keyCode===t.KeyCode.Tab||l.keyCode===t.KeyCode.RightArrow&&l.metaKey;a.isCompletionVisible&&p?(a.isCompletionAccepted=!0,a.isCompletionVisible=!1):a.isCompletionAccepted=!1});n.push(i),e.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});let s={deregister:()=>{n.forEach(l=>l.dispose()),w.clearCompletionCache(),y.delete(e),R=null}};return R=s,s}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),y.delete(e),R=null}}}},ce=W;0&&(module.exports={Copilot,registerCompletion,registerCopilot});
|
package/build/index.mjs
CHANGED
|
@@ -1,33 +1,45 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
var D=["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"},S={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},W="llama-3-70b",Y="groq",X={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},M=.3;var P=class P{constructor(){}static getInstance(){return P.instance}handleError(e,o){let n=this.getErrorDetails(e),r=`\x1B[31m[${o}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};P.instance=new P;var B=P;var C=(t,e)=>B.getInstance().handleError(t,e);var k=(t,e)=>{let o=null,n=null,r=(...i)=>new Promise((s,l)=>{o&&(clearTimeout(o),n&&n("Cancelled")),n=l,o=setTimeout(()=>{s(t(...i)),n=null},e)});return r.cancel=()=>{o&&(clearTimeout(o),n&&n("Cancelled"),o=null,n=null)},r},T=t=>!t||t.length===0?"":t.length===1?t[0]:`${t.slice(0,-1).join(", ")} and ${t.slice(-1)}`;var H=(t,e)=>e.getLineContent(t.lineNumber)[t.column-1];var I=(t,e)=>e.getLineContent(t.lineNumber).slice(t.column-1),h=(t,e)=>e.getLineContent(t.lineNumber).slice(0,t.column-1),J=(t,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:t.lineNumber,endColumn:t.column}),z=(t,e)=>e.getValueInRange({startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())}),q=(t,e,o={})=>{if(e<=0)return"";let n=t.split(`
|
|
2
|
+
`),r=n.length;if(e>=r)return t;if(o.from==="end"){let s=n.slice(-e);return s.every(l=>l==="")?`
|
|
3
|
+
`.repeat(e):s.join(`
|
|
4
|
+
`)}let i=n.slice(0,e);return i.every(s=>s==="")?`
|
|
5
|
+
`.repeat(e):i.join(`
|
|
6
|
+
`)};var Z=async(t,e,o={})=>{let n={"Content-Type":"application/json",...o.headers},r=e==="POST"&&o.body?JSON.stringify(o.body):void 0,i=await fetch(t,{method:e,headers:n,body:r,signal:o.signal});if(!i.ok)throw new Error(`${o.error||"Network error"}: ${i.statusText}`);return i.json()},ce=(t,e)=>Z(t,"GET",e),de=(t,e,o)=>Z(t,"POST",{...o,body:e}),v={GET:ce,POST:de};var Q=(t,e)=>{let o=I(t,e).trim(),n=h(t,e).trim();return t.column<=3&&(o!==""||n!=="")};var me=t=>t==="javascript"?"JavaScript (ESNext)":t,ue=t=>`You are an expert ${me(t.language)||T(t.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.`,Ce=t=>{let{filename:e="/",textBeforeCursor:o="",textAfterCursor:n="",externalContext:r,editorState:i}=t,a=`
|
|
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."}[i.completionMode]}</instruction>
|
|
9
|
+
<steps>
|
|
10
|
+
<step>Analyze the provided code and any external files thoroughly.</step>
|
|
11
|
+
<step>Ensure the generated code integrates seamlessly with the existing code.</step>
|
|
12
|
+
<step>Adhere to best practices and maintain consistent coding style.</step>
|
|
13
|
+
<step>Do <strong>not</strong> include the code before the cursor in your response.</step>
|
|
14
|
+
<step>Do <strong>not</strong> wrap your completion with markdown code syntax (\`\`\`) or inline code syntax (\`).</step>
|
|
15
|
+
<step>Focus on correct syntax and language-specific conventions.</step>
|
|
16
|
+
<step>Do <strong>not</strong> add explanations, comments, or placeholders.</step>
|
|
17
|
+
<step>Return <strong>only</strong> the code required at the cursor position.</step>
|
|
18
|
+
</steps>
|
|
19
|
+
</guidelines>
|
|
20
|
+
`,p=`
|
|
21
|
+
<context>
|
|
22
|
+
<current_file path="${e}">
|
|
23
|
+
<code>
|
|
24
|
+
${o}\u2588${n}
|
|
25
|
+
</code>
|
|
26
|
+
</current_file>
|
|
27
|
+
</context>
|
|
28
|
+
`,m=r?.map(({path:c,content:d})=>`
|
|
29
|
+
<external_file path="${c}">
|
|
30
|
+
<code>
|
|
31
|
+
${d}
|
|
32
|
+
</code>
|
|
33
|
+
</external_file>
|
|
28
34
|
`).join(`
|
|
29
|
-
`)
|
|
35
|
+
`)||"";return`
|
|
36
|
+
<task>
|
|
37
|
+
${a}
|
|
38
|
+
${p}
|
|
39
|
+
${m}
|
|
40
|
+
</task>
|
|
41
|
+
`};function F(t){return{system:ue(t),user:Ce(t)}}var ee={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var ge={createRequestBody:(t,e)=>{let n=t==="o1-preview"||t==="o1-mini"?[{role:"user",content:e.user}]:[{role:"system",content:e.system},{role:"user",content:e.user}];return{model:V(t),temperature:M,messages:n}},createHeaders:t=>({"Content-Type":"application/json",Authorization:`Bearer ${t}`}),parseCompletion:t=>t.choices?.length?t.choices[0].message.content:null},he={createRequestBody:(t,e)=>({model:V(t),temperature:M,messages:[{role:"system",content:e.system},{role:"user",content:e.user}]}),createHeaders:t=>({"Content-Type":"application/json",Authorization:`Bearer ${t}`}),parseCompletion:t=>t.choices?.length?t.choices[0].message.content:null},fe={createRequestBody:(t,e)=>({model:V(t),temperature:M,system:e.system,messages:[{role:"user",content:e.user}],max_tokens:xe(t)}),createHeaders:t=>({"Content-Type":"application/json","x-api-key":t,"anthropic-version":"2023-06-01"}),parseCompletion:t=>!t.content||typeof t.content!="string"?null:t.content},$={openai:ge,groq:he,anthropic:fe},te=(t,e,o)=>$[e].createRequestBody(t,o),oe=(t,e)=>$[e].createHeaders(t),ne=(t,e)=>$[e].parseCompletion(t),V=t=>G[t],re=t=>X[t],xe=t=>ee[t]||4096;var j=class{constructor(e,o={}){if(!e)throw new Error("Please provide an API key.");this.apiKey=e,this.provider=o.provider??Y,this.model=o.model??W,this.validateInputs()}validateInputs(){if(!D.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${T(D)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!S[this.provider].includes(this.model)){let e=T(S[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${e}`)}}async complete(e){let{body:o,options:n}=e,{completionMetadata:r}=o,{headers:i={},customPrompt:s}=n??{},l=F(r),a=s?{...l,...s(r)}:l,p=re(this.provider),m,c=oe(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let d=this.model.config(this.apiKey,a);p=d.endpoint??p,m=d.body??{},c={...c,...d.headers}}else m=te(this.model,this.provider,a);c={...c,...i};try{let d=await v.POST(p,m,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(d);u={completion:f.text??f.completion}}else u={completion:ne(d,this.provider)};return u}catch(d){return{error:C(d,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var b=class t{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new t(e)}setCompletion(e){return this.formattedCompletion=e,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(e){let o=/```[\s\S]*?```/g,n=e,r;for(;(r=o.exec(e))!==null;){let i=r[0],s=i.split(`
|
|
30
42
|
`).slice(1,-1).join(`
|
|
31
|
-
`);n=n.replace(i,
|
|
43
|
+
`);n=n.replace(i,s)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
32
44
|
|
|
33
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
45
|
+
`),this}build(){return this.formattedCompletion}};var L=class{constructor(e,o){this.cursorPos=e,this.mdl=o}shouldProvideCompletions(){return!Q(this.cursorPos,this.mdl)}};var _=class _{constructor(){this.cache=[]}getCompletionCache(e,o){return this.cache.filter(n=>this.isCacheItemValid(n,e,o))}addCompletionCache(e){this.cache=[...this.cache.slice(-(_.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,o,n){let r=n.getValueInRange(e.range);return h(o,n).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,o,r)}isPositionValid(e,o,n){return e.range.startLineNumber===o.lineNumber&&o.column===e.range.startColumn||e.completion.startsWith(n)&&e.range.startLineNumber===o.lineNumber&&o.column>=e.range.startColumn-n.length&&o.column<=e.range.endColumn}};_.MAX_CACHE_SIZE=10;var A=_;var Ee="application/json",K=async({filename:t,endpoint:e,language:o,technologies:n,externalContext:r,mdl:i,pos:s,maxContextLines:l})=>{try{let{completion:a}=await v.POST(e,{completionMetadata:Pe({filename:t,pos:s,mdl:i,language:o,technologies:n,externalContext:r,maxContextLines:l})},{headers:{"Content-Type":Ee},error:"Error while fetching completion item"});return a}catch(a){return C(a,"FETCH_COMPLETION_ITEM_ERROR"),null}},Pe=({filename:t,pos:e,mdl:o,language:n,technologies:r,externalContext:i,maxContextLines:s})=>{let l=Te(e,o),p=!!i?.length?3:2,m=s?Math.floor(s/p):void 0,c=(x,E,w)=>{let O=x(e,o);return E?q(O,E,w):O},d=(x,E)=>!x||!E?x:x.map(({content:w,...O})=>({...O,content:q(w,E)})),u=c(J,m,{from:"end"}),f=c(z,m),pe=d(i,m);return{filename:t,language:n,technologies:r,externalContext:pe,textBeforeCursor:u,textAfterCursor:f,cursorPosition:e,editorState:{completionMode:l}}},Te=(t,e)=>{let o=H(t,e),n=I(t,e);return o?"insert":n.trim()?"complete":"continue"};function ie(t,e,o){let n=e.getOffsetAt(t),r=e.getValue().slice(n),i=0,s=Math.min(o.length,r.length);for(let p=0;p<s&&o[p]===r[p];p++)i++;let l=n+i,a=e.getPositionAt(l);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:a.lineNumber,endColumn:a.column}}function se(t){return b.create(t).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=t=>({items:t,enableForwardStability:!0});var ye=300,Re=600,Oe={onTyping:k(K,ye),onIdle:k(K,Re)},N=new A,Me=async({mdl:t,pos:e,token:o,isCompletionAccepted:n,onShowCompletion:r,options:i})=>{let{trigger:s="onIdle",...l}=i;if(!new L(e,t).shouldProvideCompletions())return g([]);let a=N.getCompletionCache(e,t).map(p=>({insertText:p.completion,range:p.range}));if(a.length>0)return r(),g(a);if(o.isCancellationRequested||n)return g([]);try{let p=s==="onTyping"?"onTyping":"onIdle",m=Oe[p];o.onCancellationRequested(()=>{m.cancel()});let c=await m({...l,text:t.getValue(),mdl:t,pos:e});if(c){let d=se(c),u=ie(e,t,d);return N.addCompletionCache({completion:d,range:{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column},textBeforeCursorInLine:h(e,t)}),r(),g([{insertText:d,range:u}])}}catch(p){if(Ie(p))return g([]);C(p,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},Ie=t=>typeof t=="string"&&(t==="Cancelled"||t==="AbortError")||t instanceof Error&&(t.message==="Cancelled"||t.name==="AbortError"),le=Me;var y=new WeakMap,R=null,ae=(t,e,o)=>{R&&R.deregister();let n=[];y.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=t.languages.registerInlineCompletionsProvider(o.language,{provideInlineCompletions:(l,a,p,m)=>{let c=y.get(e);if(c)return le({mdl:l,pos:a,token:m,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:o})},freeInlineCompletions:()=>{}});n.push(r);let i=e.onKeyDown(l=>{let a=y.get(e);if(!a)return;let p=l.keyCode===t.KeyCode.Tab||l.keyCode===t.KeyCode.RightArrow&&l.metaKey;a.isCompletionVisible&&p?(a.isCompletionAccepted=!0,a.isCompletionVisible=!1):a.isCompletionAccepted=!1});n.push(i),e.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});let s={deregister:()=>{n.forEach(l=>l.dispose()),N.clearCompletionCache(),y.delete(e),R=null}};return R=s,s}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),y.delete(e),R=null}}}},ve=ae;export{j as Copilot,ae as registerCompletion,ve as registerCopilot};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monacopilot",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.4",
|
|
4
4
|
"description": "AI auto-completion plugin for Monaco Editor",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.mjs",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@typescript-eslint/eslint-plugin": "^7.3.1",
|
|
27
27
|
"eslint": "^8.57.0",
|
|
28
28
|
"groq-sdk": "^0.3.2",
|
|
29
|
-
"monaco-editor": "^0.
|
|
29
|
+
"monaco-editor": "^0.52.0",
|
|
30
30
|
"openai": "^4.60.1",
|
|
31
31
|
"prettier": "^3.2.5",
|
|
32
32
|
"release-it": "^17.2.1",
|