SimpleChat: Cleanup a bit wrt Api end point related flow

Consolidate many of the Api end point related basic meta data into
ApiEP class.

Remove the hardcoded ApiEP/Mode settings from html+js, instead use
the generic select helper logic, inturn in the settings block.

Move helper to generate the appropriate request json string based
on ApiEP into SimpleChat class itself.
This commit is contained in:
HanishKVC 2024-05-27 18:45:42 +05:30
parent f9fc543190
commit b2c10b960d
2 changed files with 43 additions and 32 deletions

View file

@ -22,16 +22,9 @@
<body> <body>
<div class="samecolumn" id="fullbody"> <div class="samecolumn" id="fullbody">
<div class="sameline"> <div class="sameline" id="heading">
<p class="heading flex-grow" > <b> SimpleChat </b> </p> <p class="heading flex-grow" > <b> SimpleChat </b> </p>
<button id="settings">Settings</button> <button id="settings">Settings</button>
<div class="sameline">
<label for="api-ep">Mode:</label>
<select name="api-ep" id="api-ep">
<option value="chat" selected>Chat</option>
<option value="completion">Completion</option>
</select>
</div>
</div> </div>
<div id="sessions-div" class="sameline"></div> <div id="sessions-div" class="sameline"></div>

View file

@ -11,10 +11,19 @@ class Roles {
static Assistant = "assistant"; static Assistant = "assistant";
} }
let gBaseURL = "http://127.0.0.1:8080";
class ApiEP { class ApiEP {
static Chat = "chat"; static Type = {
static Completion = "completion"; Chat: "chat",
Completion: "completion",
} }
static Url = {
'chat': `${gBaseURL}/chat/completions`,
'completion': `${gBaseURL}/completions`,
}
}
let gUsageMsg = ` let gUsageMsg = `
<p class="role-system">Usage</p> <p class="role-system">Usage</p>
@ -35,6 +44,7 @@ let gUsageMsg = `
</ul> </ul>
`; `;
/** @typedef {{role: string, content: string}[]} ChatMessages */ /** @typedef {{role: string, content: string}[]} ChatMessages */
class SimpleChat { class SimpleChat {
@ -144,7 +154,7 @@ class SimpleChat {
* Convert the json into string. * Convert the json into string.
* @param {Object} obj * @param {Object} obj
*/ */
request_jsonstr(obj) { request_jsonstr_extend(obj) {
for(let k in gMe.chatRequestOptions) { for(let k in gMe.chatRequestOptions) {
obj[k] = gMe.chatRequestOptions[k]; obj[k] = gMe.chatRequestOptions[k];
} }
@ -158,7 +168,7 @@ class SimpleChat {
let req = { let req = {
messages: this.recent_chat(gMe.iRecentUserMsgCnt), messages: this.recent_chat(gMe.iRecentUserMsgCnt),
} }
return this.request_jsonstr(req); return this.request_jsonstr_extend(req);
} }
/** /**
@ -181,7 +191,19 @@ class SimpleChat {
let req = { let req = {
prompt: prompt, prompt: prompt,
} }
return this.request_jsonstr(req); return this.request_jsonstr_extend(req);
}
/**
* Return a string form of json object suitable for specified api endpoint.
* @param {string} apiEP
*/
request_jsonstr(apiEP) {
if (apiEP == ApiEP.Type.Chat) {
return this.request_messages_jsonstr();
} else {
return this.request_prompt_jsonstr(gMe.bCompletionInsertStandardRolePrefix);
}
} }
/** /**
@ -243,13 +265,6 @@ class SimpleChat {
} }
let gBaseURL = "http://127.0.0.1:8080";
let gChatURL = {
'chat': `${gBaseURL}/chat/completions`,
'completion': `${gBaseURL}/completions`,
}
class MultiChatUI { class MultiChatUI {
constructor() { constructor() {
@ -263,14 +278,14 @@ class MultiChatUI {
this.elDivChat = /** @type{HTMLDivElement} */(document.getElementById("chat-div")); this.elDivChat = /** @type{HTMLDivElement} */(document.getElementById("chat-div"));
this.elBtnUser = /** @type{HTMLButtonElement} */(document.getElementById("user-btn")); this.elBtnUser = /** @type{HTMLButtonElement} */(document.getElementById("user-btn"));
this.elInUser = /** @type{HTMLInputElement} */(document.getElementById("user-in")); this.elInUser = /** @type{HTMLInputElement} */(document.getElementById("user-in"));
this.elSelectApiEP = /** @type{HTMLSelectElement} */(document.getElementById("api-ep")); this.elDivHeading = /** @type{HTMLSelectElement} */(document.getElementById("heading"));
this.elDivSessions = /** @type{HTMLDivElement} */(document.getElementById("sessions-div")); this.elDivSessions = /** @type{HTMLDivElement} */(document.getElementById("sessions-div"));
this.elBtnSettings = /** @type{HTMLButtonElement} */(document.getElementById("settings")); this.elBtnSettings = /** @type{HTMLButtonElement} */(document.getElementById("settings"));
this.validate_element(this.elInSystem, "system-in"); this.validate_element(this.elInSystem, "system-in");
this.validate_element(this.elDivChat, "chat-div"); this.validate_element(this.elDivChat, "chat-div");
this.validate_element(this.elInUser, "user-in"); this.validate_element(this.elInUser, "user-in");
this.validate_element(this.elSelectApiEP, "api-ep"); this.validate_element(this.elDivHeading, "heading");
this.validate_element(this.elDivChat, "sessions-div"); this.validate_element(this.elDivChat, "sessions-div");
this.validate_element(this.elBtnSettings, "settings"); this.validate_element(this.elBtnSettings, "settings");
} }
@ -322,7 +337,7 @@ class MultiChatUI {
if (this.elInUser.disabled) { if (this.elInUser.disabled) {
return; return;
} }
this.handle_user_submit(this.curChatId, this.elSelectApiEP.value).catch((/** @type{Error} */reason)=>{ this.handle_user_submit(this.curChatId, gMe.apiEP).catch((/** @type{Error} */reason)=>{
let msg = `ERRR:SimpleChat\nMCUI:HandleUserSubmit:${this.curChatId}\n${reason.name}:${reason.message}`; let msg = `ERRR:SimpleChat\nMCUI:HandleUserSubmit:${this.curChatId}\n${reason.name}:${reason.message}`;
console.debug(msg.replace("\n", ":")); console.debug(msg.replace("\n", ":"));
alert(msg); alert(msg);
@ -402,7 +417,7 @@ class MultiChatUI {
// So if user wants to simulate a multi-chat based completion query, // So if user wants to simulate a multi-chat based completion query,
// they will have to enter the full thing, as a suitable multiline // they will have to enter the full thing, as a suitable multiline
// user input/query. // user input/query.
if ((apiEP == ApiEP.Completion) && (gMe.bCompletionFreshChatAlways)) { if ((apiEP == ApiEP.Type.Completion) && (gMe.bCompletionFreshChatAlways)) {
chat.clear(); chat.clear();
} }
@ -415,13 +430,8 @@ class MultiChatUI {
} }
chat.show(this.elDivChat); chat.show(this.elDivChat);
let theBody; let theUrl = ApiEP.Url[apiEP];
let theUrl = gChatURL[apiEP] let theBody = chat.request_jsonstr(apiEP);
if (apiEP == ApiEP.Chat) {
theBody = chat.request_messages_jsonstr();
} else {
theBody = chat.request_prompt_jsonstr(gMe.bCompletionInsertStandardRolePrefix);
}
this.elInUser.value = "working..."; this.elInUser.value = "working...";
this.elInUser.disabled = true; this.elInUser.disabled = true;
@ -439,7 +449,7 @@ class MultiChatUI {
console.debug(`DBUG:SimpleChat:MCUI:${chatId}:HandleUserSubmit:RespBody:${JSON.stringify(respBody)}`); console.debug(`DBUG:SimpleChat:MCUI:${chatId}:HandleUserSubmit:RespBody:${JSON.stringify(respBody)}`);
let assistantMsg; let assistantMsg;
let trimmedMsg = ""; let trimmedMsg = "";
if (apiEP == ApiEP.Chat) { if (apiEP == ApiEP.Type.Chat) {
assistantMsg = respBody["choices"][0]["message"]["content"]; assistantMsg = respBody["choices"][0]["message"]["content"];
} else { } else {
try { try {
@ -557,6 +567,7 @@ class Me {
"Last1": 2, "Last1": 2,
"Last2": 3, "Last2": 3,
}; };
this.apiEP = ApiEP.Type.Chat;
// Add needed fields wrt json object to be sent wrt LLM web services completions endpoint. // Add needed fields wrt json object to be sent wrt LLM web services completions endpoint.
this.chatRequestOptions = { this.chatRequestOptions = {
"temperature": 0.7, "temperature": 0.7,
@ -586,6 +597,8 @@ class Me {
ui.el_create_append_p(`chatRequestOptions:${JSON.stringify(this.chatRequestOptions)}`, elDiv); ui.el_create_append_p(`chatRequestOptions:${JSON.stringify(this.chatRequestOptions)}`, elDiv);
ui.el_create_append_p(`ApiEndPoint:${this.apiEP}`, elDiv);
} }
/** /**
@ -614,6 +627,11 @@ class Me {
}); });
elDiv.appendChild(sel); elDiv.appendChild(sel);
sel = ui.el_creatediv_select("SetApiEP", "ApiEndPoint", ApiEP.Type, this.apiEP, (val)=>{
this.apiEP = ApiEP.Type[val];
});
elDiv.appendChild(sel);
} }
} }