SimpleChatTC:MeInTools: WebWorkers in Me

Given that Me is now passed to the tools logic during setup, have
the web worker handles in Me itself, instead of in tool related
modules.

Move setup of web worker related main thread callbacks, as well as
posting messages directly to these main thread callbacks, into Me.
This commit is contained in:
hanishkvc 2025-11-06 01:12:30 +05:30
parent 85c2779579
commit 0e7fe8bcf2
5 changed files with 73 additions and 59 deletions

View File

@ -1069,8 +1069,8 @@ class MultiChatUI {
this.handle_tool_run(this.curChatId);
})
// Handle messages from Tools web worker
tools.setup((cid, tcid, name, data)=>{
// Handle messages from tools web workers
this.me.workers_cb((cid, tcid, name, data)=>{
clearTimeout(this.timers.toolcallResponseTimeout)
this.timers.toolcallResponseTimeout = undefined
let chat = this.simpleChats[cid];
@ -1386,6 +1386,10 @@ export class Me {
//"frequency_penalty": 1.2,
//"presence_penalty": 1.2,
};
this.workers = {
js: /** @type {Worker} */(/** @type {unknown} */(undefined)),
db: /** @type {Worker} */(/** @type {unknown} */(undefined)),
}
}
/**
@ -1469,6 +1473,35 @@ export class Me {
})
}
/**
* Setup the callback that will be called when ever message
* is recieved from the Tools Web Workers.
* @param {(chatId: string, toolCallId: string, name: string, data: string) => void} cb
*/
workers_cb(cb) {
this.workers.js.onmessage = function (ev) {
cb(ev.data.cid, ev.data.tcid, ev.data.name, ev.data.data)
}
this.workers.db.onmessage = function (ev) {
cb(ev.data.cid, ev.data.tcid, ev.data.name, JSON.stringify(ev.data.data, (k,v)=>{
return (v === undefined) ? '__UNDEFINED__' : v;
}));
}
}
/**
* Send a message to specified tools web worker's monitor in main thread directly
* @param {Worker} worker
* @param {string} chatid
* @param {string} toolcallid
* @param {string} toolname
* @param {string} data
*/
workers_postmessage_for_main(worker, chatid, toolcallid, toolname, data) {
let mev = new MessageEvent('message', {data: {cid: chatid, tcid: toolcallid, name: toolname, data: data}});
if (worker.onmessage != null) {
worker.onmessage(mev)
}
}
}

View File

@ -1,12 +1,14 @@
//@ts-check
// ALERT - Simple Stupid flow - Using from a discardable VM is better
// Helpers to handle tools/functions calling wrt data store
// using a web worker.
// using a db specific web worker.
// by Humans for All
//
import * as mChatMagic from './simplechat.js'
let gToolsDBWorker = /** @type{Worker} */(/** @type {unknown} */(null));
let gMe = /** @type{mChatMagic.Me} */(/** @type {unknown} */(null));
let dsget_meta = {
@ -93,7 +95,7 @@ let dslist_meta = {
* @param {any} obj
*/
function dsops_run(chatid, toolcallid, toolname, obj) {
gToolsDBWorker.postMessage({ cid: chatid, tcid: toolcallid, name: toolname, args: obj})
gMe.workers.db.postMessage({ cid: chatid, tcid: toolcallid, name: toolname, args: obj})
}
@ -128,8 +130,8 @@ export let tc_switch = {
/**
* Used to get hold of the web worker to use for running tool/function call related code
* Also to setup tool calls, which need to cross check things at runtime
* @param {Worker} toolsWorker
* @param {mChatMagic.Me} me
*/
export async function init(toolsWorker) {
gToolsDBWorker = toolsWorker
export async function init(me) {
gMe = me
}

View File

@ -3,12 +3,14 @@
// Helpers to handle tools/functions calling wrt
// * javascript interpreter
// * simple arithmatic calculator
// using a web worker.
// using the js specific web worker.
// by Humans for All
//
import * as mChatMagic from './simplechat.js'
let gToolsWorker = /** @type{Worker} */(/** @type {unknown} */(null));
let gMe = /** @type{mChatMagic.Me} */(/** @type {unknown} */(null));
let sysdatetime_meta = {
@ -75,9 +77,7 @@ function sysdatetime_run(chatid, toolcallid, toolname, obj) {
break;
}
}
if (gToolsWorker.onmessage != null) {
gToolsWorker.onmessage(new MessageEvent('message', {data: {cid: chatid, tcid: toolcallid, name: toolname, data: sDT}}))
}
gMe.workers_postmessage_for_main(gMe.workers.js, chatid, toolcallid, toolname, sDT);
}
@ -109,7 +109,7 @@ let js_meta = {
* @param {any} obj
*/
function js_run(chatid, toolcallid, toolname, obj) {
gToolsWorker.postMessage({ cid: chatid, tcid: toolcallid, name: toolname, code: obj["code"]})
gMe.workers.js.postMessage({ cid: chatid, tcid: toolcallid, name: toolname, code: obj["code"]})
}
@ -141,7 +141,7 @@ let calc_meta = {
* @param {any} obj
*/
function calc_run(chatid, toolcallid, toolname, obj) {
gToolsWorker.postMessage({ cid: chatid, tcid: toolcallid, name: toolname, code: `console.log(${obj["arithexpr"]})`})
gMe.workers.js.postMessage({ cid: chatid, tcid: toolcallid, name: toolname, code: `console.log(${obj["arithexpr"]})`})
}
@ -170,8 +170,8 @@ export let tc_switch = {
/**
* Used to get hold of the web worker to use for running tool/function call related code
* Also to setup tool calls, which need to cross check things at runtime
* @param {Worker} toolsWorker
* @param {mChatMagic.Me} me
*/
export async function init(toolsWorker) {
gToolsWorker = toolsWorker
export async function init(me) {
gMe = me
}

View File

@ -11,8 +11,6 @@ import * as tdb from './tooldb.mjs'
import * as mChatMagic from './simplechat.js'
let gToolsWorker = new Worker('./toolsworker.mjs', { type: 'module' });
let gToolsDBWorker = new Worker('./toolsdbworker.mjs', { type: 'module' });
/**
* Maintain currently available tool/function calls
* @type {Object<string,Object<string,any>>}
@ -20,27 +18,37 @@ let gToolsDBWorker = new Worker('./toolsdbworker.mjs', { type: 'module' });
export let tc_switch = {}
/**
* @param {mChatMagic.Me} me
*/
function setup_workers(me) {
me.workers.js = new Worker('./toolsworker.mjs', { type: 'module' });
me.workers.db = new Worker('./toolsdbworker.mjs', { type: 'module' });
}
/**
* @param {mChatMagic.Me} me
*/
export async function init(me) {
setup_workers(me);
/**
* @type {string[]}
*/
let toolNames = []
await tjs.init(gToolsWorker).then(()=>{
await tjs.init(me).then(()=>{
for (const key in tjs.tc_switch) {
tc_switch[key] = tjs.tc_switch[key]
toolNames.push(key)
}
})
await tdb.init(gToolsDBWorker).then(()=>{
await tdb.init(me).then(()=>{
for (const key in tdb.tc_switch) {
tc_switch[key] = tdb.tc_switch[key]
toolNames.push(key)
}
})
let tNs = await tweb.init(gToolsWorker, me)
let tNs = await tweb.init(me)
for (const key in tNs) {
tc_switch[key] = tNs[key]
toolNames.push(key)
@ -58,23 +66,6 @@ export function meta() {
}
/**
* Setup the callback that will be called when ever message
* is recieved from the Tools Web Worker.
* @param {(chatId: string, toolCallId: string, name: string, data: string) => void} cb
*/
export function setup(cb) {
gToolsWorker.onmessage = function (ev) {
cb(ev.data.cid, ev.data.tcid, ev.data.name, ev.data.data)
}
gToolsDBWorker.onmessage = function (ev) {
cb(ev.data.cid, ev.data.tcid, ev.data.name, JSON.stringify(ev.data.data, (k,v)=>{
return (v === undefined) ? '__UNDEFINED__' : v;
}));
}
}
/**
* Try call the specified tool/function call.
* Returns undefined, if the call was placed successfully

View File

@ -2,29 +2,19 @@
// ALERT - Simple Stupid flow - Using from a discardable VM is better
// Helpers to handle tools/functions calling related to web access, pdf, etal
// which work in sync with the bundled simpleproxy.py server logic.
// Uses the js specific web worker path.
// by Humans for All
//
import * as mChatMagic from './simplechat.js'
let gToolsWorker = /** @type{Worker} */(/** @type {unknown} */(null));
/**
* @type {mChatMagic.Me}
*/
let gMe = /** @type{mChatMagic.Me} */(/** @type {unknown} */(null));
/**
* Send a message to Tools WebWorker's monitor in main thread directly
* @param {MessageEvent<any>} mev
*/
function message_toolsworker(mev) {
// @ts-ignore
gToolsWorker.onmessage(mev)
}
/**
* For now hash the shared secret with the year.
*/
@ -51,7 +41,7 @@ async function bearer_transform() {
* @param {any} objHeaders
*/
async function proxyserver_get_anyargs(chatid, toolcallid, toolname, objSearchParams, path, objHeaders={}) {
if (gToolsWorker.onmessage != null) {
if (gMe.workers.js.onmessage != null) {
let params = new URLSearchParams(objSearchParams)
let newUrl = `${gMe.tools.proxyUrl}/${path}?${params}`
let headers = new Headers(objHeaders)
@ -63,9 +53,9 @@ async function proxyserver_get_anyargs(chatid, toolcallid, toolname, objSearchPa
}
return resp.text()
}).then(data => {
message_toolsworker(new MessageEvent('message', {data: {cid: chatid, tcid: toolcallid, name: toolname, data: data}}))
gMe.workers_postmessage_for_main(gMe.workers.js, chatid, toolcallid, toolname, data);
}).catch((err)=>{
message_toolsworker(new MessageEvent('message', {data: {cid: chatid, tcid: toolcallid, name: toolname, data: `Error:${err}`}}))
gMe.workers_postmessage_for_main(gMe.workers.js, chatid, toolcallid, toolname, `Error:${err}`);
})
}
}
@ -343,15 +333,13 @@ async function fetchpdftext_setup(tcs) {
/**
* Used to get hold of the web worker to use for running tool/function call related code
* Also to setup tool calls, which need to cross check things at runtime
* @param {Worker} toolsWorker
* @param {mChatMagic.Me} me
*/
export async function init(toolsWorker, me) {
export async function init(me) {
/**
* @type {Object<string, Object<string, any>>} tcs
*/
let tc_switch = {}
gToolsWorker = toolsWorker
gMe = me
await fetchweburlraw_setup(tc_switch)
await fetchweburltext_setup(tc_switch)