Skip to content

Conversation

@hanishkvc
Copy link
Contributor

@hanishkvc hanishkvc commented Oct 28, 2025

Have extended server/public_simplechat wrt reasoning models, now the user can see the reasoning/thinking generated by such ai models, as it is being generated.

Also client ui wrt multiple chat sessions and switching between them including maintaining context wrt tool calling, as well as even resuming tool call if needed when reloading a autosaved session etal handled to an extent now.

This builds on the other PRs in this chain of changes

#16791 - added web search support to simpleproxy based builtin tools, bearer auth for bundled simpleproxy server, ...

#16563 - added support for toolcalls and inturn few direct builtin tools like calculator and javascript execution as well as support for fetch web pages using a bundled simpleproxy.py server, ...

NOTE: As the other PRs mentioned above arent merged into main/master yet, so even commits related to those PRs in the chain of commits below

Enable streaming by default, to check the handshake before going
on to change the code, given that havent looked into this for more
than a year now and have been busy with totally different stuff.

Also updated the user messages used for testing a bit
Define the meta that needs to be passed to the GenAi Engine.

Define the logic that implements the tool call, if called.

Implement the flow/structure such that a single tool calls
implementation file can define multiple tool calls.
Make tooljs structure and flow more generic

Add a simple_calculator tool/function call logic

Add initial skeleton wrt the main tools.mjs file.
Changed latestResponse type to an object instead of a string.
Inturn it contains entries for content, toolname and toolargs.

Added a custom clear logic due to the same and used it to replace
the previously simple assigning of empty string to latestResponse.

For now in all places where latestReponse is used, I have replaced
with latestReponse.content.

Next need to handle identifying the field being streamed and inturn
append to it. Also need to add logic to call tool, when tool_call
triggered by genai.
Update response_extract_stream to check for which field is being
currently streamed ie is it normal content or tool call func name
or tool call func args and then return the field name and extracted
value.

Previously it was always assumed that only normal content will be
returned.

Currently it is assumed that the server will only stream one of the
3 supported fields at any time and not more than one of them at the
same time.

TODO: Have to also add logic to extract the reasoning field later,
ie wrt gen ai models which give out their thinking.

Have updated append_response to expect both the key and the value
wrt the latestResponse object, which it will be manipualted.

Previously it was always assumed that content is what will be got
and inturn appended.
I was wrongly checking for finish_reason to be non null, before
trying to extract the genai content/toolcalls, have fixed this
oversight with the new flow in progress.

I had added few debug logs to identify the above issue, need to
remove them later. Note: given that debug logs are disabled by
replacing the debug function during this program's initialisation,
which I had forgotten about, I didnt get the debug messages and
had to scratch my head a bit, before realising this and the other
issue ;)

Also either when I had originally implemented simplechat 1+ years
back, or later due to changes on the server end, the streaming
flow sends a initial null wrt the content, where it only sets the
role. This was not handled in my flow on the client side, so a
null was getting prepended to the chat messages/responses from the
server. This has been fixed now in the new generic flow.
Make latestResponse into a new class based type instance wrt
ai assistant response, which is what it represents.

Move clearing, appending fields' values and getting assistant's
response info (irrespective of a content or toolcall response)
into this new class and inturn use the same.
Switch oneshot handler to use AssistantResponse, inturn currenlty
only handle the normal content in the response.

TODO: If any tool_calls in the oneshot response, it is currently
not handled.

Inturn switch the generic/toplevel handle response logic to use
AssistantResponse class, given that both oneshot and the
multipart/streaming flows use/return it.

Inturn add trimmedContent member to AssistantResponse class and
make the generic handle response logic to save the trimmed content
into this. Update users of trimmed to work with this structure.
As there could be failure wrt getting the response from the ai
server some where in between a long response spread over multiple
 parts, the logic uses the latestResponse to cache the response
as it is being received. However once the full response is got,
one needs to transfer it to a new instance of AssistantResponse
class, so that latestResponse can be cleared, while the new
instance can be used in other locations in the flow as needed.

Achieve the same now.
Previously if content was empty, it would have always sent the
toolcall info related version even if there was no toolcall info
in it. Fixed now to return empty string, if both content and
toolname are empty.
The implementations of javascript and simple_calculator now use
provided helpers to trap console.log messages when they execute
the code / expression provided by GenAi and inturn store the
captured log messages in the newly added result key in tc_switch

