@@ -2,6 +2,7 @@ import { streamSse } from "@continuedev/fetch";
2
2
import { ChatMessage , CompletionOptions , LLMOptions } from "../../index.js" ;
3
3
4
4
import { ChatCompletionCreateParams } from "@continuedev/openai-adapters" ;
5
+ import { APPLY_UNIQUE_TOKEN } from "../../edit/constants.js" ;
5
6
import { UNIQUE_TOKEN } from "../../nextEdit/constants.js" ;
6
7
import OpenAI from "./OpenAI.js" ;
7
8
@@ -96,40 +97,21 @@ class Inception extends OpenAI {
96
97
options : CompletionOptions ,
97
98
) : AsyncGenerator < ChatMessage > {
98
99
if ( this . isNextEdit ( messages ) ) {
99
- messages = this . removeNextEditToken ( messages ) ;
100
-
101
- // Use edit/completions endpoint.
102
- const endpoint = new URL ( "edit/completions" , this . apiBase ) ;
103
-
104
- const resp = await this . fetch ( endpoint , {
105
- method : "POST" ,
106
- body : JSON . stringify ( {
107
- model : options . model ,
108
- messages : messages ,
109
- max_tokens : options . maxTokens ,
110
- temperature : options . temperature ,
111
- top_p : options . topP ,
112
- frequency_penalty : options . frequencyPenalty ,
113
- presence_penalty : options . presencePenalty ,
114
- stop : options . stop ,
115
- stream : true ,
116
- } ) ,
117
- headers : {
118
- "Content-Type" : "application/json" ,
119
- Accept : "application/json" ,
120
- Authorization : `Bearer ${ this . apiKey } ` ,
121
- } ,
100
+ messages = this . removeToken ( messages , UNIQUE_TOKEN ) ;
101
+ yield * this . streamSpecialEndpoint (
102
+ "edit/completions" ,
103
+ messages ,
122
104
signal ,
123
- } ) ;
124
-
125
- for await ( const chunk of streamSse ( resp ) ) {
126
- if ( chunk . choices ?. [ 0 ] ?. delta ?. content ) {
127
- yield {
128
- role : "assistant ",
129
- content : chunk . choices [ 0 ] . delta . content ,
130
- } ;
131
- }
132
- }
105
+ options ,
106
+ ) ;
107
+ } else if ( this . isApply ( messages ) ) {
108
+ messages = this . removeToken ( messages , APPLY_UNIQUE_TOKEN ) ;
109
+ yield * this . streamSpecialEndpoint (
110
+ "apply/completions ",
111
+ messages ,
112
+ signal ,
113
+ options ,
114
+ ) ;
133
115
} else {
134
116
// Use regular chat/completions endpoint - call parent OpenAI implementation.
135
117
yield * super . _streamChat ( messages , signal , options ) ;
@@ -145,23 +127,68 @@ class Inception extends OpenAI {
145
127
) ;
146
128
}
147
129
148
- private removeNextEditToken ( messages : ChatMessage [ ] ) : ChatMessage [ ] {
130
+ private isApply ( messages : ChatMessage [ ] ) : boolean {
131
+ return messages . some (
132
+ ( message ) =>
133
+ typeof message . content === "string" &&
134
+ message . content . endsWith ( APPLY_UNIQUE_TOKEN ) ,
135
+ ) ;
136
+ }
137
+
138
+ private removeToken ( messages : ChatMessage [ ] , token : string ) : ChatMessage [ ] {
149
139
const lastMessage = messages [ messages . length - 1 ] ;
150
140
151
141
if (
152
142
typeof lastMessage ?. content === "string" &&
153
- lastMessage . content . endsWith ( UNIQUE_TOKEN )
143
+ lastMessage . content . endsWith ( token )
154
144
) {
155
145
const cleanedMessages = [ ...messages ] ;
156
146
cleanedMessages [ cleanedMessages . length - 1 ] = {
157
147
...lastMessage ,
158
- content : lastMessage . content . slice ( 0 , - UNIQUE_TOKEN . length ) ,
148
+ content : lastMessage . content . slice ( 0 , - token . length ) ,
159
149
} ;
160
150
return cleanedMessages ;
161
151
}
162
152
163
153
return messages ;
164
154
}
155
+
156
+ private async * streamSpecialEndpoint (
157
+ path : string ,
158
+ messages : ChatMessage [ ] ,
159
+ signal : AbortSignal ,
160
+ options : CompletionOptions ,
161
+ ) : AsyncGenerator < ChatMessage > {
162
+ const endpoint = new URL ( path , this . apiBase ) ;
163
+
164
+ const resp = await this . fetch ( endpoint , {
165
+ method : "POST" ,
166
+ body : JSON . stringify ( {
167
+ model : options . model ,
168
+ messages,
169
+ max_tokens : options . maxTokens ,
170
+ temperature : options . temperature ,
171
+ top_p : options . topP ,
172
+ frequency_penalty : options . frequencyPenalty ,
173
+ presence_penalty : options . presencePenalty ,
174
+ stop : options . stop ,
175
+ stream : true ,
176
+ } ) ,
177
+ headers : {
178
+ "Content-Type" : "application/json" ,
179
+ Accept : "application/json" ,
180
+ Authorization : `Bearer ${ this . apiKey } ` ,
181
+ } ,
182
+ signal,
183
+ } ) ;
184
+
185
+ for await ( const chunk of streamSse ( resp ) ) {
186
+ const content = chunk . choices ?. [ 0 ] ?. delta ?. content ;
187
+ if ( content ) {
188
+ yield { role : "assistant" , content } ;
189
+ }
190
+ }
191
+ }
165
192
}
166
193
167
194
export default Inception ;
0 commit comments