SimpleChatTCRV:MultipleImages:Update ChatMessage++ wrt same

Now NSChatMessage inturn ChatMessageEx, ... have been updated
to maintain a array of image data instead of a single image.

Inturn the ShowMessage as well as submit logics have been updated
to account for multiple images.

Also fix a oversight from previous commit, where when pushing new
image, I had forgotten to remove the old logic, which would have
always updated the 0th image data in the array.
This commit is contained in:
hanishkvc 2025-11-20 19:45:48 +05:30
parent 08ea5c364c
commit 122c96e8a9
1 changed files with 20 additions and 17 deletions

View File

@ -78,16 +78,16 @@ class NSChatMessage {
* @param {Array<NSToolCall>|undefined} tool_calls * @param {Array<NSToolCall>|undefined} tool_calls
* @param {string|undefined} tool_call_id - toolcall response - the tool / function call id * @param {string|undefined} tool_call_id - toolcall response - the tool / function call id
* @param {string|undefined} name - toolcall response - the tool / function call name * @param {string|undefined} name - toolcall response - the tool / function call name
* @param {string|undefined} image_url - a image url for vision models * @param {Array<string>|undefined} image_urls - a image url for vision models
*/ */
constructor(role = "", content=undefined, reasoning_content=undefined, tool_calls=undefined, tool_call_id=undefined, name=undefined, image_url=undefined) { constructor(role = "", content=undefined, reasoning_content=undefined, tool_calls=undefined, tool_call_id=undefined, name=undefined, image_urls=undefined) {
this.role = role; this.role = role;
this.content = content; this.content = content;
this.reasoning_content = reasoning_content this.reasoning_content = reasoning_content
this.tool_calls = structuredClone(tool_calls) this.tool_calls = structuredClone(tool_calls)
this.tool_call_id = tool_call_id this.tool_call_id = tool_call_id
this.name = name this.name = name
this.image_url = image_url this.image_urls = structuredClone(image_urls)
} }
/** /**
@ -287,7 +287,7 @@ class ChatMessageEx {
* @param {ChatMessageEx} old * @param {ChatMessageEx} old
*/ */
static newFrom(old) { static newFrom(old) {
return new ChatMessageEx(new NSChatMessage(old.ns.role, old.ns.content, old.ns.reasoning_content, old.ns.tool_calls, old.ns.tool_call_id, old.ns.name, old.ns.image_url), old.trimmedContent) return new ChatMessageEx(new NSChatMessage(old.ns.role, old.ns.content, old.ns.reasoning_content, old.ns.tool_calls, old.ns.tool_call_id, old.ns.name, old.ns.image_urls), old.trimmedContent)
} }
clear() { clear() {
@ -533,7 +533,7 @@ class SimpleChat {
this.iLastSys = ods.iLastSys; this.iLastSys = ods.iLastSys;
this.xchat = []; this.xchat = [];
for (const cur of ods.xchat) { for (const cur of ods.xchat) {
this.xchat.push(new ChatMessageEx(new NSChatMessage(cur.ns.role, cur.ns.content, cur.ns.reasoning_content, cur.ns.tool_calls, cur.ns.tool_call_id, cur.ns.name, cur.ns.image_url), cur.trimmedContent)) this.xchat.push(new ChatMessageEx(new NSChatMessage(cur.ns.role, cur.ns.content, cur.ns.reasoning_content, cur.ns.tool_calls, cur.ns.tool_call_id, cur.ns.name, cur.ns.image_urls), cur.trimmedContent))
} }
cb(true, status, related) cb(true, status, related)
} else { } else {
@ -610,7 +610,7 @@ class SimpleChat {
if (tmsg.ns.getReasoningContent() === "") { if (tmsg.ns.getReasoningContent() === "") {
tmsg.ns_delete("reasoning_content") tmsg.ns_delete("reasoning_content")
} }
if (tmsg.ns.image_url) { if (tmsg.ns.image_urls) {
// Has I need to know if really there or if undefined, so direct access and not through getContent helper. // Has I need to know if really there or if undefined, so direct access and not through getContent helper.
let tContent = tmsg.ns.content let tContent = tmsg.ns.content
/** @type{NSMixedContent} */ /** @type{NSMixedContent} */
@ -618,8 +618,10 @@ class SimpleChat {
if (tContent) { if (tContent) {
tMixed.push({"type": "text", "text": tContent}) tMixed.push({"type": "text", "text": tContent})
} }
tMixed.push({"type": "image_url", "image_url": {"url": tmsg.ns.image_url}}) for (const imgUrl of tmsg.ns.image_urls) {
//tMixed.push({"type": "image", "image": tmsg.ns.image_url}) tMixed.push({"type": "image_url", "image_url": {"url": imgUrl}})
//tMixed.push({"type": "image", "image": imgUrl})
}
// @ts-ignore // @ts-ignore
tmsg.ns.content = tMixed tmsg.ns.content = tMixed
tmsg.ns_delete("image_url") tmsg.ns_delete("image_url")
@ -1175,7 +1177,6 @@ class MultiChatUI {
dataurl_plus_add(dataUrl) { dataurl_plus_add(dataUrl) {
if (typeof(dataUrl) == 'string') { if (typeof(dataUrl) == 'string') {
this.me.dataURLs.push(dataUrl) this.me.dataURLs.push(dataUrl)
this.me.dataURLs[0] = dataUrl
let elImg = document.createElement('img') let elImg = document.createElement('img')
elImg.src = dataUrl elImg.src = dataUrl
this.elDivUserInImgs.appendChild(elImg) this.elDivUserInImgs.appendChild(elImg)
@ -1324,12 +1325,14 @@ class MultiChatUI {
} }
} }
// Handle Image // Handle Image
if (msg.ns.image_url) { if (msg.ns.image_urls) {
for (const imgUrl of msg.ns.image_urls) {
let img = document.createElement('img') let img = document.createElement('img')
img.classList.add('chat-message-img') img.classList.add('chat-message-img')
img.src = msg.ns.image_url img.src = imgUrl
secContents?.append(img) secContents?.append(img)
} }
}
// Handle tool call edit/trigger ui, if reqd // Handle tool call edit/trigger ui, if reqd
let bTC = false let bTC = false
let bAuto = false let bAuto = false
@ -1671,11 +1674,11 @@ class MultiChatUI {
return; return;
} }
try { try {
let image = undefined let images = undefined
if (this.me.dataURLs.length > 0) { if (this.me.dataURLs.length > 0) {
image = this.dataurl_get(0) images = /** @type{Array<string>} */(this.me.dataURLs)
} }
this.chatmsg_addsmart_uishow(chat.chatId, new ChatMessageEx(new NSChatMessage(Roles.User, content, undefined, undefined, undefined, undefined, image))) this.chatmsg_addsmart_uishow(chat.chatId, new ChatMessageEx(new NSChatMessage(Roles.User, content, undefined, undefined, undefined, undefined, images)))
} catch (err) { } catch (err) {
throw new Error("HandleUserSubmit:ChatAddShow failure", {cause: err}) throw new Error("HandleUserSubmit:ChatAddShow failure", {cause: err})
} finally { } finally {