This should help trap the output generated by the provided code
or expression as the case maybe and inturn return the same to the
GenAi, for its further processing.
Checks for toolname to be defined or not in the GenAi's response

If toolname is set, then check if a corresponding tool/func exists,
and if so call the same by passing it the GenAi provided toolargs
as a object.

Inturn the text generated by the tool/func is captured and put
into the user input entry text box, with tool_response tag around
it.
As output generated by any tool/function call is currently placed
into the TextArea provided for End user (for their queries), bcas
the GenAi (engine/LLM) may be expecting the tool response to be
sent as a user role data with tool_response tag surrounding the
results from the tool call. So also now at the end of submit btn
click handling, the end user input text area is not cleared, if
there was a tool call handled, for above reasons.

Also given that running a simple arithmatic expression in itself
doesnt generate any output, so wrap them in a console.log, to
help capture the result using the console.log trapping flow that
is already setup.
and inform the GenAi/LLM about the same
Should hopeful ensure that the GenAi/LLM will generate appropriate
code/expression as the argument to pass to these tool calls, to
some extent.
Move tool calling logic into tools module.

Try trap async promise failures by awaiting results of tool calling
and putting full thing in an outer try catch. Have forgotten the
nitty gritties of JS flow, this might help, need to check.
So that when tool handler writes the result to the tc_switch, it
can make use of the same, to write to the right location.

NOTE: This also fixes the issue with I forgetting to rename the
key in js_run wrt writing of result.
to better describe how it will be run, so that genai/llm while
creating the code to run, will hopefully take care of any naunces
required.
Also as part of same, wrap the request details in the assistant
block using a similar tagging format as the tool_response in user
block.
Instead of automatically calling the requested tool with supplied
arguments, rather allow user to verify things before triggering the
tool.

NOTE: User already provided control over tool_response before
submitting it to the ai assistant.
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.
Also avoid showing Tool calling UI elements, when not needed to
be shown.
As noted in the comments in code, this is a very insecure flow
for now.
Next will be adding a proxyAuth field also to tools.
User can configure the bearer token to send
instead of using the shared bearer token as is, hash it with
current year and use the hash.

keep /aum path out of auth check.

in future bearer token could be transformed more often, as well as
with additional nounce/dynamic token from server got during initial
/aum handshake as also running counter and so ...

NOTE: All these circus not good enough, given that currently the
simpleproxy.py handshakes work over http. However these skeletons
put in place, for future, if needed.

TODO: There is a once in a bluemoon race when the year transitions
between client generating the request and server handling the req.
But other wise year transitions dont matter bcas client always
creates fresh token, and server checks for year change to genrate
fresh token if required.
Add a new role ToolTemp, which is used to maintain any tool call
response on the client ui side, without submitting it to the server
ie till user or auto submit triggers the submitting of that tool
call response.

When ever a tool call response is got, create a ToolTemp role based
message in the corresponding chat session. And dont directly update
the user query input area, rather leave it to the updated simplechat
show and the new multichatui chat_show helper and inturn whether the
current chat session active in ui is same as the one for which the
tool call response has been recieved.

TODO: Currently the response message is added to the current
active chat session, but this needs to be changed by tracking
chatId/session through the full tool call cycle and then adding
the tool call response in the related chat session, and inturn
updating or not the ui based on whether that chat session is
still the active chat session in ui or not, given that tool call
gets handled in a asynchronous way.

Now when that tool call response is submitted, promote the equiv
tool temp role based message that should be in the session's chat
history as the last message into becoming a normal tool response
message.

SimpleChat.show has been updated to take care of showing any
ToolTemp role message in the user query input area.

A newer chat_show helper added to MultiChatUI, that takes care of
calling SimpleChat.show, provided the chat_show is being requested
for the currently active in ui, chat session. As well as to take
care of passing both the ChatDiv and elInUser. Converts users of
SimpleChat.show to use MultiChatUI.chat_show
Update the immidiate tool call triggering failure and tool call
response timeout paths to use the new ToolTemp and MultiChatUI
based chat show logics.

