mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-29 21:01:27 +00:00
Add support for multiple AI drivers via puter.js
This commit is contained in:
@@ -181,9 +181,10 @@ class Valid {
|
||||
* Makes the hybrid promise/callback function for a particular driver method
|
||||
* @param {string[]} arg_defs - argument names (for now; definitions eventually)
|
||||
* @param {string} driverInterface - name of the interface
|
||||
* @param {string} driverName - name of the driver
|
||||
* @param {string} driverMethod - name of the method
|
||||
*/
|
||||
function make_driver_method(arg_defs, driverInterface, driverMethod, settings = {}) {
|
||||
function make_driver_method(arg_defs, driverInterface, driverName, driverMethod, settings = {}) {
|
||||
return async function (...args) {
|
||||
let driverArgs = {};
|
||||
let options = {};
|
||||
@@ -214,11 +215,11 @@ function make_driver_method(arg_defs, driverInterface, driverMethod, settings =
|
||||
driverArgs = settings.preprocess(driverArgs);
|
||||
}
|
||||
|
||||
return await driverCall(options, driverInterface, driverMethod, driverArgs, settings);
|
||||
return await driverCall(options, driverInterface, driverName, driverMethod, driverArgs, settings);
|
||||
};
|
||||
}
|
||||
|
||||
async function driverCall (options, driverInterface, driverMethod, driverArgs, settings) {
|
||||
async function driverCall (options, driverInterface, driverName, driverMethod, driverArgs, settings) {
|
||||
const tp = new TeePromise();
|
||||
|
||||
driverCall_(
|
||||
@@ -226,6 +227,7 @@ async function driverCall (options, driverInterface, driverMethod, driverArgs, s
|
||||
tp.resolve.bind(tp),
|
||||
tp.reject.bind(tp),
|
||||
driverInterface,
|
||||
driverName,
|
||||
driverMethod,
|
||||
driverArgs,
|
||||
undefined,
|
||||
@@ -240,7 +242,7 @@ async function driverCall (options, driverInterface, driverMethod, driverArgs, s
|
||||
async function driverCall_(
|
||||
options = {},
|
||||
resolve_func, reject_func,
|
||||
driverInterface, driverMethod, driverArgs,
|
||||
driverInterface, driverName, driverMethod, driverArgs,
|
||||
method,
|
||||
contentType = 'application/json;charset=UTF-8',
|
||||
settings = {},
|
||||
@@ -342,6 +344,7 @@ async function driverCall_(
|
||||
// send request
|
||||
xhr.send(JSON.stringify({
|
||||
interface: driverInterface,
|
||||
driver: driverName,
|
||||
test_mode: settings?.test_mode,
|
||||
method: driverMethod,
|
||||
args: driverArgs,
|
||||
|
||||
@@ -69,7 +69,7 @@ class AI{
|
||||
testMode = true;
|
||||
}
|
||||
|
||||
return await utils.make_driver_method(['source'], 'puter-ocr', 'recognize', {
|
||||
return await utils.make_driver_method(['source'], 'puter-ocr', 'aws-textract', 'recognize', {
|
||||
test_mode: testMode ?? false,
|
||||
transform: async (result) => {
|
||||
let str = '';
|
||||
@@ -113,7 +113,7 @@ class AI{
|
||||
testMode = true;
|
||||
}
|
||||
|
||||
return await utils.make_driver_method(['source'], 'puter-tts', 'synthesize', {
|
||||
return await utils.make_driver_method(['source'], 'puter-tts', 'aws-polly', 'synthesize', {
|
||||
responseType: 'blob',
|
||||
test_mode: testMode ?? false,
|
||||
transform: async (result) => {
|
||||
@@ -132,8 +132,12 @@ class AI{
|
||||
// if object, it's treated as the full argument object that the API expects
|
||||
chat = async (...args) => {
|
||||
let options = {};
|
||||
let settings = {};
|
||||
let testMode = false;
|
||||
|
||||
// default driver is openai-completion
|
||||
let driver = 'openai-completion';
|
||||
|
||||
// Check that the argument is not undefined or null
|
||||
if(!args){
|
||||
throw({message: 'Arguments are required', code: 'arguments_required'});
|
||||
@@ -199,8 +203,35 @@ class AI{
|
||||
testMode = true;
|
||||
}
|
||||
|
||||
// if any of the args is an object, assume it's the settings object
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (typeof args[i] === 'object') {
|
||||
settings = args[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// does settings contain `model`? add it to options
|
||||
if (settings.model) {
|
||||
options.model = settings.model;
|
||||
}
|
||||
|
||||
// convert to the correct model name if necessary
|
||||
if( options.model === 'claude-3-5-sonnet' || options.model === 'claude'){
|
||||
options.model = 'claude-3-5-sonnet-20240620';
|
||||
}
|
||||
|
||||
// map model to the appropriate driver
|
||||
if (!options.model || options.model === 'gpt-4o' || options.model === 'gpt-4o-mini') {
|
||||
driver = 'openai-completion';
|
||||
}else if(options.model === 'claude-3-haiku-20240307' || options.model === 'claude-3-5-sonnet-20240620'){
|
||||
driver = 'claude';
|
||||
}else if(options.model === 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo' || options.model === 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo' || options.model === 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo' || options.model === `google/gemma-2-27b-it`){
|
||||
driver = 'together-ai';
|
||||
}
|
||||
|
||||
// Call the original chat.complete method
|
||||
return await utils.make_driver_method(['messages'], 'puter-chat-completion', 'complete', {
|
||||
return await utils.make_driver_method(['messages'], 'puter-chat-completion', driver, 'complete', {
|
||||
test_mode: testMode ?? false,
|
||||
transform: async (result) => {
|
||||
result.toString = () => {
|
||||
@@ -235,7 +266,7 @@ class AI{
|
||||
}
|
||||
|
||||
// Call the original chat.complete method
|
||||
return await utils.make_driver_method(['prompt'], 'puter-image-generation', 'generate', {
|
||||
return await utils.make_driver_method(['prompt'], 'puter-image-generation', undefined, 'generate', {
|
||||
responseType: 'blob',
|
||||
test_mode: testMode ?? false,
|
||||
transform: async blob => {
|
||||
|
||||
@@ -42,7 +42,7 @@ class Apps{
|
||||
|
||||
options = { "predicate": ['user-can-edit'] };
|
||||
|
||||
return utils.make_driver_method(['uid'], 'puter-apps', 'select').call(this, options);
|
||||
return utils.make_driver_method(['uid'], 'puter-apps', undefined, 'select').call(this, options);
|
||||
}
|
||||
|
||||
create = async (...args) => {
|
||||
@@ -70,7 +70,7 @@ class Apps{
|
||||
};
|
||||
}
|
||||
// Call the original chat.complete method
|
||||
return await utils.make_driver_method(['object'], 'puter-apps', 'create').call(this, options);
|
||||
return await utils.make_driver_method(['object'], 'puter-apps', undefined, 'create').call(this, options);
|
||||
}
|
||||
|
||||
update = async(...args) => {
|
||||
@@ -96,7 +96,7 @@ class Apps{
|
||||
}
|
||||
|
||||
// Call the original chat.complete method
|
||||
return await utils.make_driver_method(['object'], 'puter-apps', 'update').call(this, options);
|
||||
return await utils.make_driver_method(['object'], 'puter-apps', undefined, 'update').call(this, options);
|
||||
}
|
||||
|
||||
get = async(...args) => {
|
||||
@@ -106,7 +106,7 @@ class Apps{
|
||||
if (Array.isArray(args) && typeof args[0] === 'string') {
|
||||
options = { id: {name: args[0]}};
|
||||
}
|
||||
return utils.make_driver_method(['uid'], 'puter-apps', 'read').call(this, options);
|
||||
return utils.make_driver_method(['uid'], 'puter-apps', undefined, 'read').call(this, options);
|
||||
}
|
||||
|
||||
delete = async(...args) => {
|
||||
@@ -116,7 +116,7 @@ class Apps{
|
||||
if (Array.isArray(args) && typeof args[0] === 'string') {
|
||||
options = { id: {name: args[0]}};
|
||||
}
|
||||
return utils.make_driver_method(['uid'], 'puter-apps', 'delete').call(this, options);
|
||||
return utils.make_driver_method(['uid'], 'puter-apps', undefined, 'delete').call(this, options);
|
||||
}
|
||||
|
||||
getDeveloperProfile = function(...args){
|
||||
|
||||
@@ -39,7 +39,7 @@ class Hosting{
|
||||
}
|
||||
|
||||
// todo document the `Subdomain` object.
|
||||
list = utils.make_driver_method([], 'puter-subdomains', 'select');
|
||||
list = utils.make_driver_method([], 'puter-subdomains', undefined, 'select');
|
||||
|
||||
create = async (...args) => {
|
||||
let options = {};
|
||||
@@ -74,7 +74,7 @@ class Hosting{
|
||||
options = { object: args[0] };
|
||||
}
|
||||
// Call the original chat.complete method
|
||||
return await utils.make_driver_method(['object'], 'puter-subdomains', 'create').call(this, options);
|
||||
return await utils.make_driver_method(['object'], 'puter-subdomains', undefined, 'create').call(this, options);
|
||||
}
|
||||
|
||||
update = async(...args) => {
|
||||
@@ -97,7 +97,7 @@ class Hosting{
|
||||
}
|
||||
|
||||
// Call the original chat.complete method
|
||||
return await utils.make_driver_method(['object'], 'puter-subdomains', 'update').call(this, options);
|
||||
return await utils.make_driver_method(['object'], 'puter-subdomains', undefined, 'update').call(this, options);
|
||||
}
|
||||
|
||||
get = async(...args) => {
|
||||
@@ -113,7 +113,7 @@ class Hosting{
|
||||
|
||||
options = { id: {subdomain: args[0]}};
|
||||
}
|
||||
return utils.make_driver_method(['uid'], 'puter-subdomains', 'read').call(this, options);
|
||||
return utils.make_driver_method(['uid'], 'puter-subdomains', undefined, 'read').call(this, options);
|
||||
}
|
||||
|
||||
delete = async(...args) => {
|
||||
@@ -129,7 +129,7 @@ class Hosting{
|
||||
|
||||
options = { id: {subdomain: args[0]}};
|
||||
}
|
||||
return utils.make_driver_method(['uid'], 'puter-subdomains', 'delete').call(this, options);
|
||||
return utils.make_driver_method(['uid'], 'puter-subdomains', undefined, 'delete').call(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class KV{
|
||||
* `key` size cannot be larger than 1mb.
|
||||
* `value` size cannot be larger than 10mb.
|
||||
*/
|
||||
set = utils.make_driver_method(['key', 'value'], 'puter-kvstore', 'set',{
|
||||
set = utils.make_driver_method(['key', 'value'], 'puter-kvstore', undefined, 'set',{
|
||||
preprocess: (args)=>{
|
||||
// key cannot be undefined or null
|
||||
if(args.key === undefined || args.key === null){
|
||||
@@ -68,7 +68,7 @@ class KV{
|
||||
/**
|
||||
* Resolves to the value if the key exists, or `undefined` if the key does not exist. Rejects with an error on failure.
|
||||
*/
|
||||
get = utils.make_driver_method(['key'], 'puter-kvstore', 'get', {
|
||||
get = utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'get', {
|
||||
preprocess: (args)=>{
|
||||
// key size cannot be larger than MAX_KEY_SIZE
|
||||
if(args.key.length > this.MAX_KEY_SIZE){
|
||||
@@ -98,7 +98,7 @@ class KV{
|
||||
throw ({message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large'});
|
||||
}
|
||||
|
||||
return utils.make_driver_method(['key'], 'puter-kvstore', 'incr').call(this, options);
|
||||
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'incr').call(this, options);
|
||||
}
|
||||
|
||||
decr = async(...args) => {
|
||||
@@ -117,12 +117,12 @@ class KV{
|
||||
throw ({message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large'});
|
||||
}
|
||||
|
||||
return utils.make_driver_method(['key'], 'puter-kvstore', 'decr').call(this, options);
|
||||
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'decr').call(this, options);
|
||||
}
|
||||
|
||||
// resolves to 'true' on success, or rejects with an error on failure
|
||||
// will still resolve to 'true' if the key does not exist
|
||||
del = utils.make_driver_method(['key'], 'puter-kvstore', 'del', {
|
||||
del = utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'del', {
|
||||
preprocess: (args)=>{
|
||||
// key size cannot be larger than this.MAX_KEY_SIZE
|
||||
if(args.key.length > this.MAX_KEY_SIZE){
|
||||
@@ -154,7 +154,7 @@ class KV{
|
||||
pattern = args[0];
|
||||
}
|
||||
|
||||
return utils.make_driver_method([], 'puter-kvstore', 'list', {
|
||||
return utils.make_driver_method([], 'puter-kvstore', undefined, 'list', {
|
||||
transform: (res)=>{
|
||||
// glob pattern was provided
|
||||
if(pattern){
|
||||
@@ -179,7 +179,7 @@ class KV{
|
||||
|
||||
// resolve to 'true' on success, or rejects with an error on failure
|
||||
// will still resolve to 'true' if there are no keys
|
||||
flush = utils.make_driver_method([], 'puter-kvstore', 'flush')
|
||||
flush = utils.make_driver_method([], 'puter-kvstore', undefined, 'flush')
|
||||
|
||||
// clear is an alias for flush
|
||||
clear = this.flush;
|
||||
|
||||
Reference in New Issue
Block a user