diff --git a/src/puter-js/src/lib/utils.js b/src/puter-js/src/lib/utils.js index a84ac432f..8195da8f0 100644 --- a/src/puter-js/src/lib/utils.js +++ b/src/puter-js/src/lib/utils.js @@ -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, diff --git a/src/puter-js/src/modules/AI.js b/src/puter-js/src/modules/AI.js index edf9abb4a..5a37c410f 100644 --- a/src/puter-js/src/modules/AI.js +++ b/src/puter-js/src/modules/AI.js @@ -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 => { diff --git a/src/puter-js/src/modules/Apps.js b/src/puter-js/src/modules/Apps.js index 4307e29b5..4479aa2a1 100644 --- a/src/puter-js/src/modules/Apps.js +++ b/src/puter-js/src/modules/Apps.js @@ -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){ diff --git a/src/puter-js/src/modules/Hosting.js b/src/puter-js/src/modules/Hosting.js index fa2234164..349257e2f 100644 --- a/src/puter-js/src/modules/Hosting.js +++ b/src/puter-js/src/modules/Hosting.js @@ -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); } } diff --git a/src/puter-js/src/modules/KV.js b/src/puter-js/src/modules/KV.js index c04056065..5fe958757 100644 --- a/src/puter-js/src/modules/KV.js +++ b/src/puter-js/src/modules/KV.js @@ -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;