feat(ai): add xAI grok-beta

This commit is contained in:
KernelDeimos 2024-11-07 15:01:13 -05:00
parent d613c5fc83
commit 28adcf533f
3 changed files with 124 additions and 0 deletions

View File

@ -48,6 +48,11 @@ class PuterAIModule extends AdvancedBase {
const { GroqAIService } = require('./GroqAIService');
services.registerService('groq', GroqAIService);
}
if ( !! config?.services?.['xai'] ) {
const { XAIService } = require('./XAIService');
services.registerService('xai', XAIService);
}
}
}

View File

@ -0,0 +1,117 @@
const { default: Anthropic } = require("@anthropic-ai/sdk");
const BaseService = require("../../services/BaseService");
const { whatis } = require("../../util/langutil");
const { PassThrough } = require("stream");
const { TypedValue } = require("../../services/drivers/meta/Runtime");
const PUTER_PROMPT = `
You are running on an open-source platform called Puter,
as the xAI implementation for a driver interface
called puter-chat-completion.
The following JSON contains system messages from the
user of the driver interface (typically an app on Puter):
`.replace('\n', ' ').trim();
class XAIService extends BaseService {
static MODULES = {
Anthropic: require('@anthropic-ai/sdk'),
}
async _init () {
this.anthropic = new Anthropic({
apiKey: this.config.apiKey,
baseURL: 'https://api.x.ai'
});
}
static IMPLEMENTS = {
['puter-chat-completion']: {
async list () {
return [
'grok-beta',
];
},
async complete ({ messages, stream, model }) {
const adapted_messages = [];
const system_prompts = [];
let previous_was_user = false;
for ( const message of messages ) {
if ( typeof message.content === 'string' ) {
message.content = {
type: 'text',
text: message.content,
};
}
if ( whatis(message.content) !== 'array' ) {
message.content = [message.content];
}
if ( ! message.role ) message.role = 'user';
if ( message.role === 'user' && previous_was_user ) {
const last_msg = adapted_messages[adapted_messages.length-1];
last_msg.content.push(
...(Array.isArray ? message.content : [message.content])
);
continue;
}
if ( message.role === 'system' ) {
system_prompts.push(...message.content);
continue;
}
adapted_messages.push(message);
if ( message.role === 'user' ) {
previous_was_user = true;
}
}
if ( stream ) {
const stream = new PassThrough();
const retval = new TypedValue({
$: 'stream',
content_type: 'application/x-ndjson',
chunked: true,
}, stream);
(async () => {
const completion = await this.anthropic.messages.stream({
model: model ?? 'grok-beta',
max_tokens: 1000,
temperature: 0,
system: PUTER_PROMPT + JSON.stringify(system_prompts),
messages: adapted_messages,
});
for await ( const event of completion ) {
if (
event.type !== 'content_block_delta' ||
event.delta.type !== 'text_delta'
) continue;
const str = JSON.stringify({
text: event.delta.text,
});
stream.write(str + '\n');
}
stream.end();
})();
return retval;
}
const msg = await this.anthropic.messages.create({
model: model ?? 'grok-beta',
max_tokens: 1000,
temperature: 0,
system: PUTER_PROMPT + JSON.stringify(system_prompts),
messages: adapted_messages,
});
return {
message: msg,
finish_reason: 'stop'
};
}
}
}
}
module.exports = {
XAIService,
};

View File

@ -267,6 +267,8 @@ class AI{
"whisper-large-v3"
].includes(options.model)) {
driver = 'groq';
}else if(options.model === 'grok-beta') {
driver = 'xai';
}
// stream flag from settings