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 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 | Description |
319
- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
320
- | `fill-in-the-middle` | Indicates that the cursor is positioned within the existing text. In this mode, the AI will generate content to be inserted at the cursor position. |
321
- | `completion` | Indicates that the cursor is at the end of the existing text. In this mode, the AI will generate content to continue or complete the text from the cursor position. |
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 = 'fill-in-the-middle' | 'completion';
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 | undefined;
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 = 'fill-in-the-middle' | 'completion';
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 | undefined;
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 w=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var he=(e,o)=>{for(var t in o)w(e,t,{get:o[t],enumerable:!0})},fe=(e,o,t,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of Ce(o))!ge.call(e,r)&&r!==t&&w(e,r,{get:()=>o[r],enumerable:!(n=ue(o,r))||n.enumerable});return e};var Pe=e=>fe(w({},"__esModule",{value:!0}),e);var Be={};he(Be,{Copilot:()=>I,registerCompletion:()=>j,registerCopilot:()=>me});module.exports=Pe(Be);var N=["groq","openai","anthropic"],G={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},D={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},K="llama-3-70b",Y="groq",X={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},y=.3;var z=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var P=class P{constructor(){}static getInstance(){return P.instance}handleError(o,t){let n=this.getErrorDetails(o),r=`\x1B[31m[${t}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};P.instance=new P;var S=P;var C=(e,o)=>S.getInstance().handleError(e,o);var B=(e,o)=>{let t=null,n=null,r=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),n&&n("Cancelled")),n=s,t=setTimeout(()=>{a(e(...i)),n=null},o)});return r.cancel=()=>{t&&(clearTimeout(t),n&&n("Cancelled"),t=null,n=null)},r},E=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var R=(e,o)=>o.getLineContent(e.lineNumber)[e.column-1],J=(e,o)=>o.getLineContent(e.lineNumber).slice(e.column-1),h=(e,o)=>o.getLineContent(e.lineNumber).slice(0,e.column-1),Z=e=>{let o=e.split(`
2
- `);return o[o.length-1].length+1};var k=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),H=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var Q=async(e,o,t={})=>{let n={"Content-Type":"application/json",...t.headers},r=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:n,body:r,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},Ee=(e,o)=>Q(e,"GET",o),Te=(e,o,t)=>Q(e,"POST",{...t,body:o}),M={GET:Ee,POST:Te};var ee=(e,o)=>{let t=R(e,o);return!!t&&!z.has(t)},oe=(e,o)=>{let t=J(e,o).trim(),n=h(e,o).trim();return e.column<=3&&(t!==""||n!=="")};var O="<<CURSOR>>",te=e=>e==="javascript"?"latest JavaScript":e,ne=e=>{switch(e){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},xe=e=>{let o=te(e.language),t=ne(e.editorState.completionMode);return`You are an AI coding assistant with expertise in${o?` ${o}`:""} programming, specializing in ${t}. Your goal is to provide accurate, efficient, and context-aware code completions that align with the existing code and the developer's intent. Provide code that is syntactically correct, follows best practices, and integrates seamlessly with the provided code snippet.`},ye=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${E(e)}`:"",n=te(o);return`The code is written${n?` in ${n}`:""}${t}.`},Re=e=>{let{filename:o,language:t,technologies:n,editorState:{completionMode:r},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=ne(r),d=o?`the file named "${o}"`:"a larger project",l=`Please assist with ${p} for the following code snippet, which is part of ${d}.
3
-
4
- `;return l+=ye(n,t),l+=`
5
-
6
- Please follow these guidelines when generating the completion:
7
- - The cursor position is indicated by '${O}' in the code snippet.
8
- - Begin your completion exactly at the cursor position.
9
- - Do not duplicate any code that appears before or after the cursor in the provided snippet.
10
- - Ensure that the completed code is syntactically correct and logically consistent with the surrounding code.
11
- - Maintain the coding style and conventions used in the existing code.
12
- - Optimize the code for readability and performance where applicable.
13
- - Do not include any additional explanations or comments in your output.
14
- - Output only the code completion, without wrapping it in markdown code syntax (e.g., no triple backticks).`,r==="fill-in-the-middle"?l+=`
15
- - Since you are filling in the middle, replace '${O}' entirely with your completion.`:r==="completion"&&(l+=`
16
- - Since you are completing the code, provide a logical continuation starting from '${O}'.`),l+=`
17
-
18
- Here's the code snippet for completion:
19
-
20
- <code>
21
- ${i}${O}${a}
22
- </code>`,s&&s.length>0&&(l+=`
23
-
24
- Additional context from related files:
25
-
26
- `,l+=s.map(c=>`// Path: ${c.path}
27
- ${c.content}
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
- `)),l.endsWith(".")?l:`${l}.`};function q(e){return{system:xe(e),user:Re(e)}}var re={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Me={createRequestBody:(e,o)=>{let n=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:o.user}]:[{role:"system",content:o.system},{role:"user",content:o.user}];return{model:F(e),temperature:y,messages:n}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Oe={createRequestBody:(e,o)=>({model:F(e),temperature:y,messages:[{role:"system",content:o.system},{role:"user",content:o.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Ie={createRequestBody:(e,o)=>({model:F(e),temperature:y,system:o.system,messages:[{role:"user",content:o.user}],max_tokens:ve(e)}),createHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),parseCompletion:e=>!e.content||typeof e.content!="string"?null:e.content},$={openai:Me,groq:Oe,anthropic:Ie},ie=(e,o,t)=>$[o].createRequestBody(e,t),se=(e,o)=>$[o].createHeaders(e),le=(e,o)=>$[o].parseCompletion(e),F=e=>G[e],ae=e=>X[e],ve=e=>re[e]||4096;var I=class{constructor(o,t={}){if(!o)throw new Error("Please provide an API key.");this.apiKey=o,this.provider=t.provider??Y,this.model=t.model??K,this.validateInputs()}validateInputs(){if(!N.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${E(N)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!D[this.provider].includes(this.model)){let o=E(D[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${o}`)}}async complete(o){let{body:t,options:n}=o,{completionMetadata:r}=t,{headers:i={},customPrompt:a}=n??{},s=q(r),p=a?{...s,...a(r)}:s,d=ae(this.provider),l,c=se(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let m=this.model.config(this.apiKey,p);d=m.endpoint??d,l=m.body??{},c={...c,...m.headers}}else l=ie(this.model,this.provider,p);c={...c,...i};try{let m=await M.POST(d,l,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(m);u={completion:f.text??f.completion}}else u={completion:le(m,this.provider)};return u}catch(m){return{error:C(m,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var v=class e{constructor(o){this.formattedCompletion="";this.formattedCompletion=o}static create(o){return new e(o)}setCompletion(o){return this.formattedCompletion=o,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(o){let t=/```[\s\S]*?```/g,n=o,r;for(;(r=t.exec(o))!==null;){let i=r[0],a=i.split(`
35
+ `)||"";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,a)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
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 b=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!ee(this.cursorPosition,this.model)&&!oe(this.cursorPosition,this.model)}};var A=class A{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(n=>this.isCacheItemValid(n,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(A.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,n){let r=n.getValueInRange(o.range);return h(t,n).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,r)}isPositionValid(o,t,n){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(n)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-n.length&&t.column<=o.range.endColumn}};A.MAX_CACHE_SIZE=10;var L=A;var be="application/json",V=async({filename:e,endpoint:o,language:t,technologies:n,externalContext:r,model:i,position:a})=>{try{let{completion:s}=await M.POST(o,{completionMetadata:Le({filename:e,position:a,model:i,language:t,technologies:n,externalContext:r})},{headers:{"Content-Type":be},error:"Error while fetching completion item"});return s}catch(s){return C(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Le=({filename:e,position:o,model:t,language:n,technologies:r,externalContext:i})=>{let a=Ae(o,t),s=k(o,t),p=H(o,t);return{filename:e,language:n,technologies:r,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},Ae=(e,o)=>{let t=k(e,o),n=H(e,o);return t&&n?"fill-in-the-middle":"completion"};var pe=(e,o,t,n)=>{let r=(e.match(/\n/g)||[]).length,i=Z(e),a=R(t,n);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+r,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&r===0?t.column+(i-1):i:t.column}};function ce(e){return v.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=e=>({items:e,enableForwardStability:!0});var _e=300,we=600,Ne={onTyping:B(V,_e),onIdle:B(V,we)},_=new L,De=async({monaco:e,model:o,position:t,token:n,isCompletionAccepted:r,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new b(t,o).shouldProvideCompletions())return g([]);let d=_.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(d.length>0)return i(),g(d);if(n.isCancellationRequested||r)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=Ne[l];n.onCancellationRequested(()=>{c.cancel()});let m=await c({...p,text:o.getValue(),model:o,position:t});if(m){let u=ce(m),f=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),W=pe(u,f,t,o);return _.addCompletionCache({completion:u,range:W,textBeforeCursorInLine:h(t,o)}),i(),g([{insertText:u,range:W}])}}catch(l){if(Se(l))return g([]);C(l,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},Se=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),de=De;var T=new WeakMap,x=null,j=(e,o,t)=>{x&&x.deregister();let n=[];T.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,d,l)=>{let c=T.get(o);if(c)return de({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});n.push(r);let i=o.onKeyDown(s=>{let p=T.get(o);if(!p)return;let d=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&d?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});n.push(i);let a={deregister:()=>{n.forEach(s=>s.dispose()),_.clearCompletionCache(),T.delete(o),x=null}};return x=a,a}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),T.delete(o),x=null}}}},me=j;0&&(module.exports={Copilot,registerCompletion,registerCopilot});
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 _=["groq","openai","anthropic"],j={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},w={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},W="llama-3-70b",G="groq",K={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},y=.3;var Y=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var P=class P{constructor(){}static getInstance(){return P.instance}handleError(o,t){let n=this.getErrorDetails(o),r=`\x1B[31m[${t}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(o){return o instanceof Error?{message:o.message,name:o.name,stack:o.stack,context:o.context}:{message:String(o),name:"UnknownError"}}};P.instance=new P;var N=P;var C=(e,o)=>N.getInstance().handleError(e,o);var D=(e,o)=>{let t=null,n=null,r=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),n&&n("Cancelled")),n=s,t=setTimeout(()=>{a(e(...i)),n=null},o)});return r.cancel=()=>{t&&(clearTimeout(t),n&&n("Cancelled"),t=null,n=null)},r},E=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var R=(e,o)=>o.getLineContent(e.lineNumber)[e.column-1],X=(e,o)=>o.getLineContent(e.lineNumber).slice(e.column-1),h=(e,o)=>o.getLineContent(e.lineNumber).slice(0,e.column-1),z=e=>{let o=e.split(`
2
- `);return o[o.length-1].length+1};var S=(e,o)=>o.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),B=(e,o)=>o.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:o.getLineCount(),endColumn:o.getLineMaxColumn(o.getLineCount())});var J=async(e,o,t={})=>{let n={"Content-Type":"application/json",...t.headers},r=o==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(e,{method:o,headers:n,body:r,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},de=(e,o)=>J(e,"GET",o),me=(e,o,t)=>J(e,"POST",{...t,body:o}),M={GET:de,POST:me};var Z=(e,o)=>{let t=R(e,o);return!!t&&!Y.has(t)},Q=(e,o)=>{let t=X(e,o).trim(),n=h(e,o).trim();return e.column<=3&&(t!==""||n!=="")};var O="<<CURSOR>>",ee=e=>e==="javascript"?"latest JavaScript":e,oe=e=>{switch(e){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},ue=e=>{let o=ee(e.language),t=oe(e.editorState.completionMode);return`You are an AI coding assistant with expertise in${o?` ${o}`:""} programming, specializing in ${t}. Your goal is to provide accurate, efficient, and context-aware code completions that align with the existing code and the developer's intent. Provide code that is syntactically correct, follows best practices, and integrates seamlessly with the provided code snippet.`},Ce=(e,o)=>{if(!e?.length&&!o)return"";let t=e?` using ${E(e)}`:"",n=ee(o);return`The code is written${n?` in ${n}`:""}${t}.`},ge=e=>{let{filename:o,language:t,technologies:n,editorState:{completionMode:r},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=e,p=oe(r),d=o?`the file named "${o}"`:"a larger project",l=`Please assist with ${p} for the following code snippet, which is part of ${d}.
3
-
4
- `;return l+=Ce(n,t),l+=`
5
-
6
- Please follow these guidelines when generating the completion:
7
- - The cursor position is indicated by '${O}' in the code snippet.
8
- - Begin your completion exactly at the cursor position.
9
- - Do not duplicate any code that appears before or after the cursor in the provided snippet.
10
- - Ensure that the completed code is syntactically correct and logically consistent with the surrounding code.
11
- - Maintain the coding style and conventions used in the existing code.
12
- - Optimize the code for readability and performance where applicable.
13
- - Do not include any additional explanations or comments in your output.
14
- - Output only the code completion, without wrapping it in markdown code syntax (e.g., no triple backticks).`,r==="fill-in-the-middle"?l+=`
15
- - Since you are filling in the middle, replace '${O}' entirely with your completion.`:r==="completion"&&(l+=`
16
- - Since you are completing the code, provide a logical continuation starting from '${O}'.`),l+=`
17
-
18
- Here's the code snippet for completion:
19
-
20
- <code>
21
- ${i}${O}${a}
22
- </code>`,s&&s.length>0&&(l+=`
23
-
24
- Additional context from related files:
25
-
26
- `,l+=s.map(c=>`// Path: ${c.path}
27
- ${c.content}
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
- `)),l.endsWith(".")?l:`${l}.`};function k(e){return{system:ue(e),user:ge(e)}}var te={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var he={createRequestBody:(e,o)=>{let n=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:o.user}]:[{role:"system",content:o.system},{role:"user",content:o.user}];return{model:q(e),temperature:y,messages:n}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},fe={createRequestBody:(e,o)=>({model:q(e),temperature:y,messages:[{role:"system",content:o.system},{role:"user",content:o.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Pe={createRequestBody:(e,o)=>({model:q(e),temperature:y,system:o.system,messages:[{role:"user",content:o.user}],max_tokens:Ee(e)}),createHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),parseCompletion:e=>!e.content||typeof e.content!="string"?null:e.content},H={openai:he,groq:fe,anthropic:Pe},ne=(e,o,t)=>H[o].createRequestBody(e,t),re=(e,o)=>H[o].createHeaders(e),ie=(e,o)=>H[o].parseCompletion(e),q=e=>j[e],se=e=>K[e],Ee=e=>te[e]||4096;var $=class{constructor(o,t={}){if(!o)throw new Error("Please provide an API key.");this.apiKey=o,this.provider=t.provider??G,this.model=t.model??W,this.validateInputs()}validateInputs(){if(!_.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${E(_)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!w[this.provider].includes(this.model)){let o=E(w[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${o}`)}}async complete(o){let{body:t,options:n}=o,{completionMetadata:r}=t,{headers:i={},customPrompt:a}=n??{},s=k(r),p=a?{...s,...a(r)}:s,d=se(this.provider),l,c=re(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let m=this.model.config(this.apiKey,p);d=m.endpoint??d,l=m.body??{},c={...c,...m.headers}}else l=ne(this.model,this.provider,p);c={...c,...i};try{let m=await M.POST(d,l,{headers:c}),u;if(typeof this.model=="object"&&"transformResponse"in this.model){let f=this.model.transformResponse(m);u={completion:f.text??f.completion}}else u={completion:ie(m,this.provider)};return u}catch(m){return{error:C(m,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var I=class e{constructor(o){this.formattedCompletion="";this.formattedCompletion=o}static create(o){return new e(o)}setCompletion(o){return this.formattedCompletion=o,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(o){let t=/```[\s\S]*?```/g,n=o,r;for(;(r=t.exec(o))!==null;){let i=r[0],a=i.split(`
35
+ `)||"";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,a)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
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 v=class{constructor(o,t){this.cursorPosition=o,this.model=t}shouldProvideCompletions(){return!Z(this.cursorPosition,this.model)&&!Q(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(o,t){return this.cache.filter(n=>this.isCacheItemValid(n,o,t))}addCompletionCache(o){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),o]}clearCompletionCache(){this.cache=[]}isCacheItemValid(o,t,n){let r=n.getValueInRange(o.range);return h(t,n).startsWith(o.textBeforeCursorInLine)&&this.isPositionValid(o,t,r)}isPositionValid(o,t,n){return o.range.startLineNumber===t.lineNumber&&t.column===o.range.startColumn||o.completion.startsWith(n)&&o.range.startLineNumber===t.lineNumber&&t.column>=o.range.startColumn-n.length&&t.column<=o.range.endColumn}};L.MAX_CACHE_SIZE=10;var b=L;var Te="application/json",U=async({filename:e,endpoint:o,language:t,technologies:n,externalContext:r,model:i,position:a})=>{try{let{completion:s}=await M.POST(o,{completionMetadata:xe({filename:e,position:a,model:i,language:t,technologies:n,externalContext:r})},{headers:{"Content-Type":Te},error:"Error while fetching completion item"});return s}catch(s){return C(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},xe=({filename:e,position:o,model:t,language:n,technologies:r,externalContext:i})=>{let a=ye(o,t),s=S(o,t),p=B(o,t);return{filename:e,language:n,technologies:r,externalContext:i,textBeforeCursor:s,textAfterCursor:p,cursorPosition:o,editorState:{completionMode:a}}},ye=(e,o)=>{let t=S(e,o),n=B(e,o);return t&&n?"fill-in-the-middle":"completion"};var le=(e,o,t,n)=>{let r=(e.match(/\n/g)||[]).length,i=z(e),a=R(t,n);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+r,endColumn:e.includes(a)?t.lineNumber===o.startLineNumber&&r===0?t.column+(i-1):i:t.column}};function ae(e){return I.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var g=e=>({items:e,enableForwardStability:!0});var Re=300,Me=600,Oe={onTyping:D(U,Re),onIdle:D(U,Me)},A=new b,Ie=async({monaco:e,model:o,position:t,token:n,isCompletionAccepted:r,onShowCompletion:i,options:a})=>{let{trigger:s="onIdle",...p}=a;if(!new v(t,o).shouldProvideCompletions())return g([]);let d=A.getCompletionCache(t,o).map(l=>({insertText:l.completion,range:l.range}));if(d.length>0)return i(),g(d);if(n.isCancellationRequested||r)return g([]);try{let l=s==="onTyping"?"onTyping":"onIdle",c=Oe[l];n.onCancellationRequested(()=>{c.cancel()});let m=await c({...p,text:o.getValue(),model:o,position:t});if(m){let u=ae(m),f=new e.Range(t.lineNumber,t.column,t.lineNumber,t.column),V=le(u,f,t,o);return A.addCompletionCache({completion:u,range:V,textBeforeCursorInLine:h(t,o)}),i(),g([{insertText:u,range:V}])}}catch(l){if(ve(l))return g([]);C(l,"FETCH_COMPLETION_ITEM_ERROR")}return g([])},ve=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),pe=Ie;var T=new WeakMap,x=null,ce=(e,o,t)=>{x&&x.deregister();let n=[];T.set(o,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let r=e.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,p,d,l)=>{let c=T.get(o);if(c)return pe({monaco:e,model:s,position:p,token:l,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});n.push(r);let i=o.onKeyDown(s=>{let p=T.get(o);if(!p)return;let d=s.keyCode===e.KeyCode.Tab||s.keyCode===e.KeyCode.RightArrow&&s.metaKey;p.isCompletionVisible&&d?(p.isCompletionAccepted=!0,p.isCompletionVisible=!1):p.isCompletionAccepted=!1});n.push(i);let a={deregister:()=>{n.forEach(s=>s.dispose()),A.clearCompletionCache(),T.delete(o),x=null}};return x=a,a}catch(r){return C(r,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(i=>i.dispose()),T.delete(o),x=null}}}},be=ce;export{$ as Copilot,ce as registerCompletion,be as registerCopilot};
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",
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.50.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",