monacopilot 0.10.5 → 0.10.6
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 +54 -21
- package/build/index.d.mts +13 -8
- package/build/index.d.ts +13 -8
- package/build/index.js +11 -11
- package/build/index.mjs +11 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
- [API Handler](#api-handler)
|
|
18
18
|
- [Register Completion with the Monaco Editor](#register-completion-with-the-monaco-editor)
|
|
19
19
|
- [Register Completion Options](#register-completion-options)
|
|
20
|
+
- [Get Completions in Real-Time](#get-completions-in-real-time)
|
|
21
|
+
- [Manually Trigger Completions](#manually-trigger-completions)
|
|
20
22
|
- [External Context](#external-context)
|
|
21
23
|
- [Filename](#filename)
|
|
22
24
|
- [Completions for Specific Technologies](#completions-for-specific-technologies)
|
|
23
|
-
- [Get Completions in Real-Time](#get-completions-in-real-time)
|
|
24
25
|
- [Max Context Lines](#max-context-lines)
|
|
25
26
|
- [Copilot Options](#copilot-options)
|
|
26
27
|
- [Changing the Provider and Model](#changing-the-provider-and-model)
|
|
@@ -114,6 +115,58 @@ registerCompletion(monaco, editor, {
|
|
|
114
115
|
|
|
115
116
|
## Register Completion Options
|
|
116
117
|
|
|
118
|
+
### Get Completions in Real-Time
|
|
119
|
+
|
|
120
|
+
The `trigger` option determines when the completion service provides code completions. You can choose between receiving suggestions/completions in real-time as you type or after a brief pause.
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
registerCompletion(monaco, editor, {
|
|
124
|
+
// ...other options
|
|
125
|
+
trigger: 'onTyping',
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
| Trigger | Description | Notes |
|
|
130
|
+
| -------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
131
|
+
| `'onIdle'` (default) | The completion service provides completions after a brief pause in typing. | This approach is less resource-intensive, as it only initiates a request when the editor is idle. However, compared to `onTyping`, it may result in a slightly reduced experience with completions. |
|
|
132
|
+
| `'onTyping'` | The completion service provides completions in real-time as you type. | This approach is best suited for models with low response latency, such as Groq models. Please note that this trigger mode initiates additional background requests to deliver real-time suggestions. Technically, this method is called predictive caching. |
|
|
133
|
+
|
|
134
|
+
[OnTyping Demo](https://github.com/user-attachments/assets/22c2ce44-334c-4963-b853-01b890b8e39f)
|
|
135
|
+
|
|
136
|
+
> **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.
|
|
137
|
+
|
|
138
|
+
### Manually Trigger Completions
|
|
139
|
+
|
|
140
|
+
If you prefer not to trigger completions automatically (e.g., on typing or on idle), you can trigger completions manually. This is useful in scenarios where you want to control when completions are provided, such as through a button click or a keyboard shortcut.
|
|
141
|
+
|
|
142
|
+
#### Usage
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
const completion = registerCompletion(monaco, editor, {
|
|
146
|
+
trigger: 'onDemand',
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
completion.trigger();
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
To set up manual triggering, configure the `trigger` option to `'onDemand'`. This disables automatic completions, allowing you to call the `completion.trigger()` method explicitly when needed.
|
|
153
|
+
|
|
154
|
+
For instance, you can set up manual completions to be triggered when the `Ctrl+Shift+Space` keyboard shortcut is pressed.
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
const completion = registerCompletion(monaco, editor, {
|
|
158
|
+
// ...other options
|
|
159
|
+
trigger: 'onDemand',
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
monaco.editor.addCommand(
|
|
163
|
+
monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.Space,
|
|
164
|
+
() => {
|
|
165
|
+
completion.trigger();
|
|
166
|
+
},
|
|
167
|
+
);
|
|
168
|
+
```
|
|
169
|
+
|
|
117
170
|
### External Context
|
|
118
171
|
|
|
119
172
|
Enhance the accuracy and relevance of Copilot's completions by providing additional code context from your workspace.
|
|
@@ -159,26 +212,6 @@ registerCompletion(monaco, editor, {
|
|
|
159
212
|
|
|
160
213
|
This configuration will provide completions relevant to React, Next.js, and Tailwind CSS.
|
|
161
214
|
|
|
162
|
-
### Get Completions in Real-Time
|
|
163
|
-
|
|
164
|
-
The `trigger` option determines when the completion service provides code completions. You can choose between receiving suggestions/completions in real-time as you type or after a brief pause.
|
|
165
|
-
|
|
166
|
-
```javascript
|
|
167
|
-
registerCompletion(monaco, editor, {
|
|
168
|
-
// ...other options
|
|
169
|
-
trigger: 'onTyping',
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
| Trigger | Description | Notes |
|
|
174
|
-
| -------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
175
|
-
| `'onIdle'` (default) | The completion service provides completions after a brief pause in typing. | This approach is less resource-intensive, as it only initiates a request when the editor is idle. However, compared to `onTyping`, it may result in a slightly reduced experience with completions. |
|
|
176
|
-
| `'onTyping'` | The completion service provides completions in real-time as you type. | This approach is best suited for models with low response latency, such as Groq models. Please note that this trigger mode initiates additional background requests to deliver real-time suggestions. Technically, this method is called predictive caching. |
|
|
177
|
-
|
|
178
|
-
[OnTyping Demo](https://github.com/user-attachments/assets/22c2ce44-334c-4963-b853-01b890b8e39f)
|
|
179
|
-
|
|
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.
|
|
181
|
-
|
|
182
215
|
### Max Context Lines
|
|
183
216
|
|
|
184
217
|
To manage potentially lengthy code in your editor, you can limit the number of lines included in the completion request using the `maxContextLines` option.
|
package/build/index.d.mts
CHANGED
|
@@ -119,14 +119,15 @@ interface RegisterCompletionOptions {
|
|
|
119
119
|
* Specifies when the completion service should provide code completions.
|
|
120
120
|
*
|
|
121
121
|
* Options:
|
|
122
|
-
* - `'onIdle'`:
|
|
123
|
-
* - `'onTyping'`:
|
|
122
|
+
* - `'onIdle'`: Provides completions after a brief pause in typing.
|
|
123
|
+
* - `'onTyping'`: Provides completions in real-time as you type.
|
|
124
124
|
* - *Note:* Best suited for models with low response latency (e.g., Groq).
|
|
125
125
|
* - *Consideration:* May initiate additional background requests to deliver real-time suggestions.
|
|
126
|
+
* - `'onDemand'`: Completions are not provided automatically. You need to trigger the completion manually, possibly by using the `trigger` function from `registerCompletion` return.
|
|
126
127
|
*
|
|
127
128
|
* @default 'onIdle'
|
|
128
129
|
*/
|
|
129
|
-
trigger?: 'onTyping' | 'onIdle';
|
|
130
|
+
trigger?: 'onTyping' | 'onIdle' | 'onDemand';
|
|
130
131
|
/**
|
|
131
132
|
* The name of the file you are editing. This is used to provide more relevant completions based on the file's purpose.
|
|
132
133
|
* For example, if you are editing a file named `utils.js`, the completions will be more relevant to utility functions.
|
|
@@ -159,6 +160,10 @@ interface RegisterCompletionOptions {
|
|
|
159
160
|
maxContextLines?: number;
|
|
160
161
|
}
|
|
161
162
|
interface CompletionRegistration {
|
|
163
|
+
/**
|
|
164
|
+
* Triggers the completion.
|
|
165
|
+
*/
|
|
166
|
+
trigger: () => void;
|
|
162
167
|
/**
|
|
163
168
|
* Deregisters the completion from the Monaco editor.
|
|
164
169
|
* This should be called when the completion is no longer needed.
|
|
@@ -268,11 +273,11 @@ declare class Copilot {
|
|
|
268
273
|
}
|
|
269
274
|
|
|
270
275
|
/**
|
|
271
|
-
* Registers
|
|
272
|
-
* @param monaco The Monaco instance.
|
|
273
|
-
* @param editor The editor instance.
|
|
274
|
-
* @param options
|
|
275
|
-
* @returns CompletionRegistration object with
|
|
276
|
+
* Registers completion functionality with the Monaco editor.
|
|
277
|
+
* @param monaco - The Monaco instance.
|
|
278
|
+
* @param editor - The editor instance.
|
|
279
|
+
* @param options - Options for the completion.
|
|
280
|
+
* @returns A CompletionRegistration object with deregister and trigger methods.
|
|
276
281
|
*/
|
|
277
282
|
declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
278
283
|
/**
|
package/build/index.d.ts
CHANGED
|
@@ -119,14 +119,15 @@ interface RegisterCompletionOptions {
|
|
|
119
119
|
* Specifies when the completion service should provide code completions.
|
|
120
120
|
*
|
|
121
121
|
* Options:
|
|
122
|
-
* - `'onIdle'`:
|
|
123
|
-
* - `'onTyping'`:
|
|
122
|
+
* - `'onIdle'`: Provides completions after a brief pause in typing.
|
|
123
|
+
* - `'onTyping'`: Provides completions in real-time as you type.
|
|
124
124
|
* - *Note:* Best suited for models with low response latency (e.g., Groq).
|
|
125
125
|
* - *Consideration:* May initiate additional background requests to deliver real-time suggestions.
|
|
126
|
+
* - `'onDemand'`: Completions are not provided automatically. You need to trigger the completion manually, possibly by using the `trigger` function from `registerCompletion` return.
|
|
126
127
|
*
|
|
127
128
|
* @default 'onIdle'
|
|
128
129
|
*/
|
|
129
|
-
trigger?: 'onTyping' | 'onIdle';
|
|
130
|
+
trigger?: 'onTyping' | 'onIdle' | 'onDemand';
|
|
130
131
|
/**
|
|
131
132
|
* The name of the file you are editing. This is used to provide more relevant completions based on the file's purpose.
|
|
132
133
|
* For example, if you are editing a file named `utils.js`, the completions will be more relevant to utility functions.
|
|
@@ -159,6 +160,10 @@ interface RegisterCompletionOptions {
|
|
|
159
160
|
maxContextLines?: number;
|
|
160
161
|
}
|
|
161
162
|
interface CompletionRegistration {
|
|
163
|
+
/**
|
|
164
|
+
* Triggers the completion.
|
|
165
|
+
*/
|
|
166
|
+
trigger: () => void;
|
|
162
167
|
/**
|
|
163
168
|
* Deregisters the completion from the Monaco editor.
|
|
164
169
|
* This should be called when the completion is no longer needed.
|
|
@@ -268,11 +273,11 @@ declare class Copilot {
|
|
|
268
273
|
}
|
|
269
274
|
|
|
270
275
|
/**
|
|
271
|
-
* Registers
|
|
272
|
-
* @param monaco The Monaco instance.
|
|
273
|
-
* @param editor The editor instance.
|
|
274
|
-
* @param options
|
|
275
|
-
* @returns CompletionRegistration object with
|
|
276
|
+
* Registers completion functionality with the Monaco editor.
|
|
277
|
+
* @param monaco - The Monaco instance.
|
|
278
|
+
* @param editor - The editor instance.
|
|
279
|
+
* @param options - Options for the completion.
|
|
280
|
+
* @returns A CompletionRegistration object with deregister and trigger methods.
|
|
276
281
|
*/
|
|
277
282
|
declare const registerCompletion: (monaco: Monaco, editor: StandaloneCodeEditor, options: RegisterCompletionOptions) => CompletionRegistration;
|
|
278
283
|
/**
|
package/build/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`),r=n.length;if(t>=r)return e;if(o.from==="end"){let l=n.slice(-t);return l.every(
|
|
1
|
+
"use strict";var H=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var ge=(e,t)=>{for(var o in t)H(e,o,{get:t[o],enumerable:!0})},he=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ue(t))!Ce.call(e,r)&&r!==o&&H(e,r,{get:()=>t[r],enumerable:!(n=me(t,r))||n.enumerable});return e};var fe=e=>he(H({},"__esModule",{value:!0}),e);var qe={};ge(qe,{Copilot:()=>L,registerCompletion:()=>Y,registerCopilot:()=>de});module.exports=fe(qe);var q=["groq","openai","anthropic"],X={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},F={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},J="llama-3-70b",z="groq",Z={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},M=.1;var T=class T{constructor(){}static getInstance(){return T.instance}handleError(t,o){let n=this.getErrorDetails(t),r=`\x1B[31m[${o}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(t){return t instanceof Error?{message:t.message,name:t.name,stack:t.stack,context:t.context}:{message:String(t),name:"UnknownError"}}};T.instance=new T;var $=T;var g=(e,t)=>$.getInstance().handleError(e,t);var I=(e,t)=>{let o=null,n=null,r=(...i)=>new Promise((l,c)=>{o&&(clearTimeout(o),n&&n("Cancelled")),n=c,o=setTimeout(()=>{l(e(...i)),n=null},t)});return r.cancel=()=>{o&&(clearTimeout(o),n&&n("Cancelled"),o=null,n=null)},r},y=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var U=(e,t)=>t.getLineContent(e.lineNumber)[e.column-1];var b=(e,t)=>t.getLineContent(e.lineNumber).slice(e.column-1),f=(e,t)=>t.getLineContent(e.lineNumber).slice(0,e.column-1),Q=(e,t)=>t.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),ee=(e,t)=>t.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:t.getLineCount(),endColumn:t.getLineMaxColumn(t.getLineCount())}),V=(e,t,o={})=>{if(t<=0)return"";let n=e.split(`
|
|
2
|
+
`),r=n.length;if(t>=r)return e;if(o.from==="end"){let l=n.slice(-t);return l.every(c=>c==="")?`
|
|
3
3
|
`.repeat(t):l.join(`
|
|
4
4
|
`)}let i=n.slice(0,t);return i.every(l=>l==="")?`
|
|
5
5
|
`.repeat(t):i.join(`
|
|
6
|
-
`)};var te=async(e,t,o={})=>{let n={"Content-Type":"application/json",...o.headers},r=t==="POST"&&o.body?JSON.stringify(o.body):void 0,i=await fetch(e,{method:t,headers:n,body:r,signal:o.signal});if(!i.ok)throw new Error(`${o.error||"Network error"}: ${i.statusText}`);return i.json()},
|
|
6
|
+
`)};var te=async(e,t,o={})=>{let n={"Content-Type":"application/json",...o.headers},r=t==="POST"&&o.body?JSON.stringify(o.body):void 0,i=await fetch(e,{method:t,headers:n,body:r,signal:o.signal});if(!i.ok)throw new Error(`${o.error||"Network error"}: ${i.statusText}`);return i.json()},Ee=(e,t)=>te(e,"GET",t),xe=(e,t,o)=>te(e,"POST",{...o,body:t}),v={GET:Ee,POST:xe};var oe=(e,t)=>{let o=b(e,t).trim(),n=f(e,t).trim();return e.column<=3&&(o!==""||n!=="")};var Pe="<user-current-cursor-position-is-here>",Te=e=>e==="javascript"?"JavaScript (ESNext)":e,ye=e=>`You are an expert ${Te(e.language)||y(e.technologies)} developer assistant with extensive experience in code completion and adhering to best coding practices. Your role is to provide precise and contextually relevant code completions without any errors, including syntax, punctuation, spaces, tabs, and line breaks. Focus on integrating seamlessly with the existing code and follow the user's instructions carefully.`,Oe=e=>{let{filename:t="/",textBeforeCursor:o="",textAfterCursor:n="",externalContext:r,editorState:i}=e,a=`
|
|
7
7
|
<guidelines>
|
|
8
8
|
<instruction>${{continue:"Continue writing the code from where the cursor is positioned.",insert:"Insert the appropriate code snippet at the cursor position.",complete:"Provide the necessary code to complete the current statement or block."}[i.completionMode]}</instruction>
|
|
9
9
|
<steps>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<step>Return <strong>only</strong> the code required at the cursor position.</step>
|
|
18
18
|
</steps>
|
|
19
19
|
</guidelines>
|
|
20
|
-
`,
|
|
20
|
+
`,s=`
|
|
21
21
|
<context>
|
|
22
22
|
<current_file path="${t}">
|
|
23
23
|
<code>
|
|
@@ -25,21 +25,21 @@ ${o}${Pe}${n}
|
|
|
25
25
|
</code>
|
|
26
26
|
</current_file>
|
|
27
27
|
</context>
|
|
28
|
-
`,
|
|
29
|
-
<external_file path="${
|
|
28
|
+
`,m=r?.map(({path:u,content:p})=>`
|
|
29
|
+
<external_file path="${u}">
|
|
30
30
|
<code>
|
|
31
|
-
${
|
|
31
|
+
${p}
|
|
32
32
|
</code>
|
|
33
33
|
</external_file>
|
|
34
34
|
`).join(`
|
|
35
35
|
`)||"";return`
|
|
36
36
|
<task>
|
|
37
37
|
${a}
|
|
38
|
-
${
|
|
39
|
-
${
|
|
38
|
+
${s}
|
|
39
|
+
${m}
|
|
40
40
|
</task>
|
|
41
|
-
`};function
|
|
41
|
+
`};function j(e){return{system:ye(e),user:Oe(e)}}var ne={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Re={createRequestBody:(e,t)=>{let n=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:t.user}]:[{role:"system",content:t.system},{role:"user",content:t.user}];return{model:K(e),temperature:M,messages:n}},createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Me={createRequestBody:(e,t)=>({model:K(e),temperature:M,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Ie={createRequestBody:(e,t)=>({model:K(e),temperature:M,system:t.system,messages:[{role:"user",content:t.user}],max_tokens:be(e)}),createHeaders:e=>({"Content-Type":"application/json","x-api-key":e,"anthropic-version":"2023-06-01"}),parseCompletion:e=>!e.content||typeof e.content!="string"?null:e.content},G={openai:Re,groq:Me,anthropic:Ie},re=(e,t,o)=>G[t].createRequestBody(e,o),ie=(e,t)=>G[t].createHeaders(e),se=(e,t)=>G[t].parseCompletion(e),K=e=>X[e],le=e=>Z[e],be=e=>ne[e]||4096;var L=class{constructor(t,o={}){if(!t)throw new Error("Please provide an API key.");this.apiKey=t,this.provider=o.provider??z,this.model=o.model??J,this.validateInputs()}validateInputs(){if(!q.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${y(q)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!F[this.provider].includes(this.model)){let t=y(F[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${t}`)}}async complete(t){let{body:o,options:n}=t,{completionMetadata:r}=o,{headers:i={},customPrompt:l}=n??{},c=j(r),a=l?{...c,...l(r)}:c,s=le(this.provider),m,u=ie(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let p=this.model.config(this.apiKey,a);s=p.endpoint??s,m=p.body??{},u={...u,...p.headers}}else m=re(this.model,this.provider,a);u={...u,...i};try{let p=await v.POST(s,m,{headers:u}),d;if(typeof this.model=="object"&&"transformResponse"in this.model){let C=this.model.transformResponse(p);d={completion:C.text??C.completion}}else d={completion:se(p,this.provider)};return d}catch(p){return{error:g(p,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var _=class e{constructor(t){this.formattedCompletion="";this.formattedCompletion=t}static create(t){return new e(t)}setCompletion(t){return this.formattedCompletion=t,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(t){let o=/```[\s\S]*?```/g,n=t,r;for(;(r=o.exec(t))!==null;){let i=r[0],l=i.split(`
|
|
42
42
|
`).slice(1,-1).join(`
|
|
43
43
|
`);n=n.replace(i,l)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
44
44
|
|
|
45
|
-
`),this}build(){return this.formattedCompletion}};var A=class{constructor(t,o){this.cursorPos=t,this.mdl=o}shouldProvideCompletions(){return!oe(this.cursorPos,this.mdl)}};var
|
|
45
|
+
`),this}build(){return this.formattedCompletion}};var A=class{constructor(t,o){this.cursorPos=t,this.mdl=o}shouldProvideCompletions(){return!oe(this.cursorPos,this.mdl)}};var D=class D{constructor(){this.cache=[]}get(t,o){return this.cache.filter(n=>this.isValidCacheItem(n,t,o))}add(t){let o=[...this.cache.slice(-(D.MAX_CACHE_SIZE-1)),t];this.cache=o}clear(){this.cache=[]}isValidCacheItem(t,o,n){let r=n.getValueInRange(t.range);return f(o,n).startsWith(t.textBeforeCursorInLine)&&this.isPositionValid(t,o,r)}isPositionValid(t,o,n){let{range:r,completion:i}=t,{startLineNumber:l,startColumn:c,endColumn:a}=r,{lineNumber:s,column:m}=o,u=s===l&&m===c,p=i.startsWith(n)&&s===l&&m>=c-n.length&&m<=a+n.length;return u||p}};D.MAX_CACHE_SIZE=10;var N=D;var ve="application/json",S=async({filename:e,endpoint:t,language:o,technologies:n,externalContext:r,mdl:i,pos:l,maxContextLines:c})=>{try{let{completion:a}=await v.POST(t,{completionMetadata:Le({filename:e,pos:l,mdl:i,language:o,technologies:n,externalContext:r,maxContextLines:c})},{headers:{"Content-Type":ve},error:"Error while fetching completion item"});return a}catch(a){return g(a,"FETCH_COMPLETION_ITEM_ERROR"),null}},Le=({filename:e,pos:t,mdl:o,language:n,technologies:r,externalContext:i,maxContextLines:l})=>{let c=_e(t,o),s=!!i?.length?3:2,m=l?Math.floor(l/s):void 0,u=(x,P,k)=>{let R=x(t,o);return P?V(R,P,k):R},p=(x,P)=>!x||!P?x:x.map(({content:k,...R})=>({...R,content:V(k,P)})),d=u(Q,m,{from:"end"}),C=u(ee,m),B=p(i,m);return{filename:e,language:n,technologies:r,externalContext:B,textBeforeCursor:d,textAfterCursor:C,cursorPosition:t,editorState:{completionMode:c}}},_e=(e,t)=>{let o=U(e,t),n=b(e,t);return o?"insert":n.trim()?"complete":"continue"};var ae=(e,t,o)=>{if(!o)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let n=t.getOffsetAt(e),r=t.getValue().substring(n),i=0,l=0,c=0,a=o.length,s=r.length;if(n>=t.getValue().length)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};if(s===0)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let m=Math.min(a,s);for(let d=0;d<m&&o[d]===r[d];d++)i++;for(let d=1;d<=m;d++){let C=o.slice(-d),B=r.slice(0,d);C===B&&(l=d)}if(c=Math.max(i,l),c===0)for(let d=1;d<a;d++){let C=o.substring(d);if(r.startsWith(C)){c=a-d;break}}let u=n+c,p=t.getPositionAt(u);return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:p.lineNumber,endColumn:p.column}},pe=e=>_.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build(),h=e=>({items:e,enableForwardStability:!0});var Ne=300,De=600,Se=0,we={onTyping:I(S,Ne),onIdle:I(S,De),onDemand:I(S,Se)},w=new N,Be=async({mdl:e,pos:t,token:o,isCompletionAccepted:n,onShowCompletion:r,options:i})=>{let{trigger:l="onIdle",...c}=i;if(!new A(t,e).shouldProvideCompletions())return h([]);let a=w.get(t,e).map(s=>({insertText:s.completion,range:{...s.range,endColumn:t.column}}));if(a.length>0)return r(),h(a);if(o.isCancellationRequested||n)return h([]);try{let s=we[l];o.onCancellationRequested(()=>{s.cancel()});let m=await s({...c,text:e.getValue(),mdl:e,pos:t});if(m){let u=pe(m),p=ae(t,e,u);return w.add({completion:u,range:p,textBeforeCursorInLine:f(t,e)}),r(),h([{insertText:u,range:p}])}}catch(s){if(ke(s))return h([]);g(s,"FETCH_COMPLETION_ITEM_ERROR")}return h([])},ke=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),ce=Be;var E=new WeakMap,O=null,Y=(e,t,o)=>{O&&O.deregister();let n=[],r={isCompletionAccepted:!1,isCompletionVisible:!1,isManualTrigger:!1};E.set(t,r),t.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});try{let i=e.languages.registerInlineCompletionsProvider(o.language,{provideInlineCompletions:(a,s,m,u)=>{let p=E.get(t);if(!(!p||o.trigger==="onDemand"&&!p.isManualTrigger))return ce({mdl:a,pos:s,token:u,isCompletionAccepted:p.isCompletionAccepted,onShowCompletion:()=>{p.isCompletionVisible=!0,p.isManualTrigger=!1},options:o})},freeInlineCompletions:()=>{}});n.push(i);let l=t.onKeyDown(a=>{let s=E.get(t);if(!s)return;let m=a.keyCode===e.KeyCode.Tab||a.keyCode===e.KeyCode.RightArrow&&a.metaKey;s.isCompletionVisible&&m?(s.isCompletionAccepted=!0,s.isCompletionVisible=!1):s.isCompletionAccepted=!1});n.push(l);let c={deregister:()=>{n.forEach(a=>a.dispose()),w.clear(),E.delete(t),O=null},trigger:()=>He(t)};return O=c,c}catch(i){return g(i,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(l=>l.dispose()),E.delete(t),O=null},trigger:()=>{}}}},He=e=>{let t=E.get(e);if(!t){g(new Error("Completion is not registered. Use `registerCompletion` to register completion first."),"TRIGGER_COMPLETION_ERROR");return}t.isManualTrigger=!0,e.trigger("keyboard","editor.action.inlineSuggest.trigger",{})},de=Y;0&&(module.exports={Copilot,registerCompletion,registerCopilot});
|
package/build/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),r=n.length;if(t>=r)return e;if(o.from==="end"){let l=n.slice(-t);return l.every(
|
|
1
|
+
var k=["groq","openai","anthropic"],W={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini","claude-3.5-sonnet":"claude-3.5-sonnet-20240620","claude-3-opus":"claude-3-opus-20240229","claude-3-sonnet":"claude-3-sonnet-20240229","claude-3-haiku":"claude-3-haiku-20240307","o1-preview":"o1-preview","o1-mini":"o1-mini"},H={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini","o1-preview","o1-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},Y="llama-3-70b",X="groq",J={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},M=.1;var T=class T{constructor(){}static getInstance(){return T.instance}handleError(t,o){let n=this.getErrorDetails(t),r=`\x1B[31m[${o}]\x1B[0m \x1B[1m${n.message}\x1B[0m`;return console.error(r),n}getErrorDetails(t){return t instanceof Error?{message:t.message,name:t.name,stack:t.stack,context:t.context}:{message:String(t),name:"UnknownError"}}};T.instance=new T;var q=T;var g=(e,t)=>q.getInstance().handleError(e,t);var I=(e,t)=>{let o=null,n=null,r=(...i)=>new Promise((l,c)=>{o&&(clearTimeout(o),n&&n("Cancelled")),n=c,o=setTimeout(()=>{l(e(...i)),n=null},t)});return r.cancel=()=>{o&&(clearTimeout(o),n&&n("Cancelled"),o=null,n=null)},r},y=e=>!e||e.length===0?"":e.length===1?e[0]:`${e.slice(0,-1).join(", ")} and ${e.slice(-1)}`;var F=(e,t)=>t.getLineContent(e.lineNumber)[e.column-1];var b=(e,t)=>t.getLineContent(e.lineNumber).slice(e.column-1),f=(e,t)=>t.getLineContent(e.lineNumber).slice(0,e.column-1),z=(e,t)=>t.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:e.lineNumber,endColumn:e.column}),Z=(e,t)=>t.getValueInRange({startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:t.getLineCount(),endColumn:t.getLineMaxColumn(t.getLineCount())}),$=(e,t,o={})=>{if(t<=0)return"";let n=e.split(`
|
|
2
|
+
`),r=n.length;if(t>=r)return e;if(o.from==="end"){let l=n.slice(-t);return l.every(c=>c==="")?`
|
|
3
3
|
`.repeat(t):l.join(`
|
|
4
4
|
`)}let i=n.slice(0,t);return i.every(l=>l==="")?`
|
|
5
5
|
`.repeat(t):i.join(`
|
|
6
|
-
`)};var Q=async(e,t,o={})=>{let n={"Content-Type":"application/json",...o.headers},r=t==="POST"&&o.body?JSON.stringify(o.body):void 0,i=await fetch(e,{method:t,headers:n,body:r,signal:o.signal});if(!i.ok)throw new Error(`${o.error||"Network error"}: ${i.statusText}`);return i.json()},ce=(e,t)=>Q(e,"GET",t),de=(e,t,o)=>Q(e,"POST",{...o,body:t}),
|
|
6
|
+
`)};var Q=async(e,t,o={})=>{let n={"Content-Type":"application/json",...o.headers},r=t==="POST"&&o.body?JSON.stringify(o.body):void 0,i=await fetch(e,{method:t,headers:n,body:r,signal:o.signal});if(!i.ok)throw new Error(`${o.error||"Network error"}: ${i.statusText}`);return i.json()},ce=(e,t)=>Q(e,"GET",t),de=(e,t,o)=>Q(e,"POST",{...o,body:t}),v={GET:ce,POST:de};var ee=(e,t)=>{let o=b(e,t).trim(),n=f(e,t).trim();return e.column<=3&&(o!==""||n!=="")};var me="<user-current-cursor-position-is-here>",ue=e=>e==="javascript"?"JavaScript (ESNext)":e,Ce=e=>`You are an expert ${ue(e.language)||y(e.technologies)} developer assistant with extensive experience in code completion and adhering to best coding practices. Your role is to provide precise and contextually relevant code completions without any errors, including syntax, punctuation, spaces, tabs, and line breaks. Focus on integrating seamlessly with the existing code and follow the user's instructions carefully.`,ge=e=>{let{filename:t="/",textBeforeCursor:o="",textAfterCursor:n="",externalContext:r,editorState:i}=e,a=`
|
|
7
7
|
<guidelines>
|
|
8
8
|
<instruction>${{continue:"Continue writing the code from where the cursor is positioned.",insert:"Insert the appropriate code snippet at the cursor position.",complete:"Provide the necessary code to complete the current statement or block."}[i.completionMode]}</instruction>
|
|
9
9
|
<steps>
|
|
@@ -17,7 +17,7 @@ var D=["groq","openai","anthropic"],G={"llama-3-70b":"llama3-70b-8192","gpt-4o":
|
|
|
17
17
|
<step>Return <strong>only</strong> the code required at the cursor position.</step>
|
|
18
18
|
</steps>
|
|
19
19
|
</guidelines>
|
|
20
|
-
`,
|
|
20
|
+
`,s=`
|
|
21
21
|
<context>
|
|
22
22
|
<current_file path="${t}">
|
|
23
23
|
<code>
|
|
@@ -25,21 +25,21 @@ ${o}${me}${n}
|
|
|
25
25
|
</code>
|
|
26
26
|
</current_file>
|
|
27
27
|
</context>
|
|
28
|
-
`,
|
|
29
|
-
<external_file path="${
|
|
28
|
+
`,m=r?.map(({path:u,content:p})=>`
|
|
29
|
+
<external_file path="${u}">
|
|
30
30
|
<code>
|
|
31
|
-
${
|
|
31
|
+
${p}
|
|
32
32
|
</code>
|
|
33
33
|
</external_file>
|
|
34
34
|
`).join(`
|
|
35
35
|
`)||"";return`
|
|
36
36
|
<task>
|
|
37
37
|
${a}
|
|
38
|
-
${
|
|
39
|
-
${
|
|
38
|
+
${s}
|
|
39
|
+
${m}
|
|
40
40
|
</task>
|
|
41
|
-
`};function
|
|
41
|
+
`};function U(e){return{system:Ce(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,t)=>{let n=e==="o1-preview"||e==="o1-mini"?[{role:"user",content:t.user}]:[{role:"system",content:t.system},{role:"user",content:t.user}];return{model:j(e),temperature:M,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,t)=>({model:j(e),temperature:M,messages:[{role:"system",content:t.system},{role:"user",content:t.user}]}),createHeaders:e=>({"Content-Type":"application/json",Authorization:`Bearer ${e}`}),parseCompletion:e=>e.choices?.length?e.choices[0].message.content:null},Ee={createRequestBody:(e,t)=>({model:j(e),temperature:M,system:t.system,messages:[{role:"user",content:t.user}],max_tokens:xe(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},V={openai:he,groq:fe,anthropic:Ee},oe=(e,t,o)=>V[t].createRequestBody(e,o),ne=(e,t)=>V[t].createHeaders(e),re=(e,t)=>V[t].parseCompletion(e),j=e=>W[e],ie=e=>J[e],xe=e=>te[e]||4096;var G=class{constructor(t,o={}){if(!t)throw new Error("Please provide an API key.");this.apiKey=t,this.provider=o.provider??X,this.model=o.model??Y,this.validateInputs()}validateInputs(){if(!k.includes(this.provider))throw new Error(`The provider "${this.provider}" is not supported. Please choose a supported provider: ${y(k)}. If you're using a custom model, you don't need to specify a provider.`);if(typeof this.model=="string"&&!H[this.provider].includes(this.model)){let t=y(H[this.provider]);throw new Error(`Model "${this.model}" is not supported by the "${this.provider}" provider. Supported models: ${t}`)}}async complete(t){let{body:o,options:n}=t,{completionMetadata:r}=o,{headers:i={},customPrompt:l}=n??{},c=U(r),a=l?{...c,...l(r)}:c,s=ie(this.provider),m,u=ne(this.apiKey,this.provider);if(typeof this.model=="object"&&"config"in this.model){let p=this.model.config(this.apiKey,a);s=p.endpoint??s,m=p.body??{},u={...u,...p.headers}}else m=oe(this.model,this.provider,a);u={...u,...i};try{let p=await v.POST(s,m,{headers:u}),d;if(typeof this.model=="object"&&"transformResponse"in this.model){let C=this.model.transformResponse(p);d={completion:C.text??C.completion}}else d={completion:re(p,this.provider)};return d}catch(p){return{error:g(p,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}};var L=class e{constructor(t){this.formattedCompletion="";this.formattedCompletion=t}static create(t){return new e(t)}setCompletion(t){return this.formattedCompletion=t,this}removeInvalidLineBreaks(){return this.formattedCompletion=this.formattedCompletion.trimEnd(),this}removeMarkdownCodeSyntax(){return this.formattedCompletion=this.removeMarkdownCodeBlocks(this.formattedCompletion),this}removeMarkdownCodeBlocks(t){let o=/```[\s\S]*?```/g,n=t,r;for(;(r=o.exec(t))!==null;){let i=r[0],l=i.split(`
|
|
42
42
|
`).slice(1,-1).join(`
|
|
43
43
|
`);n=n.replace(i,l)}return n.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
|
|
44
44
|
|
|
45
|
-
`),this}build(){return this.formattedCompletion}};var
|
|
45
|
+
`),this}build(){return this.formattedCompletion}};var _=class{constructor(t,o){this.cursorPos=t,this.mdl=o}shouldProvideCompletions(){return!ee(this.cursorPos,this.mdl)}};var N=class N{constructor(){this.cache=[]}get(t,o){return this.cache.filter(n=>this.isValidCacheItem(n,t,o))}add(t){let o=[...this.cache.slice(-(N.MAX_CACHE_SIZE-1)),t];this.cache=o}clear(){this.cache=[]}isValidCacheItem(t,o,n){let r=n.getValueInRange(t.range);return f(o,n).startsWith(t.textBeforeCursorInLine)&&this.isPositionValid(t,o,r)}isPositionValid(t,o,n){let{range:r,completion:i}=t,{startLineNumber:l,startColumn:c,endColumn:a}=r,{lineNumber:s,column:m}=o,u=s===l&&m===c,p=i.startsWith(n)&&s===l&&m>=c-n.length&&m<=a+n.length;return u||p}};N.MAX_CACHE_SIZE=10;var A=N;var Pe="application/json",D=async({filename:e,endpoint:t,language:o,technologies:n,externalContext:r,mdl:i,pos:l,maxContextLines:c})=>{try{let{completion:a}=await v.POST(t,{completionMetadata:Te({filename:e,pos:l,mdl:i,language:o,technologies:n,externalContext:r,maxContextLines:c})},{headers:{"Content-Type":Pe},error:"Error while fetching completion item"});return a}catch(a){return g(a,"FETCH_COMPLETION_ITEM_ERROR"),null}},Te=({filename:e,pos:t,mdl:o,language:n,technologies:r,externalContext:i,maxContextLines:l})=>{let c=ye(t,o),s=!!i?.length?3:2,m=l?Math.floor(l/s):void 0,u=(x,P,B)=>{let R=x(t,o);return P?$(R,P,B):R},p=(x,P)=>!x||!P?x:x.map(({content:B,...R})=>({...R,content:$(B,P)})),d=u(z,m,{from:"end"}),C=u(Z,m),w=p(i,m);return{filename:e,language:n,technologies:r,externalContext:w,textBeforeCursor:d,textAfterCursor:C,cursorPosition:t,editorState:{completionMode:c}}},ye=(e,t)=>{let o=F(e,t),n=b(e,t);return o?"insert":n.trim()?"complete":"continue"};var se=(e,t,o)=>{if(!o)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let n=t.getOffsetAt(e),r=t.getValue().substring(n),i=0,l=0,c=0,a=o.length,s=r.length;if(n>=t.getValue().length)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};if(s===0)return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:e.lineNumber,endColumn:e.column};let m=Math.min(a,s);for(let d=0;d<m&&o[d]===r[d];d++)i++;for(let d=1;d<=m;d++){let C=o.slice(-d),w=r.slice(0,d);C===w&&(l=d)}if(c=Math.max(i,l),c===0)for(let d=1;d<a;d++){let C=o.substring(d);if(r.startsWith(C)){c=a-d;break}}let u=n+c,p=t.getPositionAt(u);return{startLineNumber:e.lineNumber,startColumn:e.column,endLineNumber:p.lineNumber,endColumn:p.column}},le=e=>L.create(e).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build(),h=e=>({items:e,enableForwardStability:!0});var Re=300,Me=600,Ie=0,be={onTyping:I(D,Re),onIdle:I(D,Me),onDemand:I(D,Ie)},S=new A,ve=async({mdl:e,pos:t,token:o,isCompletionAccepted:n,onShowCompletion:r,options:i})=>{let{trigger:l="onIdle",...c}=i;if(!new _(t,e).shouldProvideCompletions())return h([]);let a=S.get(t,e).map(s=>({insertText:s.completion,range:{...s.range,endColumn:t.column}}));if(a.length>0)return r(),h(a);if(o.isCancellationRequested||n)return h([]);try{let s=be[l];o.onCancellationRequested(()=>{s.cancel()});let m=await s({...c,text:e.getValue(),mdl:e,pos:t});if(m){let u=le(m),p=se(t,e,u);return S.add({completion:u,range:p,textBeforeCursorInLine:f(t,e)}),r(),h([{insertText:u,range:p}])}}catch(s){if(Le(s))return h([]);g(s,"FETCH_COMPLETION_ITEM_ERROR")}return h([])},Le=e=>typeof e=="string"&&(e==="Cancelled"||e==="AbortError")||e instanceof Error&&(e.message==="Cancelled"||e.name==="AbortError"),ae=ve;var E=new WeakMap,O=null,pe=(e,t,o)=>{O&&O.deregister();let n=[],r={isCompletionAccepted:!1,isCompletionVisible:!1,isManualTrigger:!1};E.set(t,r),t.updateOptions({inlineSuggest:{enabled:!0,mode:"subwordSmart"}});try{let i=e.languages.registerInlineCompletionsProvider(o.language,{provideInlineCompletions:(a,s,m,u)=>{let p=E.get(t);if(!(!p||o.trigger==="onDemand"&&!p.isManualTrigger))return ae({mdl:a,pos:s,token:u,isCompletionAccepted:p.isCompletionAccepted,onShowCompletion:()=>{p.isCompletionVisible=!0,p.isManualTrigger=!1},options:o})},freeInlineCompletions:()=>{}});n.push(i);let l=t.onKeyDown(a=>{let s=E.get(t);if(!s)return;let m=a.keyCode===e.KeyCode.Tab||a.keyCode===e.KeyCode.RightArrow&&a.metaKey;s.isCompletionVisible&&m?(s.isCompletionAccepted=!0,s.isCompletionVisible=!1):s.isCompletionAccepted=!1});n.push(l);let c={deregister:()=>{n.forEach(a=>a.dispose()),S.clear(),E.delete(t),O=null},trigger:()=>_e(t)};return O=c,c}catch(i){return g(i,"REGISTER_COMPLETION_ERROR"),{deregister:()=>{n.forEach(l=>l.dispose()),E.delete(t),O=null},trigger:()=>{}}}},_e=e=>{let t=E.get(e);if(!t){g(new Error("Completion is not registered. Use `registerCompletion` to register completion first."),"TRIGGER_COMPLETION_ERROR");return}t.isManualTrigger=!0,e.trigger("keyboard","editor.action.inlineSuggest.trigger",{})},Ae=pe;export{G as Copilot,pe as registerCompletion,Ae as registerCopilot};
|