|
@@ -1,7 +1,10 @@
|
|
|
+const { PassThrough } = require('stream');
|
|
|
const APIError = require('../../api/APIError');
|
|
|
const BaseService = require('../../services/BaseService');
|
|
|
+const { TypedValue } = require('../../services/drivers/meta/Runtime');
|
|
|
const { Context } = require('../../util/context');
|
|
|
const SmolUtil = require('../../util/smolutil');
|
|
|
+const { nou } = require('../../util/langutil');
|
|
|
|
|
|
class OpenAICompletionService extends BaseService {
|
|
|
static MODULES = {
|
|
@@ -20,7 +23,7 @@ class OpenAICompletionService extends BaseService {
|
|
|
|
|
|
static IMPLEMENTS = {
|
|
|
['puter-chat-completion']: {
|
|
|
- async complete ({ messages, test_mode }) {
|
|
|
+ async complete ({ messages, test_mode, stream }) {
|
|
|
if ( test_mode ) {
|
|
|
const { LoremIpsum } = require('lorem-ipsum');
|
|
|
const li = new LoremIpsum({
|
|
@@ -50,6 +53,7 @@ class OpenAICompletionService extends BaseService {
|
|
|
return await this.complete(messages, {
|
|
|
model,
|
|
|
moderation: true,
|
|
|
+ stream,
|
|
|
});
|
|
|
}
|
|
|
}
|
|
@@ -76,7 +80,7 @@ class OpenAICompletionService extends BaseService {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- async complete (messages, { moderation, model }) {
|
|
|
+ async complete (messages, { stream, moderation, model }) {
|
|
|
// Validate messages
|
|
|
if ( ! Array.isArray(messages) ) {
|
|
|
throw new Error('`messages` must be an array');
|
|
@@ -199,7 +203,35 @@ class OpenAICompletionService extends BaseService {
|
|
|
messages: messages,
|
|
|
model: model,
|
|
|
max_tokens,
|
|
|
+ stream,
|
|
|
});
|
|
|
+
|
|
|
+ if ( stream ) {
|
|
|
+ const entire = [];
|
|
|
+ const stream = new PassThrough();
|
|
|
+ const retval = new TypedValue({
|
|
|
+ $: 'stream',
|
|
|
+ content_type: 'application/x-ndjson',
|
|
|
+ chunked: true,
|
|
|
+ }, stream);
|
|
|
+ (async () => {
|
|
|
+ for await ( const chunk of completion ) {
|
|
|
+ entire.push(chunk);
|
|
|
+ if ( chunk.choices.length < 1 ) continue;
|
|
|
+ if ( chunk.choices[0].finish_reason ) {
|
|
|
+ stream.end();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if ( nou(chunk.choices[0].delta.content) ) continue;
|
|
|
+ const str = JSON.stringify({
|
|
|
+ text: chunk.choices[0].delta.content
|
|
|
+ });
|
|
|
+ stream.write(str + '\n');
|
|
|
+ }
|
|
|
+ })();
|
|
|
+ return retval;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
this.log.info('how many choices?: ' + completion.choices.length);
|
|
|
|
|
@@ -244,7 +276,7 @@ class OpenAICompletionService extends BaseService {
|
|
|
throw new Error('message is not allowed');
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return completion.choices[0];
|
|
|
}
|
|
|
}
|