Actual tool call itself generating errors, is already handled
in the previous commit changes.
Pass chatId to tool call, and use chatId in got tool call resp,
to decide as to to which chat session the async tool call resp
belongs and inturn if auto submit timer should be started if auto
is enabled.
This should ensure that tool call responses can be mapped back to
the chat session for which it was triggered.
Rather simplify and make the content_equiv provide a relatively
simple and neat representation of the reasoning with content and
toolcall as the cases may be.

Also remove the partial new para that I had introduced in the
initial go for reasoning.
Update existing flow so that next Tool Role message is handled
directly from within
Also take care of updating the toolcall ui if needed from within
this.
Fix up the initial skeleton / logic as needed.

Remember that we are working with potentially a subset of chat
messages from the session, given the sliding window logic of
context managing on client ui side, so fix up the logic to use
the right subset of messages array and not the global xchat
when deciding whether a message is the last or last but one,
which need special handling wrt Assistant (with toolcall) and
Tool (ie response) messages.

Moving tool call ui setup as well as tool call response got ui
setup into ChatShow of MultiChatUI ensures that switching between
chat sessions handle the ui wrt tool call triggering ui and tool
call response submission related ui as needed properly.

Rather even loading a previously auto saved chat session if it had
tool call or tool call response to be handled, the chat ui will be
setup as needed to continue that session properly.
Also cleanup the minimal based showing of chat messages a bit

And add github.com to allowed list
@hanishkvc
Copy link
Contributor Author

hanishkvc commented Oct 28, 2025

Hi @mofosyne

I have updated tools/server/public_simplechat client ui with the below features (bringing it up to date with some of the ai features which have come up over the last ~1.5 years)

  1. support for tool calling (with user supervision, if needed) wrt genai models which support the same

1.1. builtin tool / function calls wrt calculator and javascript execution (these run using a webworker)

1.2. optional fetch web page and web search tool / function calls using a included python proxy server (simpleproxy.py, to help overcome cors restriction with fetch requests from browsers, as well as to help with html stripping into plain text, additional tool calls in future, if needed)

1.2.1. the simpleproxy.py controls access to web using a whitelist and also includes bearer auth token mechanism (https needed wrt simpleproxy.py handshake to make bearer token usage really useful, but avoided for now).

  1. support for showing reasoning / thinking generated by ai models with reasoning support

  2. allow user to switch between the different chat sessions as well as load any previously locally auto saved chat sessions and resume any tool calling in them.

  3. cleanup code flow to make it easy to implement above features as well as multimodal feature in future / later.

  4. auto settings ui and config info helper logics, so that adding new config fields get auto reflected in settings and info, if needed

With above end users / developers can make use of tool calling in their chat sessions without needing any additional backend or otherwise setup of MCP host / routers / parts etal

I have tested these with Gemma3N, Granite4 and GPT-OSS ai models.

Also I couldnt find any directly usable open source ui with support for ready builtin tool calls in my limited search

  • some seemed to need creating a online account or so to use tool calling feature or so,

  • also most seemed to thinking of using mcp mechanism etal to bring tool calling in, when simple yet very useful tool calls (esp for a browser env based ui) like calculator and javascript execution can be implemented without any need for such.

so also the reason for updating public_simplechat with these now.

This is ready for merging.

CC: @ggerganov

@github-actions github-actions bot added examples python python script changes server labels Oct 28, 2025
Add a newline between name and content in the xml representation
of the tool response, so that it is more easy to distinguish things

Add github, linkedin and apnews domains to allowed.domains for
simpleproxy.py
Seperate out the message ui block into a container containing
a role block and contents container block.

This will allow themeing of these seperately, if required.
As part of same, currently the role has been put to the side
of the message with vertical text flow.
Also make reasoning easily identifiable in the chat
Define rules to ensure that chat message contents wrap so as to
avoid overflowing beyond the size of the screen being viewed.

The style used for chat message role to be placed with vertical
oriented text adjacent to the actual message content on the side
seems to be creating issue with blank pages in some browsers,
so avoid that styling when one is printing.
@hanishkvc
Copy link
Contributor Author

Client ui now seperates out and tags the different elements of a chat message seperately, so that one could theme the chat messages and their contents if needed. As part of same also allow multiple function / tool calls within a single assistant message to be shown. NOTE: tool call triggering will work with only the 0th function call for now.

Use same to have a slightly different presentation of the chat messages when accessed directly and when printed. This was done as there was a issue with printing the new default layout of chat message contents, in some browsers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

examples python python script changes server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant