diff --git a/tools/server/public_simplechat/simplechat.css b/tools/server/public_simplechat/simplechat.css
index 13bfb80b48..d4755074b7 100644
--- a/tools/server/public_simplechat/simplechat.css
+++ b/tools/server/public_simplechat/simplechat.css
@@ -21,6 +21,9 @@
.role-user {
background-color: lightgray;
}
+.role-tool {
+ background-color: lightyellow;
+}
.role-trim {
background-color: lightpink;
}
diff --git a/tools/server/public_simplechat/simplechat.js b/tools/server/public_simplechat/simplechat.js
index 2b82a4648d..281b2c15b9 100644
--- a/tools/server/public_simplechat/simplechat.js
+++ b/tools/server/public_simplechat/simplechat.js
@@ -77,6 +77,17 @@ class ChatMessageEx {
this.trimmedContent = "";
}
+ /**
+ * Create a all in one tool call result string
+ * @param {string} toolCallId
+ * @param {string} toolName
+ * @param {string} toolResult
+ */
+ static createToolCallResultAllInOne(toolCallId, toolName, toolResult) {
+ return ` ${toolCallId} ${toolName} ${toolResult} `;
+ }
+
+
/**
* Update based on the drip by drip data got from network in streaming mode.
* Tries to support both Chat and Completion endpoints
@@ -561,15 +572,16 @@ class SimpleChat {
* Call the requested tool/function.
* Returns undefined, if the call was placed successfully
* Else some appropriate error message will be returned.
+ * @param {string} toolcallid
* @param {string} toolname
* @param {string} toolargs
*/
- async handle_toolcall(toolname, toolargs) {
+ async handle_toolcall(toolcallid, toolname, toolargs) {
if (toolname === "") {
return "Tool/Function call name not specified"
}
try {
- return await tools.tool_call(toolname, toolargs)
+ return await tools.tool_call(toolcallid, toolname, toolargs)
} catch (/** @type {any} */error) {
return `Tool/Function call raised an exception:${error.name}:${error.message}`
}
@@ -633,11 +645,13 @@ class MultiChatUI {
if (ar.has_toolcall()) {
this.elDivTool.hidden = false
this.elInToolName.value = ar.ns.tool_calls[0].function.name
+ this.elInToolName.dataset.tool_call_id = ar.ns.tool_calls[0].id
this.elInToolArgs.value = ar.ns.tool_calls[0].function.arguments
this.elBtnTool.disabled = false
} else {
this.elDivTool.hidden = true
this.elInToolName.value = ""
+ this.elInToolName.dataset.tool_call_id = ""
this.elInToolArgs.value = ""
this.elBtnTool.disabled = true
}
@@ -697,9 +711,9 @@ class MultiChatUI {
this.handle_tool_run(this.curChatId);
})
- tools.setup((name, data)=>{
+ tools.setup((id, name, data)=>{
clearTimeout(this.idTimeOut)
- this.elInUser.value = `${data}`
+ this.elInUser.value = ChatMessageEx.createToolCallResultAllInOne(id, name, data);
this.ui_reset_userinput(false)
})
@@ -744,6 +758,14 @@ class MultiChatUI {
/**
* Handle user query submit request, wrt specified chat session.
+ * NOTE: Currently the user query entry area is used for
+ * * showing and allowing edits by user wrt tool call results
+ * in a predfined simple xml format,
+ * ie before they submit tool result to ai engine on server
+ * * as well as for user to enter their own queries.
+ * Based on presence of the predefined xml format data at beginning
+ * the logic will treat it has a tool result and if not then as a
+ * normal user query.
* @param {string} chatId
* @param {string} apiEP
*/
@@ -768,7 +790,11 @@ class MultiChatUI {
console.debug(`WARN:SimpleChat:MCUI:${chatId}:HandleUserSubmit:Ignoring empty user input...`);
return;
}
- chat.add(new ChatMessageEx(Roles.User, content))
+ if (content.startsWith("")) {
+ chat.add(new ChatMessageEx(Roles.Tool, content))
+ } else {
+ chat.add(new ChatMessageEx(Roles.User, content))
+ }
chat.show(this.elDivChat);
let theUrl = ApiEP.Url(gMe.baseURL, apiEP);
@@ -808,13 +834,17 @@ class MultiChatUI {
this.elInUser.value = "toolcall in progress...";
this.elInUser.disabled = true;
let toolname = this.elInToolName.value.trim()
- let toolResult = await chat.handle_toolcall(toolname, this.elInToolArgs.value)
+ let toolCallId = this.elInToolName.dataset.tool_call_id;
+ if (toolCallId === undefined) {
+ toolCallId = "??? ToolCallId Missing ???"
+ }
+ let toolResult = await chat.handle_toolcall(toolCallId, toolname, this.elInToolArgs.value)
if (toolResult !== undefined) {
- this.elInUser.value = `${toolResult}`
+ this.elInUser.value = ChatMessageEx.createToolCallResultAllInOne(toolCallId, toolname, toolResult);
this.ui_reset_userinput(false)
} else {
this.idTimeOut = setTimeout(() => {
- this.elInUser.value = `Tool/Function call ${toolname} taking too much time, aborting...`
+ this.elInUser.value = ChatMessageEx.createToolCallResultAllInOne(toolCallId, toolname, `Tool/Function call ${toolname} taking too much time, aborting...`);
this.ui_reset_userinput(false)
}, 10000)
}
diff --git a/tools/server/public_simplechat/tooljs.mjs b/tools/server/public_simplechat/tooljs.mjs
index 6aea9a5ee4..a44333ca1b 100644
--- a/tools/server/public_simplechat/tooljs.mjs
+++ b/tools/server/public_simplechat/tooljs.mjs
@@ -32,11 +32,12 @@ let js_meta = {
/**
* Implementation of the javascript interpretor logic. Minimal skeleton for now.
* ALERT: Has access to the javascript web worker environment and can mess with it and beyond
+ * @param {string} toolcallid
* @param {string} toolname
* @param {any} obj
*/
-function js_run(toolname, obj) {
- gToolsWorker.postMessage({ name: toolname, code: obj["code"]})
+function js_run(toolcallid, toolname, obj) {
+ gToolsWorker.postMessage({ id: toolcallid, name: toolname, code: obj["code"]})
}
@@ -62,11 +63,12 @@ let calc_meta = {
/**
* Implementation of the simple calculator logic. Minimal skeleton for now.
* ALERT: Has access to the javascript web worker environment and can mess with it and beyond
+ * @param {string} toolcallid
* @param {string} toolname
* @param {any} obj
*/
-function calc_run(toolname, obj) {
- gToolsWorker.postMessage({ name: toolname, code: `console.log(${obj["arithexpr"]})`})
+function calc_run(toolcallid, toolname, obj) {
+ gToolsWorker.postMessage({ id: toolcallid, name: toolname, code: `console.log(${obj["arithexpr"]})`})
}
diff --git a/tools/server/public_simplechat/tools.mjs b/tools/server/public_simplechat/tools.mjs
index 75fe56e4f4..8c89e96525 100644
--- a/tools/server/public_simplechat/tools.mjs
+++ b/tools/server/public_simplechat/tools.mjs
@@ -32,11 +32,11 @@ export function meta() {
/**
* Setup the callback that will be called when ever message
* is recieved from the Tools Web Worker.
- * @param {(name: string, data: string) => void} cb
+ * @param {(id: string, name: string, data: string) => void} cb
*/
export function setup(cb) {
gToolsWorker.onmessage = function (ev) {
- cb(ev.data.name, ev.data.data)
+ cb(ev.data.id, ev.data.name, ev.data.data)
}
}
@@ -45,14 +45,15 @@ export function setup(cb) {
* 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} toolcallid
* @param {string} toolname
* @param {string} toolargs
*/
-export async function tool_call(toolname, toolargs) {
+export async function tool_call(toolcallid, toolname, toolargs) {
for (const fn in tc_switch) {
if (fn == toolname) {
try {
- tc_switch[fn]["handler"](fn, JSON.parse(toolargs))
+ tc_switch[fn]["handler"](toolcallid, fn, JSON.parse(toolargs))
return undefined
} catch (/** @type {any} */error) {
return `Tool/Function call raised an exception:${error.name}:${error.message}`
diff --git a/tools/server/public_simplechat/toolsworker.mjs b/tools/server/public_simplechat/toolsworker.mjs
index e370fd0a9d..590c45234b 100644
--- a/tools/server/public_simplechat/toolsworker.mjs
+++ b/tools/server/public_simplechat/toolsworker.mjs
@@ -21,5 +21,5 @@ self.onmessage = function (ev) {
console.log(`\n\nTool/Function call "${ev.data.name}" raised an exception:${error.name}:${error.message}\n\n`)
}
tconsole.console_revert()
- self.postMessage({ name: ev.data.name, data: tconsole.gConsoleStr})
+ self.postMessage({ id: ev.data.id, name: ev.data.name, data: tconsole.gConsoleStr})
}