diff --git a/tools/server/public_simplechat/simplechat.js b/tools/server/public_simplechat/simplechat.js index 599b147adc..925a181dbf 100644 --- a/tools/server/public_simplechat/simplechat.js +++ b/tools/server/public_simplechat/simplechat.js @@ -539,13 +539,15 @@ class SimpleChat { } /** - * Call the requested tool/function and get its response + * Call the requested tool/function. + * Returns undefined, if the call was placed successfully + * Else some appropriate error message will be returned. * @param {string} toolname * @param {string} toolargs */ async handle_toolcall(toolname, toolargs) { if (toolname === "") { - return undefined + return "Tool/Function call name not specified" } try { return await tools.tool_call(toolname, toolargs) @@ -675,6 +677,11 @@ class MultiChatUI { this.handle_tool_run(this.curChatId); }) + tools.setup((name, data)=>{ + this.elInUser.value = `${data}` + this.ui_reset_userinput(false) + }) + this.elInUser.addEventListener("keyup", (ev)=> { // allow user to insert enter into their message using shift+enter. // while just pressing enter key will lead to submitting. @@ -771,17 +778,24 @@ class MultiChatUI { /** * Handle running of specified tool call if any, for the specified chat session. + * Also sets up a timeout, so that user gets control back to interact with the ai model. * @param {string} chatId */ async handle_tool_run(chatId) { let chat = this.simpleChats[chatId]; this.elInUser.value = "toolcall in progress..."; this.elInUser.disabled = true; - let toolResult = await chat.handle_toolcall(this.elInToolName.value, this.elInToolArgs.value) + let toolname = this.elInToolName.value.trim() + let toolResult = await chat.handle_toolcall(toolname, this.elInToolArgs.value) if (toolResult !== undefined) { this.elInUser.value = `${toolResult}` + this.ui_reset_userinput(false) + } else { + setTimeout(() => { + this.elInUser.value = `Tool/Function call ${toolname} taking too much time, aborting...` + this.ui_reset_userinput(false) + }, 10000) } - this.ui_reset_userinput(toolResult === undefined); } /** @@ -1073,7 +1087,7 @@ function startme() { document["gMe"] = gMe; document["du"] = du; document["tools"] = tools; - tools.setup() + tools.init() for (let cid of gMe.defaultChatIds) { gMe.multiChat.new_chat_session(cid); } diff --git a/tools/server/public_simplechat/tools.mjs b/tools/server/public_simplechat/tools.mjs index d75d3eb7bf..4ece70ae56 100644 --- a/tools/server/public_simplechat/tools.mjs +++ b/tools/server/public_simplechat/tools.mjs @@ -8,12 +8,14 @@ import * as tjs from './tooljs.mjs' +let gToolsWorker = new Worker('./toolsworker.mjs'); /** * @type {Object>} */ export let tc_switch = {} -export function setup() { +export function init() { + tjs.init(gToolsWorker) for (const key in tjs.tc_switch) { tc_switch[key] = tjs.tc_switch[key] } @@ -27,9 +29,22 @@ export function meta() { return tools } +/** + * Setup the callback that will be called when ever message + * is recieved from the Tools Web Worker. + * @param {(name: string, data: string) => void} cb + */ +export function setup(cb) { + gToolsWorker.onmessage = function (ev) { + cb(ev.data.name, ev.data.data) + } +} + /** - * Try call the specified tool/function call and return its response + * Try call the specified tool/function call. + * Returns undefined, if the call was placed successfully + * Else some appropriate error message will be returned. * @param {string} toolname * @param {string} toolargs */ @@ -38,7 +53,7 @@ export async function tool_call(toolname, toolargs) { if (fn == toolname) { try { tc_switch[fn]["handler"](fn, JSON.parse(toolargs)) - return tc_switch[fn]["result"] + return undefined } catch (/** @type {any} */error) { return `Tool/Function call raised an exception:${error.name}:${error.message}` }