SimpleChatTC:Vision: Prepare NSChatMessage for Text &| Image

Avoid directly accessing content field, from any place other than
where it is absolutely requried.

Add a bOverwrite field to the content_adj helper, so that one can
overwrite instead of appending passed content to whats already in.

* this is currently used only wrt
  * promote_tooltemp helper
  * trim garbage helper
* the oneshot could ideally use overwriting, but currently
  not doing as this flow will occur only once per message

Add a image_url field for the image url with image data in dataurl
format with base64 encoded image data.
This commit is contained in:
hanishkvc 2025-11-09 21:13:46 +05:30
parent 8079618c85
commit 5db6f927df
1 changed files with 23 additions and 14 deletions

View File

@ -67,14 +67,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
*/ */
constructor(role = "", content=undefined, reasoning_content=undefined, tool_calls=undefined, tool_call_id=undefined, name=undefined) { constructor(role = "", content=undefined, reasoning_content=undefined, tool_calls=undefined, tool_call_id=undefined, name=undefined, image_url=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
} }
/** /**
@ -142,17 +144,24 @@ class NSChatMessage {
} }
/** /**
* Append to the content, if already exists * Creates/Defines the content field if undefined.
* Else create the content. * If already defined, based on bOverwrite either
* * appends to the existing content or
* * overwrite the existing content
* @param {string} content * @param {string} content
* @param {boolean} bOverwrite
*/ */
content_adj(content="") { content_adj(content="", bOverwrite=false) {
if (this.content == undefined) { if (this.content == undefined) {
this.content = content this.content = content
} else {
if (bOverwrite) {
this.content = content
} else { } else {
this.content += content this.content += content
} }
} }
}
/** /**
* Append to the reasoningContent, if already exists * Append to the reasoningContent, if already exists
@ -344,7 +353,7 @@ class ChatMessageEx {
let curContent = nwo["choices"][0]["message"]["content"]; let curContent = nwo["choices"][0]["message"]["content"];
if (curContent != undefined) { if (curContent != undefined) {
if (curContent != null) { if (curContent != null) {
this.ns.content = curContent; this.ns.content_adj(curContent)
} }
} }
let curRC = nwo["choices"][0]["message"]["reasoning_content"]; let curRC = nwo["choices"][0]["message"]["reasoning_content"];
@ -357,9 +366,9 @@ class ChatMessageEx {
} }
} else { } else {
try { try {
this.ns.content = nwo["choices"][0]["text"]; this.ns.content_adj(nwo["choices"][0]["text"]);
} catch { } catch {
this.ns.content = nwo["content"]; this.ns.content_adj(nwo["content"]);
} }
} }
} }
@ -585,7 +594,7 @@ class SimpleChat {
return return
} }
this.xchat[lastIndex].ns.role = Roles.Tool; this.xchat[lastIndex].ns.role = Roles.Tool;
this.xchat[lastIndex].ns.content = content; this.xchat[lastIndex].ns.content_adj(content, true);
} }
/** /**
@ -651,7 +660,7 @@ class SimpleChat {
if (bInsertStandardRolePrefix) { if (bInsertStandardRolePrefix) {
prompt += `${msg.ns.role}: `; prompt += `${msg.ns.role}: `;
} }
prompt += `${msg.ns.content}`; prompt += `${msg.ns.getContent()}`;
} }
let req = { let req = {
prompt: prompt, prompt: prompt,
@ -687,7 +696,7 @@ class SimpleChat {
return this.add(new ChatMessageEx(new NSChatMessage(Roles.System, sysPrompt))); return this.add(new ChatMessageEx(new NSChatMessage(Roles.System, sysPrompt)));
} }
let lastSys = this.xchat[this.iLastSys].ns.content; let lastSys = this.xchat[this.iLastSys].ns.getContent();
if (lastSys !== sysPrompt) { if (lastSys !== sysPrompt) {
return this.add(new ChatMessageEx(new NSChatMessage(Roles.System, sysPrompt))); return this.add(new ChatMessageEx(new NSChatMessage(Roles.System, sysPrompt)));
} }
@ -796,10 +805,10 @@ class SimpleChat {
theResp = await this.handle_response_oneshot(resp, apiEP); theResp = await this.handle_response_oneshot(resp, apiEP);
} }
if (this.me.chatProps.bTrimGarbage) { if (this.me.chatProps.bTrimGarbage) {
let origMsg = theResp.ns.content; let origMsg = theResp.ns.getContent();
if (origMsg) { if (origMsg) {
theResp.ns.content = du.trim_garbage_at_end(origMsg); theResp.ns.content_adj(du.trim_garbage_at_end(origMsg), true);
theResp.trimmedContent = origMsg.substring(theResp.ns.content.length); theResp.trimmedContent = origMsg.substring(theResp.ns.getContent().length);
} }
} }
theResp.ns.role = Roles.Assistant; theResp.ns.role = Roles.Assistant;