monacopilot 0.9.19 → 0.9.20

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
@@ -9,9 +9,11 @@
9
9
  - [Examples](#examples)
10
10
  - [Installation](#installation)
11
11
  - [Usage](#usage)
12
+ - [Copilot Instance Options](#copilot-instance-options)
13
+ - [Changing the Provider and Model](#changing-the-provider-and-model)
14
+ - [Custom Headers](#custom-headers)
12
15
  - [Configuration Options](#configuration-options)
13
16
  - [External Context](#external-context)
14
- - [Changing the Provider and Model](#changing-the-provider-and-model)
15
17
  - [Filename](#filename)
16
18
  - [Completions for Specific Technologies](#completions-for-specific-technologies)
17
19
  - [Cost Overview](#cost-overview)
@@ -40,6 +42,8 @@ npm install monacopilot
40
42
 
41
43
  #### Setting Up the API Key
42
44
 
45
+ In this example, we'll use Groq as our provider.
46
+
43
47
  Start by obtaining an API key from the [Groq console](https://console.groq.com/keys). Once you have your API key, define it as an environment variable in your project:
44
48
 
45
49
  ```bash
@@ -87,6 +91,43 @@ registerCopilot(monaco, editor, {
87
91
  });
88
92
  ```
89
93
 
94
+ ## Copilot Instance Options
95
+
96
+ ### Changing the Provider and Model
97
+
98
+ You can specify a different provider and model for completions by setting the `provider` and `model` parameters in the `Copilot` instance.
99
+
100
+ ```javascript
101
+ const copilot = new Copilot(process.env.OPENAI_API_KEY, {
102
+ provider: 'openai',
103
+ model: 'gpt-4o',
104
+ });
105
+ ```
106
+
107
+ The default provider is `groq` and the default model is `llama-3-70b`.
108
+
109
+ | Provider | Model | Description |
110
+ | --------- | ----------------- | ------------------------------------------------------------------------------------------------------------- |
111
+ | Groq | llama-3-70b | Ultra-fast inference (<0.5s response time), balancing speed and quality for a wide range of coding tasks |
112
+ | OpenAI | gpt-4o-mini | Compact version of gpt-4o, offering cost-effective completions with good performance |
113
+ | OpenAI | gpt-4o | State-of-the-art model, excelling in complex reasoning and generating high-quality, context-aware completions |
114
+ | Anthropic | Claude-3.5-Sonnet | Advanced AI with broad knowledge, ideal for diverse coding scenarios and natural language understanding |
115
+ | Anthropic | Claude-3-Opus | Top-tier AI model, exceptional at handling intricate tasks and providing detailed, nuanced completions |
116
+ | Anthropic | Claude-3-Sonnet | Versatile and powerful, offering a great balance between performance and efficiency for various coding needs |
117
+ | Anthropic | Claude-3-Haiku | Streamlined model optimized for speed, perfect for quick completions and real-time coding assistance |
118
+
119
+ ### Custom Headers
120
+
121
+ You can add custom headers to the provider's completion requests. For example, if you select `OpenAI` as your provider, you can add a custom header to the OpenAI chat completion requests made by Monacopilot.
122
+
123
+ ```javascript
124
+ const copilot = new Copilot(process.env.API_KEY, {
125
+ headers: {
126
+ 'X-Custom-Header': 'custom-value',
127
+ },
128
+ });
129
+ ```
130
+
90
131
  ## Configuration Options
91
132
 
92
133
  ### External Context
@@ -108,25 +149,6 @@ registerCopilot(monaco, editor, {
108
149
 
109
150
  By providing external context, Copilot can offer more intelligent suggestions. For example, if you start typing `const isPalindrome = `, Copilot may suggest using the `reverse` function from `utils.js`.
110
151
 
111
- ### Changing the Provider and Model
112
-
113
- You can specify a different provider and model for completions by setting the `provider` and `model` parameters in the `Copilot` instance.
114
-
115
- ```javascript
116
- const copilot = new Copilot(process.env.OPENAI_API_KEY, {
117
- provider: 'openai',
118
- model: 'gpt-4o',
119
- });
120
- ```
121
-
122
- The default provider is `groq` and the default model is `llama-3-70b`.
123
-
124
- | Provider | Model | Description | Avg. Response Time |
125
- | -------- | ----------- | ------------------------------------------------- | ------------------ |
126
- | Groq | llama-3-70b | Fast and efficient, suitable for most tasks | <0.5s |
127
- | OpenAI | gpt-4o-mini | Mini version of gpt-4o, cheaper | 1.5-3s |
128
- | OpenAI | gpt-4o | Highly intelligent, ideal for complex completions | 1-2s |
129
-
130
152
  ### Filename
131
153
 
132
154
  Specify the name of the file being edited to receive more contextually relevant completions.
@@ -153,24 +175,6 @@ registerCopilot(monaco, editor, {
153
175
 
154
176
  This configuration will provide completions relevant to React, Next.js, and Tailwind CSS.
155
177
 
156
- ## Cost Overview
157
-
158
- The cost of completions is very affordable. See the table below for an estimate of the costs you will need to pay for completions.
159
-
160
- | Provider | Model | Avg. Cost per 1000 Code Completions |
161
- | -------- | ----------- | ----------------------------------- |
162
- | Groq | llama-3-70b | $0.939 |
163
- | OpenAI | gpt-4o-mini | $0.821 |
164
- | OpenAI | gpt-4o | $3.46 |
165
-
166
- > **Note:** Currently, Groq does not implement billing, allowing free usage of their API. During this free period, you will experience minimal rate limiting and some latency in completions. You can opt for Groq's enterprise plan to benefit from increased rate limits and get quick completions without visible latency.
167
-
168
- ## FAQ
169
-
170
- ### Is AI Auto Completion Free?
171
-
172
- You use your own Groq or OpenAI API key for AI auto-completion. The cost of completions is very affordable, and we implement various methods to minimize these costs as much as possible. Costs vary depending on the model you use; see this [cost overview](#cost-overview) for an idea of the cost.
173
-
174
178
  ## Contributing
175
179
 
176
180
  For guidelines on contributing, Please read the [contributing guide](https://github.com/arshad-yaseen/monacopilot/blob/main/CONTRIBUTING.md).
package/build/index.d.mts CHANGED
@@ -3,9 +3,25 @@ import * as monaco from 'monaco-editor';
3
3
  type Monaco = typeof monaco;
4
4
  type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
5
5
 
6
+ /**
7
+ * Options for configuring the Copilot instance.
8
+ */
6
9
  interface CopilotOptions {
10
+ /**
11
+ * The completion provider to use (e.g., 'openai', 'anthropic', 'groq').
12
+ * If not specified, a default provider will be used.
13
+ */
7
14
  provider?: CompletionProvider;
15
+ /**
16
+ * The specific model to use for completions.
17
+ * Must be compatible with the chosen provider.
18
+ * If not specified, a default model will be used.
19
+ */
8
20
  model?: CompletionModel;
21
+ /**
22
+ * Additional headers to include in the completion requests.
23
+ */
24
+ headers?: Record<string, string>;
9
25
  }
10
26
  type Endpoint = string;
11
27
  type Filename = string;
@@ -64,8 +80,11 @@ interface CopilotRegistration {
64
80
  deregister: () => void;
65
81
  }
66
82
 
67
- type CompletionModel = 'llama-3-70b' | 'gpt-4o' | 'gpt-4o-mini';
68
- type CompletionProvider = 'openai' | 'groq';
83
+ type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini';
84
+ type GroqModel = 'llama-3-70b';
85
+ type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
86
+ type CompletionModel = OpenAIModel | GroqModel | AnthropicModel;
87
+ type CompletionProvider = 'openai' | 'groq' | 'anthropic';
69
88
  interface CompletionRequest {
70
89
  completionMetadata: CompletionMetadata;
71
90
  }
@@ -87,29 +106,26 @@ interface CompletionMetadata {
87
106
  }
88
107
 
89
108
  /**
90
- * Copilot class for handling completions using the API.
109
+ * Copilot class for handling completions using various AI providers.
91
110
  */
92
111
  declare class Copilot {
93
112
  private readonly apiKey;
94
- private readonly model;
95
113
  private readonly provider;
114
+ private readonly model;
115
+ private readonly headers;
96
116
  /**
97
117
  * Initializes the Copilot with an API key and optional configuration.
98
- * @param {string} apiKey - The API key.
99
- * @param {CopilotOptions<CompletionProvider>} [options] - Optional parameters to configure the completion model.
100
- * @throws {Error} If the API key is not provided.
118
+ * @param apiKey - The API key for the chosen provider.
119
+ * @param options - Options for configuring the Copilot instance.
101
120
  */
102
121
  constructor(apiKey: string, options?: CopilotOptions);
103
122
  /**
104
- * Sends a completion request to API and returns the completion.
105
- * @param {CompletionRequest} params - The metadata required to generate the completion.
106
- * @returns {Promise<CompletionResponse>} The completed text snippet or an error.
123
+ * Sends a completion request to the API and returns the completion.
124
+ * @param params - The metadata required to generate the completion.
125
+ * @returns A promise resolving to the completed text snippet or an error.
107
126
  */
108
127
  complete({ completionMetadata, }: CompletionRequest): Promise<CompletionResponse>;
109
- private getEndpoint;
110
- private getModelId;
111
- private createRequestBody;
112
- private createHeaders;
128
+ private validateInputs;
113
129
  }
114
130
 
115
131
  /**
package/build/index.d.ts CHANGED
@@ -3,9 +3,25 @@ import * as monaco from 'monaco-editor';
3
3
  type Monaco = typeof monaco;
4
4
  type StandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
5
5
 
6
+ /**
7
+ * Options for configuring the Copilot instance.
8
+ */
6
9
  interface CopilotOptions {
10
+ /**
11
+ * The completion provider to use (e.g., 'openai', 'anthropic', 'groq').
12
+ * If not specified, a default provider will be used.
13
+ */
7
14
  provider?: CompletionProvider;
15
+ /**
16
+ * The specific model to use for completions.
17
+ * Must be compatible with the chosen provider.
18
+ * If not specified, a default model will be used.
19
+ */
8
20
  model?: CompletionModel;
21
+ /**
22
+ * Additional headers to include in the completion requests.
23
+ */
24
+ headers?: Record<string, string>;
9
25
  }
10
26
  type Endpoint = string;
11
27
  type Filename = string;
@@ -64,8 +80,11 @@ interface CopilotRegistration {
64
80
  deregister: () => void;
65
81
  }
66
82
 
67
- type CompletionModel = 'llama-3-70b' | 'gpt-4o' | 'gpt-4o-mini';
68
- type CompletionProvider = 'openai' | 'groq';
83
+ type OpenAIModel = 'gpt-4o' | 'gpt-4o-mini';
84
+ type GroqModel = 'llama-3-70b';
85
+ type AnthropicModel = 'claude-3.5-sonnet' | 'claude-3-opus' | 'claude-3-haiku' | 'claude-3-sonnet';
86
+ type CompletionModel = OpenAIModel | GroqModel | AnthropicModel;
87
+ type CompletionProvider = 'openai' | 'groq' | 'anthropic';
69
88
  interface CompletionRequest {
70
89
  completionMetadata: CompletionMetadata;
71
90
  }
@@ -87,29 +106,26 @@ interface CompletionMetadata {
87
106
  }
88
107
 
89
108
  /**
90
- * Copilot class for handling completions using the API.
109
+ * Copilot class for handling completions using various AI providers.
91
110
  */
92
111
  declare class Copilot {
93
112
  private readonly apiKey;
94
- private readonly model;
95
113
  private readonly provider;
114
+ private readonly model;
115
+ private readonly headers;
96
116
  /**
97
117
  * Initializes the Copilot with an API key and optional configuration.
98
- * @param {string} apiKey - The API key.
99
- * @param {CopilotOptions<CompletionProvider>} [options] - Optional parameters to configure the completion model.
100
- * @throws {Error} If the API key is not provided.
118
+ * @param apiKey - The API key for the chosen provider.
119
+ * @param options - Options for configuring the Copilot instance.
101
120
  */
102
121
  constructor(apiKey: string, options?: CopilotOptions);
103
122
  /**
104
- * Sends a completion request to API and returns the completion.
105
- * @param {CompletionRequest} params - The metadata required to generate the completion.
106
- * @returns {Promise<CompletionResponse>} The completed text snippet or an error.
123
+ * Sends a completion request to the API and returns the completion.
124
+ * @param params - The metadata required to generate the completion.
125
+ * @returns A promise resolving to the completed text snippet or an error.
107
126
  */
108
127
  complete({ completionMetadata, }: CompletionRequest): Promise<CompletionResponse>;
109
- private getEndpoint;
110
- private getModelId;
111
- private createRequestBody;
112
- private createHeaders;
128
+ private validateInputs;
113
129
  }
114
130
 
115
131
  /**
package/build/index.js CHANGED
@@ -1,36 +1,38 @@
1
- "use strict";var N=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var ce=(o,e)=>{for(var t in e)N(o,t,{get:e[t],enumerable:!0})},de=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of me(e))!pe.call(o,n)&&n!==t&&N(o,n,{get:()=>e[n],enumerable:!(r=ae(e,n))||r.enumerable});return o};var ue=o=>de(N({},"__esModule",{value:!0}),o);var Me={};ce(Me,{Copilot:()=>I,registerCopilot:()=>ie});module.exports=ue(Me);var k={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini"},w={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"]},F="llama-3-70b",H="groq",U={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions"},q={temperature:.3};var V=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var f=class f{static getInstance(){return f.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logError(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}styleMessage(e,t){let r=this.getTimestamp(),n="Please create an issue on GitHub if the issue persists.",i=80,a="\u2500".repeat(i-2),s=`\u250C${a}\u2510`,l=`\u2514${a}\u2518`,m=((C,se)=>{let le=C.split(" "),A=[],g="";return le.forEach(B=>{(g+B).length>se&&(A.push(g.trim()),g=""),g+=B+" "}),g.trim()&&A.push(g.trim()),A})(e,i-4),p=[s,...m.map(C=>`\u2502 ${C.padEnd(i-4)} \u2502`),l].join(`
1
+ "use strict";var S=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var fe=Object.prototype.hasOwnProperty;var Ee=(o,e)=>{for(var t in e)S(o,t,{get:e[t],enumerable:!0})},Te=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of he(e))!fe.call(o,n)&&n!==t&&S(o,n,{get:()=>e[n],enumerable:!(r=ge(e,n))||r.enumerable});return o};var Pe=o=>Te(S({},"__esModule",{value:!0}),o);var Se={};Ee(Se,{Copilot:()=>b,registerCopilot:()=>de});module.exports=Pe(Se);var U={"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"},k={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},D="llama-3-70b",P="groq",V={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},j=.3;var W=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var x=class o{constructor(){}static getInstance(){return o.instance||(o.instance=new o),o.instance}error(e,t){console.error(this.styleMessage(t.message,e,"error")),t.stack&&console.error(this.styleStackTrace(t.stack))}warn(e,t){console.warn(this.styleMessage(t,e,"warning"))}styleMessage(e,t,r){let n=this.getTimestamp(),i="Please create an issue on GitHub if the issue persists.",a=100,s="\u2500".repeat(a-2),l=`\u250C${s}\u2510`,m=`\u2514${s}\u2518`,c=((w,ue)=>{let Ce=w.split(" "),_=[],C="";return Ce.forEach(q=>{(C+q).length>ue&&(_.push(C.trim()),C=""),C+=q+" "}),C.trim()&&_.push(C.trim()),_})(e,a-4),T=[l,...c.map(w=>`\u2502 ${w.padEnd(a-4)} \u2502`),m].join(`
2
2
  `);return`
3
- \x1B[1m\x1B[37m[${r}]\x1B[0m \x1B[31m[${t}]\x1B[0m \x1B[2m${n}\x1B[0m
4
- ${p}
5
- `}logError(e,t){console.error(this.styleMessage(t.message,e))}getTimestamp(){return new Date().toISOString()}};f.instance=new f;var _=f;var d=(o,e)=>_.getInstance().handleError(o,e);var j=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},P=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var x=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],W=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),h=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),G=o=>{let e=o.split(`
6
- `);return e[e.length-1].length+1};var S=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),D=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var Y=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},Ce=(o,e)=>Y(o,"GET",e),ge=(o,e,t)=>Y(o,"POST",{...t,body:e}),M={GET:Ce,POST:ge};var K=(o,e)=>{let t=x(o,e);return!!t&&!V.has(t)},J=(o,e)=>{let t=W(o,e).trim(),r=h(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var y="<<CURSOR>>",X=o=>o==="javascript"?"latest JavaScript":o,z=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},Z=o=>{let e=X(o.language),t=z(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},he=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${P(o)}`:"",r=X(e);return`The code is written${r?` in ${r}`:""}${t}.`},Q=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,l=z(n),c=e?`the file named "${e}"`:"a larger project",m=`You are tasked with ${l} for a code snippet. The code is part of ${c}.
3
+ \x1B[1m\x1B[37m[${n}]\x1B[0m${r==="error"?"\x1B[31m":"\x1B[33m"} [${t}]\x1B[0m \x1B[2m${i}\x1B[0m
4
+ ${T}
5
+ `}styleStackTrace(e){return e.split(`
6
+ `).map((n,i)=>i===0?`\x1B[31m${n}\x1B[0m`:`\x1B[2m${n}\x1B[0m`).join(`
7
+ `)}getTimestamp(){return new Date().toISOString()}};var h=class h{constructor(){this.logger=x.getInstance()}static getInstance(){return h.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logger.error(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};h.instance=new h;var B=h;var d=(o,e)=>B.getInstance().handleError(o,e);var G={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var Y=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},y=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var M=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],K=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),g=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),X=o=>{let e=o.split(`
8
+ `);return e[e.length-1].length+1};var $=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),H=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var z=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},xe=(o,e)=>z(o,"GET",e),ye=(o,e,t)=>z(o,"POST",{...t,body:e}),R={GET:xe,POST:ye};var J=(o,e)=>{let t=M(o,e);return!!t&&!W.has(t)},Z=(o,e)=>{let t=K(o,e).trim(),r=g(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var I="<<CURSOR>>",Q=o=>o==="javascript"?"latest JavaScript":o,ee=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},oe=o=>{let e=Q(o.language),t=ee(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},Me=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${y(o)}`:"",r=Q(e);return`The code is written${r?` in ${r}`:""}${t}.`},te=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,l=ee(n),m=e?`the file named "${e}"`:"a larger project",p=`You are tasked with ${l} for a code snippet. The code is part of ${m}.
7
9
 
8
- `;return m+=he(r,t),m+=`
10
+ `;return p+=Me(r,t),p+=`
9
11
 
10
12
  Here are the details about how the completion should be generated:
11
- - The cursor position is marked with '${y}'.
13
+ - The cursor position is marked with '${I}'.
12
14
  - Your completion must start exactly at the cursor position.
13
15
  - Do not repeat any code that appears before or after the cursor.
14
16
  - Ensure your completion does not introduce any syntactical or logical errors.
15
- `,n==="fill-in-the-middle"?m+=` - If filling in the middle, replace '${y}' entirely with your completion.
16
- `:n==="completion"&&(m+=` - If completing the code, start from '${y}' and provide a logical continuation.
17
- `),m+=` - Optimize for readability and performance where possible.
17
+ `,n==="fill-in-the-middle"?p+=` - If filling in the middle, replace '${I}' entirely with your completion.
18
+ `:n==="completion"&&(p+=` - If completing the code, start from '${I}' and provide a logical continuation.
19
+ `),p+=` - Optimize for readability and performance where possible.
18
20
 
19
21
  Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
20
22
 
21
23
  Here's the code snippet for completion:
22
24
 
23
25
  <code>
24
- ${i}${y}${a}
25
- </code>`,s&&s.length>0&&(m+=`
26
+ ${i}${I}${a}
27
+ </code>`,s&&s.length>0&&(p+=`
26
28
 
27
29
  Additional context from related files:
28
30
 
29
- `,m+=s.map(p=>`// Path: ${p.path}
30
- ${p.content}
31
+ `,p+=s.map(c=>`// Path: ${c.path}
32
+ ${c.content}
31
33
  `).join(`
32
- `)),m.endsWith(".")?m:`${m}.`};var fe="application/json",ee=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await M.POST(e,{completionMetadata:Ee({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":fe},error:"Error while fetching completion item"});return s}catch(s){return s instanceof Error&&(s.message==="Cancelled"||s.name==="AbortError")||d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Ee=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=Te(e,t),s=S(e,t),l=D(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:l,editorState:{completionMode:a}}},Te=(o,e)=>{let t=S(o,e),r=D(o,e);return t&&r?"fill-in-the-middle":"completion"};var I=class{constructor(e,t){let{provider:r,model:n}=t||{};if(r&&!n)throw new Error("You must provide a model when setting a provider");if(n&&!r)throw new Error("You must provide a provider when setting a model");if(this.model=n||F,this.provider=r||H,!w[this.provider].includes(this.model))throw new Error(`Model ${this.model} is not supported by ${this.provider} provider. Supported models: ${P(w[this.provider])}`);if(!e)throw new Error(`Please provide ${this.provider} API key.`);this.apiKey=e}async complete({completionMetadata:e}){try{let t=this.createRequestBody(e),r=this.createHeaders(),n=this.getEndpoint(),i=await M.POST(n,t,{headers:r});if(!i.choices?.length)throw new Error("No completion choices received from API");return{completion:i.choices[0].message.content}}catch(t){return{error:d(t,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}getEndpoint(){return U[this.provider]}getModelId(){return k[this.model]}createRequestBody(e){return{...q,model:this.getModelId(),messages:[{role:"system",content:Z(e)},{role:"user",content:Q(e)}]}}createHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}};var R=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(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 t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
34
+ `)),p.endsWith(".")?p:`${p}.`};var re=(o,e,t)=>{let r=oe(o),n=te(o),a={model:Oe(e),temperature:j},s={openai:{messages:[{role:"system",content:r},{role:"user",content:n}]},groq:{messages:[{role:"system",content:r},{role:"user",content:n}]},anthropic:{system:r,messages:[{role:"user",content:n}],max_tokens:ve(e)}};return{...a,...s[t]}},ne=(o,e)=>{let t={"Content-Type":"application/json"},r={openai:{Authorization:`Bearer ${o}`},groq:{Authorization:`Bearer ${o}`},anthropic:{"x-api-key":o,"anthropic-version":"2023-06-01"}};return{...t,...r[e]}},ie=(o,e)=>{let r={openai:Re,groq:Ie,anthropic:be}[e];if(!r)throw new Error(`Unsupported provider: ${e}`);return r(o)},Re=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the openai response"},Ie=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the groq response"},be=o=>o.content?typeof o.content!="string"?{completion:null,error:"Completion content is not a string"}:{completion:o.content}:{completion:null,error:"No completion found in the anthropic response"},Oe=o=>U[o],se=o=>V[o],ve=o=>G[o]||4096;var b=class{constructor(e,t={}){this.validateInputs(e,t),this.apiKey=e,this.provider=t.provider??P,this.model=t.model??D,this.headers=t.headers??{}}async complete({completionMetadata:e}){try{let t=re(e,this.model,this.provider),r=se(this.provider),n=ne(this.apiKey,this.provider),i=await R.POST(r,t,{headers:{...this.headers,...n}});return ie(i,this.provider)}catch(t){return{error:d(t,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}validateInputs(e,t){if(!e)throw new Error(`Please provide ${this.provider??P} API key.`);let{provider:r,model:n}=t;if(r&&!n||!r&&n)throw new Error("Both provider and model must be specified together");let i=r??P,a=n??D;if(!k[i].includes(a)){let s=y(k[i]);throw new Error(`Model ${a} is not supported by ${i} provider. Supported models: ${s}`)}}};var O=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(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 t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
33
35
  `).slice(1,-1).join(`
34
36
  `);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
35
37
 
36
- `),this}build(){return this.formattedCompletion}};var b=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!K(this.cursorPosition,this.model)&&!J(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return h(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};L.MAX_CACHE_SIZE=10;var O=L;var te=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=G(o),a=x(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function oe(o){return R.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var Pe=300,re=j(ee,Pe),v=new O,xe=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{if(!new b(t,e).shouldProvideCompletions())return u([]);let s=v.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let l=re({...a,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{re.cancel()});let c=await l;if(c){let m=oe(c),p=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),C=te(m,p,t,e);return v.addCompletionCache({completion:m,range:C,textBeforeCursorInLine:h(t,e)}),i(),u([{insertText:m,range:C}])}}catch(l){if(l instanceof Error&&(l.message==="Cancelled"||l.name==="AbortError"))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},ne=xe;var E=new WeakMap,T=null,ie=(o,e,t)=>{T&&T.deregister();let r=[];E.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,l,c,m)=>{let p=E.get(e);if(p)return ne({monaco:o,model:s,position:l,token:m,isCompletionAccepted:p.isCompletionAccepted,onShowCompletion:()=>{p.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let l=E.get(e);if(!l)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;l.isCompletionVisible&&c?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),v.clearCompletionCache(),E.delete(e),T=null}};return T=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),E.delete(e),T=null}}}};0&&(module.exports={Copilot,registerCopilot});
38
+ `),this}build(){return this.formattedCompletion}};var v=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!J(this.cursorPosition,this.model)&&!Z(this.cursorPosition,this.model)}};var A=class A{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(A.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return g(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};A.MAX_CACHE_SIZE=10;var L=A;var Le="application/json",le=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await R.POST(e,{completionMetadata:Ae({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":Le},error:"Error while fetching completion item"});return s}catch(s){return d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},Ae=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=Ne(e,t),s=$(e,t),l=H(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:l,editorState:{completionMode:a}}},Ne=(o,e)=>{let t=$(o,e),r=H(o,e);return t&&r?"fill-in-the-middle":"completion"};var ae=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=X(o),a=M(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function pe(o){return O.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var we=300,ce=Y(le,we),N=new L,_e=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{if(!new v(t,e).shouldProvideCompletions())return u([]);let s=N.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let l=ce({...a,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{ce.cancel()});let m=await l;if(m){let p=pe(m),c=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),T=ae(p,c,t,e);return N.addCompletionCache({completion:p,range:T,textBeforeCursorInLine:g(t,e)}),i(),u([{insertText:p,range:T}])}}catch(l){if(typeof l=="string"&&(l==="Cancelled"||l==="AbortError")||l instanceof Error&&(l.message==="Cancelled"||l.name==="AbortError"))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},me=_e;var f=new WeakMap,E=null,de=(o,e,t)=>{E&&E.deregister();let r=[];f.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,l,m,p)=>{let c=f.get(e);if(c)return me({monaco:o,model:s,position:l,token:p,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let l=f.get(e);if(!l)return;let m=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;l.isCompletionVisible&&m?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),N.clearCompletionCache(),f.delete(e),E=null}};return E=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),f.delete(e),E=null}}}};0&&(module.exports={Copilot,registerCopilot});
package/build/index.mjs CHANGED
@@ -1,36 +1,38 @@
1
- var B={"llama-3-70b":"llama3-70b-8192","gpt-4o":"gpt-4o-2024-08-06","gpt-4o-mini":"gpt-4o-mini"},A={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"]},k="llama-3-70b",F="groq",H={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions"},U={temperature:.3};var q=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var f=class f{static getInstance(){return f.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logError(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}styleMessage(e,t){let r=this.getTimestamp(),n="Please create an issue on GitHub if the issue persists.",i=80,a="\u2500".repeat(i-2),s=`\u250C${a}\u2510`,l=`\u2514${a}\u2518`,m=((C,ne)=>{let ie=C.split(" "),v=[],g="";return ie.forEach($=>{(g+$).length>ne&&(v.push(g.trim()),g=""),g+=$+" "}),g.trim()&&v.push(g.trim()),v})(e,i-4),p=[s,...m.map(C=>`\u2502 ${C.padEnd(i-4)} \u2502`),l].join(`
1
+ var q={"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"},_={groq:["llama-3-70b"],openai:["gpt-4o","gpt-4o-mini"],anthropic:["claude-3.5-sonnet","claude-3-opus","claude-3-haiku","claude-3-sonnet"]},S="llama-3-70b",P="groq",U={groq:"https://api.groq.com/openai/v1/chat/completions",openai:"https://api.openai.com/v1/chat/completions",anthropic:"https://api.anthropic.com/v1/messages"},V=.3;var j=new Set(['"',"'","`","{","}","[","]","(",")",","," ",":","."]);var x=class o{constructor(){}static getInstance(){return o.instance||(o.instance=new o),o.instance}error(e,t){console.error(this.styleMessage(t.message,e,"error")),t.stack&&console.error(this.styleStackTrace(t.stack))}warn(e,t){console.warn(this.styleMessage(t,e,"warning"))}styleMessage(e,t,r){let n=this.getTimestamp(),i="Please create an issue on GitHub if the issue persists.",a=100,s="\u2500".repeat(a-2),l=`\u250C${s}\u2510`,m=`\u2514${s}\u2518`,c=((N,me)=>{let de=N.split(" "),w=[],C="";return de.forEach(F=>{(C+F).length>me&&(w.push(C.trim()),C=""),C+=F+" "}),C.trim()&&w.push(C.trim()),w})(e,a-4),T=[l,...c.map(N=>`\u2502 ${N.padEnd(a-4)} \u2502`),m].join(`
2
2
  `);return`
3
- \x1B[1m\x1B[37m[${r}]\x1B[0m \x1B[31m[${t}]\x1B[0m \x1B[2m${n}\x1B[0m
4
- ${p}
5
- `}logError(e,t){console.error(this.styleMessage(t.message,e))}getTimestamp(){return new Date().toISOString()}};f.instance=new f;var N=f;var d=(o,e)=>N.getInstance().handleError(o,e);var V=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},P=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var x=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],j=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),h=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),W=o=>{let e=o.split(`
6
- `);return e[e.length-1].length+1};var w=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),_=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var G=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},se=(o,e)=>G(o,"GET",e),le=(o,e,t)=>G(o,"POST",{...t,body:e}),M={GET:se,POST:le};var Y=(o,e)=>{let t=x(o,e);return!!t&&!q.has(t)},K=(o,e)=>{let t=j(o,e).trim(),r=h(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var y="<<CURSOR>>",J=o=>o==="javascript"?"latest JavaScript":o,X=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},z=o=>{let e=J(o.language),t=X(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},ae=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${P(o)}`:"",r=J(e);return`The code is written${r?` in ${r}`:""}${t}.`},Z=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,l=X(n),c=e?`the file named "${e}"`:"a larger project",m=`You are tasked with ${l} for a code snippet. The code is part of ${c}.
3
+ \x1B[1m\x1B[37m[${n}]\x1B[0m${r==="error"?"\x1B[31m":"\x1B[33m"} [${t}]\x1B[0m \x1B[2m${i}\x1B[0m
4
+ ${T}
5
+ `}styleStackTrace(e){return e.split(`
6
+ `).map((n,i)=>i===0?`\x1B[31m${n}\x1B[0m`:`\x1B[2m${n}\x1B[0m`).join(`
7
+ `)}getTimestamp(){return new Date().toISOString()}};var h=class h{constructor(){this.logger=x.getInstance()}static getInstance(){return h.instance}handleError(e,t){let r=this.getErrorDetails(e);return this.logger.error(t,r),r}getErrorDetails(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack,context:e.context}:{message:String(e),name:"UnknownError"}}};h.instance=new h;var k=h;var d=(o,e)=>k.getInstance().handleError(o,e);var W={"claude-3.5-sonnet":8192,"claude-3-opus":4096,"claude-3-haiku":4096,"claude-3-sonnet":4096};var G=(o,e)=>{let t=null,r=null,n=(...i)=>new Promise((a,s)=>{t&&(clearTimeout(t),r&&r("Cancelled")),r=s,t=setTimeout(()=>{a(o(...i)),r=null},e)});return n.cancel=()=>{t&&(clearTimeout(t),r&&r("Cancelled"),t=null,r=null)},n},y=o=>!o||o.length===0?"":o.length===1?o[0]:`${o.slice(0,-1).join(", ")} and ${o.slice(-1)}`;var M=(o,e)=>e.getLineContent(o.lineNumber)[o.column-1],Y=(o,e)=>e.getLineContent(o.lineNumber).slice(o.column-1),g=(o,e)=>e.getLineContent(o.lineNumber).slice(0,o.column-1),K=o=>{let e=o.split(`
8
+ `);return e[e.length-1].length+1};var D=(o,e)=>e.getValueInRange({startLineNumber:1,startColumn:1,endLineNumber:o.lineNumber,endColumn:o.column}),B=(o,e)=>e.getValueInRange({startLineNumber:o.lineNumber,startColumn:o.column,endLineNumber:e.getLineCount(),endColumn:e.getLineMaxColumn(e.getLineCount())});var X=async(o,e,t={})=>{let r={"Content-Type":"application/json",...t.headers},n=e==="POST"&&t.body?JSON.stringify(t.body):void 0,i=await fetch(o,{method:e,headers:r,body:n,signal:t.signal});if(!i.ok)throw new Error(`${t.error||"Network error"}: ${i.statusText}`);return i.json()},ue=(o,e)=>X(o,"GET",e),Ce=(o,e,t)=>X(o,"POST",{...t,body:e}),R={GET:ue,POST:Ce};var z=(o,e)=>{let t=M(o,e);return!!t&&!j.has(t)},J=(o,e)=>{let t=Y(o,e).trim(),r=g(o,e).trim();return o.column<=3&&(t!==""||r!=="")};var I="<<CURSOR>>",Z=o=>o==="javascript"?"latest JavaScript":o,Q=o=>{switch(o){case"fill-in-the-middle":return"filling in the middle of the code";case"completion":return"completing the code"}},ee=o=>{let e=Z(o.language),t=Q(o.editorState.completionMode),r=e?` ${e}`:"";return`You are an advanced AI coding assistant with expertise in ${t} for${r} programming. Your goal is to provide accurate, efficient, and context-aware code completions. Remember, your role is to act as an extension of the developer's thought process, providing intelligent and contextually appropriate code completions.`},ge=(o,e)=>{if(!o?.length&&!e)return"";let t=o?` using ${y(o)}`:"",r=Z(e);return`The code is written${r?` in ${r}`:""}${t}.`},oe=o=>{let{filename:e,language:t,technologies:r,editorState:{completionMode:n},textBeforeCursor:i,textAfterCursor:a,externalContext:s}=o,l=Q(n),m=e?`the file named "${e}"`:"a larger project",p=`You are tasked with ${l} for a code snippet. The code is part of ${m}.
7
9
 
8
- `;return m+=ae(r,t),m+=`
10
+ `;return p+=ge(r,t),p+=`
9
11
 
10
12
  Here are the details about how the completion should be generated:
11
- - The cursor position is marked with '${y}'.
13
+ - The cursor position is marked with '${I}'.
12
14
  - Your completion must start exactly at the cursor position.
13
15
  - Do not repeat any code that appears before or after the cursor.
14
16
  - Ensure your completion does not introduce any syntactical or logical errors.
15
- `,n==="fill-in-the-middle"?m+=` - If filling in the middle, replace '${y}' entirely with your completion.
16
- `:n==="completion"&&(m+=` - If completing the code, start from '${y}' and provide a logical continuation.
17
- `),m+=` - Optimize for readability and performance where possible.
17
+ `,n==="fill-in-the-middle"?p+=` - If filling in the middle, replace '${I}' entirely with your completion.
18
+ `:n==="completion"&&(p+=` - If completing the code, start from '${I}' and provide a logical continuation.
19
+ `),p+=` - Optimize for readability and performance where possible.
18
20
 
19
21
  Remember to output only the completion code without any additional explanation, and do not wrap it in markdown code syntax, such as three backticks (\`\`\`).
20
22
 
21
23
  Here's the code snippet for completion:
22
24
 
23
25
  <code>
24
- ${i}${y}${a}
25
- </code>`,s&&s.length>0&&(m+=`
26
+ ${i}${I}${a}
27
+ </code>`,s&&s.length>0&&(p+=`
26
28
 
27
29
  Additional context from related files:
28
30
 
29
- `,m+=s.map(p=>`// Path: ${p.path}
30
- ${p.content}
31
+ `,p+=s.map(c=>`// Path: ${c.path}
32
+ ${c.content}
31
33
  `).join(`
32
- `)),m.endsWith(".")?m:`${m}.`};var me="application/json",Q=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await M.POST(e,{completionMetadata:pe({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":me},error:"Error while fetching completion item"});return s}catch(s){return s instanceof Error&&(s.message==="Cancelled"||s.name==="AbortError")||d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},pe=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=ce(e,t),s=w(e,t),l=_(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:l,editorState:{completionMode:a}}},ce=(o,e)=>{let t=w(o,e),r=_(o,e);return t&&r?"fill-in-the-middle":"completion"};var D=class{constructor(e,t){let{provider:r,model:n}=t||{};if(r&&!n)throw new Error("You must provide a model when setting a provider");if(n&&!r)throw new Error("You must provide a provider when setting a model");if(this.model=n||k,this.provider=r||F,!A[this.provider].includes(this.model))throw new Error(`Model ${this.model} is not supported by ${this.provider} provider. Supported models: ${P(A[this.provider])}`);if(!e)throw new Error(`Please provide ${this.provider} API key.`);this.apiKey=e}async complete({completionMetadata:e}){try{let t=this.createRequestBody(e),r=this.createHeaders(),n=this.getEndpoint(),i=await M.POST(n,t,{headers:r});if(!i.choices?.length)throw new Error("No completion choices received from API");return{completion:i.choices[0].message.content}}catch(t){return{error:d(t,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}getEndpoint(){return H[this.provider]}getModelId(){return B[this.model]}createRequestBody(e){return{...U,model:this.getModelId(),messages:[{role:"system",content:z(e)},{role:"user",content:Z(e)}]}}createHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"}}};var I=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(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 t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
34
+ `)),p.endsWith(".")?p:`${p}.`};var te=(o,e,t)=>{let r=ee(o),n=oe(o),a={model:Te(e),temperature:V},s={openai:{messages:[{role:"system",content:r},{role:"user",content:n}]},groq:{messages:[{role:"system",content:r},{role:"user",content:n}]},anthropic:{system:r,messages:[{role:"user",content:n}],max_tokens:Pe(e)}};return{...a,...s[t]}},re=(o,e)=>{let t={"Content-Type":"application/json"},r={openai:{Authorization:`Bearer ${o}`},groq:{Authorization:`Bearer ${o}`},anthropic:{"x-api-key":o,"anthropic-version":"2023-06-01"}};return{...t,...r[e]}},ne=(o,e)=>{let r={openai:he,groq:fe,anthropic:Ee}[e];if(!r)throw new Error(`Unsupported provider: ${e}`);return r(o)},he=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the openai response"},fe=o=>o.choices?.length?{completion:o.choices[0].message.content}:{completion:null,error:"No completion found in the groq response"},Ee=o=>o.content?typeof o.content!="string"?{completion:null,error:"Completion content is not a string"}:{completion:o.content}:{completion:null,error:"No completion found in the anthropic response"},Te=o=>q[o],ie=o=>U[o],Pe=o=>W[o]||4096;var $=class{constructor(e,t={}){this.validateInputs(e,t),this.apiKey=e,this.provider=t.provider??P,this.model=t.model??S,this.headers=t.headers??{}}async complete({completionMetadata:e}){try{let t=te(e,this.model,this.provider),r=ie(this.provider),n=re(this.apiKey,this.provider),i=await R.POST(r,t,{headers:{...this.headers,...n}});return ne(i,this.provider)}catch(t){return{error:d(t,"COPILOT_COMPLETION_FETCH_ERROR").message,completion:null}}}validateInputs(e,t){if(!e)throw new Error(`Please provide ${this.provider??P} API key.`);let{provider:r,model:n}=t;if(r&&!n||!r&&n)throw new Error("Both provider and model must be specified together");let i=r??P,a=n??S;if(!_[i].includes(a)){let s=y(_[i]);throw new Error(`Model ${a} is not supported by ${i} provider. Supported models: ${s}`)}}};var b=class o{constructor(e){this.formattedCompletion="";this.formattedCompletion=e}static create(e){return new o(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 t=/```[\s\S]*?```/g,r=e,n;for(;(n=t.exec(e))!==null;){let i=n[0],a=i.split(`
33
35
  `).slice(1,-1).join(`
34
36
  `);r=r.replace(i,a)}return r.trim()}removeExcessiveNewlines(){return this.formattedCompletion=this.formattedCompletion.replace(/\n{3,}/g,`
35
37
 
36
- `),this}build(){return this.formattedCompletion}};var R=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!Y(this.cursorPosition,this.model)&&!K(this.cursorPosition,this.model)}};var O=class O{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(O.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return h(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};O.MAX_CACHE_SIZE=10;var b=O;var ee=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=W(o),a=x(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function te(o){return I.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var de=300,oe=V(Q,de),L=new b,ue=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{if(!new R(t,e).shouldProvideCompletions())return u([]);let s=L.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let l=oe({...a,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{oe.cancel()});let c=await l;if(c){let m=te(c),p=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),C=ee(m,p,t,e);return L.addCompletionCache({completion:m,range:C,textBeforeCursorInLine:h(t,e)}),i(),u([{insertText:m,range:C}])}}catch(l){if(l instanceof Error&&(l.message==="Cancelled"||l.name==="AbortError"))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},re=ue;var E=new WeakMap,T=null,Ce=(o,e,t)=>{T&&T.deregister();let r=[];E.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,l,c,m)=>{let p=E.get(e);if(p)return re({monaco:o,model:s,position:l,token:m,isCompletionAccepted:p.isCompletionAccepted,onShowCompletion:()=>{p.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let l=E.get(e);if(!l)return;let c=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;l.isCompletionVisible&&c?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),L.clearCompletionCache(),E.delete(e),T=null}};return T=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),E.delete(e),T=null}}}};export{D as Copilot,Ce as registerCopilot};
38
+ `),this}build(){return this.formattedCompletion}};var O=class{constructor(e,t){this.cursorPosition=e,this.model=t}shouldProvideCompletions(){return!z(this.cursorPosition,this.model)&&!J(this.cursorPosition,this.model)}};var L=class L{constructor(){this.cache=[]}getCompletionCache(e,t){return this.cache.filter(r=>this.isCacheItemValid(r,e,t))}addCompletionCache(e){this.cache=[...this.cache.slice(-(L.MAX_CACHE_SIZE-1)),e]}clearCompletionCache(){this.cache=[]}isCacheItemValid(e,t,r){let n=r.getValueInRange(e.range);return g(t,r).startsWith(e.textBeforeCursorInLine)&&this.isPositionValid(e,t,n)}isPositionValid(e,t,r){return e.range.startLineNumber===t.lineNumber&&t.column===e.range.startColumn||e.completion.startsWith(r)&&e.range.startLineNumber===t.lineNumber&&t.column>=e.range.startColumn-r.length&&t.column<=e.range.endColumn}};L.MAX_CACHE_SIZE=10;var v=L;var xe="application/json",se=async({filename:o,endpoint:e,language:t,technologies:r,externalContext:n,model:i,position:a})=>{try{let{completion:s}=await R.POST(e,{completionMetadata:ye({filename:o,position:a,model:i,language:t,technologies:r,externalContext:n})},{headers:{"Content-Type":xe},error:"Error while fetching completion item"});return s}catch(s){return d(s,"FETCH_COMPLETION_ITEM_ERROR"),null}},ye=({filename:o,position:e,model:t,language:r,technologies:n,externalContext:i})=>{let a=Me(e,t),s=D(e,t),l=B(e,t);return{filename:o,language:r,technologies:n,externalContext:i,textBeforeCursor:s,textAfterCursor:l,editorState:{completionMode:a}}},Me=(o,e)=>{let t=D(o,e),r=B(o,e);return t&&r?"fill-in-the-middle":"completion"};var le=(o,e,t,r)=>{let n=(o.match(/\n/g)||[]).length,i=K(o),a=M(t,r);return{startLineNumber:t.lineNumber,startColumn:t.column,endLineNumber:t.lineNumber+n,endColumn:o.includes(a)?t.lineNumber===e.startLineNumber&&n===0?t.column+(i-1):i:t.column}};function ae(o){return b.create(o).removeMarkdownCodeSyntax().removeExcessiveNewlines().removeInvalidLineBreaks().build()}var u=o=>({items:o,enableForwardStability:!0});var Re=300,pe=G(se,Re),A=new v,Ie=async({monaco:o,model:e,position:t,token:r,isCompletionAccepted:n,onShowCompletion:i,options:a})=>{if(!new O(t,e).shouldProvideCompletions())return u([]);let s=A.getCompletionCache(t,e).map(l=>({insertText:l.completion,range:l.range}));if(s.length)return i(),u(s);if(r.isCancellationRequested||n)return u([]);try{let l=pe({...a,text:e.getValue(),model:e,position:t});r.onCancellationRequested(()=>{pe.cancel()});let m=await l;if(m){let p=ae(m),c=new o.Range(t.lineNumber,t.column,t.lineNumber,t.column),T=le(p,c,t,e);return A.addCompletionCache({completion:p,range:T,textBeforeCursorInLine:g(t,e)}),i(),u([{insertText:p,range:T}])}}catch(l){if(typeof l=="string"&&(l==="Cancelled"||l==="AbortError")||l instanceof Error&&(l.message==="Cancelled"||l.name==="AbortError"))return u([]);d(l,"FETCH_COMPLETION_ITEM_ERROR")}return u([])},ce=Ie;var f=new WeakMap,E=null,be=(o,e,t)=>{E&&E.deregister();let r=[];f.set(e,{isCompletionAccepted:!1,isCompletionVisible:!1});try{let n=o.languages.registerInlineCompletionsProvider(t.language,{provideInlineCompletions:(s,l,m,p)=>{let c=f.get(e);if(c)return ce({monaco:o,model:s,position:l,token:p,isCompletionAccepted:c.isCompletionAccepted,onShowCompletion:()=>{c.isCompletionVisible=!0},options:t})},freeInlineCompletions:()=>{}});r.push(n);let i=e.onKeyDown(s=>{let l=f.get(e);if(!l)return;let m=s.keyCode===o.KeyCode.Tab||s.keyCode===o.KeyCode.RightArrow&&s.metaKey;l.isCompletionVisible&&m?(l.isCompletionAccepted=!0,l.isCompletionVisible=!1):l.isCompletionAccepted=!1});r.push(i);let a={deregister:()=>{r.forEach(s=>s.dispose()),A.clearCompletionCache(),f.delete(e),E=null}};return E=a,a}catch(n){return d(n,"REGISTER_COPILOT_ERROR"),{deregister:()=>{r.forEach(i=>i.dispose()),f.delete(e),E=null}}}};export{$ as Copilot,be as registerCopilot};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monacopilot",
3
- "version": "0.9.19",
3
+ "version": "0.9.20",
4
4
  "description": "AI auto-completion plugin for Monaco Editor",
5
5
  "main": "./build/index.js",
6
6
  "module": "./build/index.mjs",
@@ -17,10 +17,11 @@
17
17
  "lint": "eslint . --ext .ts,.tsx --fix",
18
18
  "lint:test-ui": "pnpm -C tests/ui lint",
19
19
  "format": "prettier --write .",
20
- "pre-commit": "pnpm format && pnpm type-check && pnpm lint && pnpm lint:test-ui",
20
+ "pre-commit": "pnpm build && pnpm format && pnpm type-check && pnpm lint && pnpm lint:test-ui",
21
21
  "release": "release-it"
22
22
  },
23
23
  "devDependencies": {
24
+ "@anthropic-ai/sdk": "^0.27.1",
24
25
  "@ianvs/prettier-plugin-sort-imports": "^4.2.1",
25
26
  "@typescript-eslint/eslint-plugin": "^7.3.1",
26
27
  "eslint": "^8.57.0",