SimpleChatTC: Let user trigger tool call, instead of automatic

Instead of automatically calling any requested tool by the GenAi
/ llm, that is from the tail end of the handle user submit btn
click,

Now if the GenAi/LLM has requested any tool to be called, then
enable the Tool Run related UI elements and fill them with the
tool name and tool args.

In turn the user can verify if they are ok with the tool being
called and the arguments being passed to it. Rather they can
even fix any errors in the tool usage like the arithmatic expr
to calculate that is being passed to simple_calculator or the
javascript code being passed to run_javascript_function_code

If user is ok with the tool call being requested, then trigger
the same.

The results if any will be automatically placed into the user
query text area.

User can cross verify if they are ok with the result and or
modify it suitabley if required and inturn submit the same to
the GenAi/LLM.
This commit is contained in:
hanishkvc 2025-10-13 01:19:37 +05:30
parent 1fc44c971d
commit bfe789706e
1 changed files with 49 additions and 6 deletions

View File

@ -70,10 +70,17 @@ class AssistantResponse {
this.response[resp.key] += resp.value; this.response[resp.key] += resp.value;
} }
has_toolcall() {
if (this.response.toolname.trim() == "") {
return false
}
return true
}
content_equiv() { content_equiv() {
if (this.response.content !== "") { if (this.response.content !== "") {
return this.response.content; return this.response.content;
} else if (this.response.toolname !== "") { } else if (this.has_toolcall()) {
return `<tool_call>\n<tool_name>${this.response.toolname}</tool_name>\n<tool_args>${this.response.toolargs}</tool_args>\n</tool_call>`; return `<tool_call>\n<tool_name>${this.response.toolname}</tool_name>\n<tool_args>${this.response.toolargs}</tool_args>\n</tool_call>`;
} else { } else {
return "" return ""
@ -533,15 +540,15 @@ class SimpleChat {
/** /**
* Call the requested tool/function and get its response * Call the requested tool/function and get its response
* @param {AssistantResponse} ar * @param {string} toolname
* @param {string} toolargs
*/ */
async handle_toolcall(ar) { async handle_toolcall(toolname, toolargs) {
let toolname = ar.response.toolname.trim();
if (toolname === "") { if (toolname === "") {
return undefined return undefined
} }
try { try {
return await tools.tool_call(toolname, ar.response.toolargs) return await tools.tool_call(toolname, toolargs)
} catch (/** @type {any} */error) { } catch (/** @type {any} */error) {
return `Tool/Function call raised an exception:${error.name}:${error.message}` return `Tool/Function call raised an exception:${error.name}:${error.message}`
} }
@ -596,6 +603,24 @@ class MultiChatUI {
} }
} }
/**
* Reset/Setup Tool Call UI parts as needed
* @param {AssistantResponse} ar
*/
ui_reset_toolcall_as_needed(ar) {
if (ar.has_toolcall()) {
this.elDivTool.hidden = false
this.elInToolName.value = ar.response.toolname
this.elInToolArgs.value = ar.response.toolargs
this.elBtnTool.disabled = false
} else {
this.elDivTool.hidden = true
this.elInToolName.value = ""
this.elInToolArgs.value = ""
this.elBtnTool.disabled = true
}
}
/** /**
* Reset user input ui. * Reset user input ui.
* * clear user input (if requested, default true) * * clear user input (if requested, default true)
@ -641,6 +666,13 @@ class MultiChatUI {
}); });
}); });
this.elBtnTool.addEventListener("click", (ev)=>{
if (this.elDivTool.hidden) {
return;
}
this.handle_tool_run(this.curChatId);
})
this.elInUser.addEventListener("keyup", (ev)=> { this.elInUser.addEventListener("keyup", (ev)=> {
// allow user to insert enter into their message using shift+enter. // allow user to insert enter into their message using shift+enter.
// while just pressing enter key will lead to submitting. // while just pressing enter key will lead to submitting.
@ -729,7 +761,18 @@ class MultiChatUI {
} else { } else {
console.debug(`DBUG:SimpleChat:MCUI:HandleUserSubmit:ChatId has changed:[${chatId}] [${this.curChatId}]`); console.debug(`DBUG:SimpleChat:MCUI:HandleUserSubmit:ChatId has changed:[${chatId}] [${this.curChatId}]`);
} }
let toolResult = await chat.handle_toolcall(theResp) this.ui_reset_toolcall_as_needed(theResp);
this.ui_reset_userinput();
}
/**
* @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)
if (toolResult !== undefined) { if (toolResult !== undefined) {
this.elInUser.value = `<tool_response>${toolResult}</tool_response>` this.elInUser.value = `<tool_response>${toolResult}</tool_response>`
} }