SimpleChatTCRV:Submit: Remember to include image, if available

Also rename the id/label of InFile+Btn to Image.

Extra fields while Adding.
This commit is contained in:
hanishkvc 2025-11-10 15:42:48 +05:30
parent 930fd656b9
commit a6b5555fe5
2 changed files with 41 additions and 4 deletions

View File

@ -45,6 +45,8 @@ control over tool calling and response submitting.
For GenAi/LLM models which support reasoning, the thinking of the model will be shown to the end user as the For GenAi/LLM models which support reasoning, the thinking of the model will be shown to the end user as the
model is running through its reasoning. model is running through its reasoning.
For GenAi/LLM models with vision support, one can specify image file and get the ai to respond wrt the same.
NOTE: As all genai/llm web service apis may or may not expose the model context length directly, and also NOTE: As all genai/llm web service apis may or may not expose the model context length directly, and also
as using ai out of band for additional parallel work may not be efficient given the loading of current systems as using ai out of band for additional parallel work may not be efficient given the loading of current systems
by genai/llm models, so client logic doesnt provide any adaptive culling of old messages nor of replacing them by genai/llm models, so client logic doesnt provide any adaptive culling of old messages nor of replacing them
@ -110,6 +112,11 @@ remember to
* other builtin tool / function calls like datetime, calculator, javascript runner, DataStore * other builtin tool / function calls like datetime, calculator, javascript runner, DataStore
dont require the simpleproxy.py helper. dont require the simpleproxy.py helper.
### for vision models
* remember to specify a mmproj file directly or by using -hf to fetch the model and its mmproj gguf
from huggingface.
* additionally specify a large enough -batch-size (ex 8k) and -ubatch-size (ex 2k)
### using the front end ### using the front end
@ -158,7 +165,10 @@ Once inside
* this allows for the subsequent user chatting to be driven by the new system prompt set above. * this allows for the subsequent user chatting to be driven by the new system prompt set above.
* Enter your query and either press enter or click on the submit button. * Enter your query and either press enter or click on the submit button.
If you want to insert enter (\n) as part of your chat/query to ai model, use shift+enter. * If you want to insert enter (\n) as part of your chat/query to ai model, use shift+enter.
* If the tool response has been placed into user input textarea, its color is changed to help user
identify the same easily.
* allow user to specify a image file, for vision models.
* Wait for the logic to communicate with the server and get the response. * Wait for the logic to communicate with the server and get the response.
* the user is not allowed to enter any fresh query during this time. * the user is not allowed to enter any fresh query during this time.
@ -705,6 +715,20 @@ sliding window based drop off or even before they kick in, this can help in many
color to match the tool role chat message block color, so that user can easily know that the input color to match the tool role chat message block color, so that user can easily know that the input
area is being used for submitting tool response or user response, at any given moment in time. area is being used for submitting tool response or user response, at any given moment in time.
* Vision
* Add image_url field. Allow user to load image, which is inturn stored as a dataURL in image_url.
* when user presses submit with a message, if there is some content (image for now) in dataURL,
then initialise image_url field with same.
* when generating chat messages for ai server network handshake, create the mixed content type of
content field which includes both the text (from content field) and image (from image_url field)
ie if a image_url is found wrt a image.
* follow the openai format/template wrt these mixed content messages.
* Usage: specify a mmproj file directly or through -hf, additionally had to set --batch-size to 8k
and ubatch-size to 2k wrt gemma3-4b-it
* SimpleChat class now allows extra fields to be specified while adding, in a generic way using a
object/literal object or equivalent.
#### ToDo #### ToDo

View File

@ -570,6 +570,7 @@ class SimpleChat {
tMixed.push({"type": "text", "text": tContent}) tMixed.push({"type": "text", "text": tContent})
} }
tMixed.push({"type": "image_url", "image_url": {"url": tmsg.ns.image_url}}) tMixed.push({"type": "image_url", "image_url": {"url": tmsg.ns.image_url}})
//tMixed.push({"type": "image", "image": tmsg.ns.image_url})
// @ts-ignore // @ts-ignore
tmsg.ns.content = tMixed tmsg.ns.content = tMixed
tmsg.ns_delete("image_url") tmsg.ns_delete("image_url")
@ -587,8 +588,9 @@ class SimpleChat {
* NOTE: A new copy is created and added into xchat. * NOTE: A new copy is created and added into xchat.
* Also update iLastSys system prompt index tracker * Also update iLastSys system prompt index tracker
* @param {ChatMessageEx} chatMsg * @param {ChatMessageEx} chatMsg
* @param {Object<string,any>|undefined} extra - optional additional fieldName=Value pairs to be added, if any
*/ */
add(chatMsg) { add(chatMsg, extra=undefined) {
if (this.xchat.length > 0) { if (this.xchat.length > 0) {
let lastIndex = this.xchat.length - 1; let lastIndex = this.xchat.length - 1;
if (this.xchat[lastIndex].ns.role == Roles.ToolTemp) { if (this.xchat[lastIndex].ns.role == Roles.ToolTemp) {
@ -600,6 +602,11 @@ class SimpleChat {
if (chatMsg.ns.role == Roles.System) { if (chatMsg.ns.role == Roles.System) {
this.iLastSys = this.xchat.length - 1; this.iLastSys = this.xchat.length - 1;
} }
if (extra) {
for (const key in extra) {
this.xchat[this.xchat.length-1].ns_set_extra(key, extra[key])
}
}
this.save(); this.save();
return true; return true;
} }
@ -956,7 +963,8 @@ class MultiChatUI {
// Save any placeholder set by default like through html, to restore where needed // Save any placeholder set by default like through html, to restore where needed
this.elInUser.dataset.placeholder = this.elInUser.placeholder this.elInUser.dataset.placeholder = this.elInUser.placeholder
this.elInFileX = ui.el_creatediv_inputfile('file', 'file', '', ()=>{ // Setup Image loading button and flow
this.elInFileX = ui.el_creatediv_inputfile('image', 'image', '', ()=>{
let f0 = this.elInFileX.el.files?.item(0); let f0 = this.elInFileX.el.files?.item(0);
if (!f0) { if (!f0) {
return return
@ -1341,7 +1349,12 @@ class MultiChatUI {
this.elInUser.placeholder = "dont forget to enter a message, before submitting to ai" this.elInUser.placeholder = "dont forget to enter a message, before submitting to ai"
return; return;
} }
chat.add(new ChatMessageEx(new NSChatMessage(Roles.User, content))) let image = undefined
if (this.me.dataURLs.length > 0) {
image = /** @type{string} */(this.me.dataURLs[0])
this.me.dataURLs.pop()
}
chat.add(new ChatMessageEx(new NSChatMessage(Roles.User, content, undefined, undefined, undefined, undefined, image)))
} }
if (this.elInUser.dataset.placeholder) { if (this.elInUser.dataset.placeholder) {
this.elInUser.placeholder = this.elInUser.dataset.placeholder; this.elInUser.placeholder = this.elInUser.dataset.placeholder;