11// @ts -check
2- // A simple completions and chat/completions test related web front end logic
2+ // Core classes which provide a simple implementation of handshake with ai server's completions and chat/completions endpoints
3+ // as well as related web front end logic for basic usage and testing.
34// by Humans for All
45
56import * as du from "./datautils.mjs" ;
@@ -277,7 +278,10 @@ class ChatMessageEx {
277278}
278279
279280
280- function usage_note ( ) {
281+ /**
282+ * @param {number } iRecentUserMsgCnt
283+ */
284+ function usage_note ( iRecentUserMsgCnt ) {
281285 let sUsageNote = `
282286 <details>
283287 <summary id="UsageNote" class="role-system">Usage Note</summary>
@@ -293,7 +297,7 @@ function usage_note() {
293297 <li> If ai assistant requests a tool call, verify same before triggering.</li>
294298 <li> submit tool response placed into user query/response text area</li>
295299 </ul>
296- <li> ContextWindow = [System, Last[${ gMe . chatProps . iRecentUserMsgCnt - 1 } ] User Query/Resp, Cur Query].</li>
300+ <li> ContextWindow = [System, Last[${ iRecentUserMsgCnt } ] User Query/Resp, Cur Query].</li>
297301 <ul class="ul2">
298302 <li> ChatHistInCtxt, MaxTokens, ModelCtxt window to expand</li>
299303 </ul>
@@ -311,8 +315,9 @@ class SimpleChat {
311315
312316 /**
313317 * @param {string } chatId
318+ * @param {Me } me
314319 */
315- constructor ( chatId ) {
320+ constructor ( chatId , me ) {
316321 this . chatId = chatId ;
317322 /**
318323 * Maintain in a form suitable for common LLM web service chat/completions' messages entry
@@ -321,6 +326,7 @@ class SimpleChat {
321326 this . xchat = [ ] ;
322327 this . iLastSys = - 1 ;
323328 this . latestResponse = new ChatMessageEx ( ) ;
329+ this . me = me ;
324330 }
325331
326332 clear ( ) {
@@ -485,14 +491,14 @@ class SimpleChat {
485491
486492 /**
487493 * Setup the fetch headers.
488- * It picks the headers from gMe .headers.
494+ * It picks the headers from this.me .headers.
489495 * It inserts Authorization only if its non-empty.
490496 * @param {string } apiEP
491497 */
492498 fetch_headers ( apiEP ) {
493499 let headers = new Headers ( ) ;
494- for ( let k in gMe . headers ) {
495- let v = gMe . headers [ k ] ;
500+ for ( let k in this . me . headers ) {
501+ let v = this . me . headers [ k ] ;
496502 if ( ( k == "Authorization" ) && ( v . trim ( ) == "" ) ) {
497503 continue ;
498504 }
@@ -509,13 +515,13 @@ class SimpleChat {
509515 * @param {Object<string, any> } obj
510516 */
511517 request_jsonstr_extend ( obj ) {
512- for ( let k in gMe . apiRequestOptions ) {
513- obj [ k ] = gMe . apiRequestOptions [ k ] ;
518+ for ( let k in this . me . apiRequestOptions ) {
519+ obj [ k ] = this . me . apiRequestOptions [ k ] ;
514520 }
515- if ( gMe . chatProps . stream ) {
521+ if ( this . me . chatProps . stream ) {
516522 obj [ "stream" ] = true ;
517523 }
518- if ( gMe . tools . enabled ) {
524+ if ( this . me . tools . enabled ) {
519525 obj [ "tools" ] = tools . meta ( ) ;
520526 }
521527 return JSON . stringify ( obj ) ;
@@ -526,7 +532,7 @@ class SimpleChat {
526532 */
527533 request_messages_jsonstr ( ) {
528534 let req = {
529- messages : this . recent_chat_ns ( gMe . chatProps . iRecentUserMsgCnt ) ,
535+ messages : this . recent_chat_ns ( this . me . chatProps . iRecentUserMsgCnt ) ,
530536 }
531537 return this . request_jsonstr_extend ( req ) ;
532538 }
@@ -538,7 +544,7 @@ class SimpleChat {
538544 request_prompt_jsonstr ( bInsertStandardRolePrefix ) {
539545 let prompt = "" ;
540546 let iCnt = 0 ;
541- for ( const msg of this . recent_chat ( gMe . chatProps . iRecentUserMsgCnt ) ) {
547+ for ( const msg of this . recent_chat ( this . me . chatProps . iRecentUserMsgCnt ) ) {
542548 iCnt += 1 ;
543549 if ( iCnt > 1 ) {
544550 prompt += "\n" ;
@@ -562,7 +568,7 @@ class SimpleChat {
562568 if ( apiEP == ApiEP . Type . Chat ) {
563569 return this . request_messages_jsonstr ( ) ;
564570 } else {
565- return this . request_prompt_jsonstr ( gMe . chatProps . bCompletionInsertStandardRolePrefix ) ;
571+ return this . request_prompt_jsonstr ( this . me . chatProps . bCompletionInsertStandardRolePrefix ) ;
566572 }
567573 }
568574
@@ -676,7 +682,7 @@ class SimpleChat {
676682 */
677683 async handle_response ( resp , apiEP , elDiv ) {
678684 let theResp = null ;
679- if ( gMe . chatProps . stream ) {
685+ if ( this . me . chatProps . stream ) {
680686 try {
681687 theResp = await this . handle_response_multipart ( resp , apiEP , elDiv ) ;
682688 this . latestResponse . clear ( ) ;
@@ -690,7 +696,7 @@ class SimpleChat {
690696 } else {
691697 theResp = await this . handle_response_oneshot ( resp , apiEP ) ;
692698 }
693- if ( gMe . chatProps . bTrimGarbage ) {
699+ if ( this . me . chatProps . bTrimGarbage ) {
694700 let origMsg = theResp . ns . content ;
695701 theResp . ns . content = du . trim_garbage_at_end ( origMsg ) ;
696702 theResp . trimmedContent = origMsg . substring ( theResp . ns . content . length ) ;
@@ -756,7 +762,11 @@ class SimpleChat {
756762
757763class MultiChatUI {
758764
759- constructor ( ) {
765+ /**
766+ * @param {Me } me
767+ */
768+ constructor ( me ) {
769+ this . me = me
760770 /** @type {Object<string, SimpleChat> } */
761771 this . simpleChats = { } ;
762772 /** @type {string } */
@@ -842,10 +852,10 @@ class MultiChatUI {
842852 this . elInToolName . dataset . tool_call_id = ar . ns . tool_calls [ 0 ] . id
843853 this . elInToolArgs . value = ar . ns . tool_calls [ 0 ] . function . arguments
844854 this . elBtnTool . disabled = false
845- if ( ( gMe . tools . autoSecs > 0 ) && ( bAuto ) ) {
855+ if ( ( this . me . tools . autoSecs > 0 ) && ( bAuto ) ) {
846856 this . timers . toolcallTriggerClick = setTimeout ( ( ) => {
847857 this . elBtnTool . click ( )
848- } , gMe . tools . autoSecs * this . TimePeriods . ToolCallAutoSecsTimeUnit )
858+ } , this . me . tools . autoSecs * this . TimePeriods . ToolCallAutoSecsTimeUnit )
849859 }
850860 } else {
851861 this . elDivTool . hidden = true
@@ -992,7 +1002,7 @@ class MultiChatUI {
9921002 this . ui_reset_toolcall_as_needed ( new ChatMessageEx ( ) ) ;
9931003 }
9941004 this . elLastChatMessage = null
995- let chatToShow = chat . recent_chat ( gMe . chatProps . iRecentUserMsgCnt ) ;
1005+ let chatToShow = chat . recent_chat ( this . me . chatProps . iRecentUserMsgCnt ) ;
9961006 for ( const [ i , x ] of chatToShow . entries ( ) ) {
9971007 let iFromLast = ( chatToShow . length - 1 ) - i
9981008 let nextMsg = undefined
@@ -1005,9 +1015,9 @@ class MultiChatUI {
10051015 /** @type {HTMLElement } */ ( this . elLastChatMessage ) . scrollIntoView ( false ) ; // Stupid ts-check js-doc intersection ???
10061016 } else {
10071017 if ( bClear ) {
1008- this . elDivChat . innerHTML = usage_note ( ) ;
1009- gMe . setup_load ( this . elDivChat , chat ) ;
1010- gMe . show_info ( this . elDivChat , bShowInfoAll ) ;
1018+ this . elDivChat . innerHTML = usage_note ( this . me . chatProps . iRecentUserMsgCnt - 1 ) ;
1019+ this . me . setup_load ( this . elDivChat , chat ) ;
1020+ this . me . show_info ( this . elDivChat , bShowInfoAll ) ;
10111021 }
10121022 }
10131023 return true
@@ -1030,7 +1040,7 @@ class MultiChatUI {
10301040
10311041 this . elBtnSettings . addEventListener ( "click" , ( ev ) => {
10321042 this . elDivChat . replaceChildren ( ) ;
1033- gMe . show_settings ( this . elDivChat ) ;
1043+ this . me . show_settings ( this . elDivChat ) ;
10341044 } ) ;
10351045 this . elBtnClearChat . addEventListener ( "click" , ( ev ) => {
10361046 this . simpleChats [ this . curChatId ] . clear ( )
@@ -1043,7 +1053,7 @@ class MultiChatUI {
10431053 if ( this . elInUser . disabled ) {
10441054 return ;
10451055 }
1046- this . handle_user_submit ( this . curChatId , gMe . chatProps . apiEP ) . catch ( ( /** @type {Error } */ reason ) => {
1056+ this . handle_user_submit ( this . curChatId , this . me . chatProps . apiEP ) . catch ( ( /** @type {Error } */ reason ) => {
10471057 let msg = `ERRR:SimpleChat\nMCUI:HandleUserSubmit:${ this . curChatId } \n${ reason . name } :${ reason . message } ` ;
10481058 console . error ( msg . replace ( "\n" , ":" ) ) ;
10491059 alert ( msg ) ;
@@ -1065,17 +1075,17 @@ class MultiChatUI {
10651075 this . timers . toolcallResponseTimeout = undefined
10661076 let chat = this . simpleChats [ cid ] ;
10671077 let limitedData = data
1068- if ( gMe . tools . iResultMaxDataLength > 0 ) {
1069- if ( data . length > gMe . tools . iResultMaxDataLength ) {
1070- limitedData = data . slice ( 0 , gMe . tools . iResultMaxDataLength ) + `\n\n\nALERT: Data too long, was chopped ....`
1078+ if ( this . me . tools . iResultMaxDataLength > 0 ) {
1079+ if ( data . length > this . me . tools . iResultMaxDataLength ) {
1080+ limitedData = data . slice ( 0 , this . me . tools . iResultMaxDataLength ) + `\n\n\nALERT: Data too long, was chopped ....`
10711081 }
10721082 }
10731083 chat . add ( new ChatMessageEx ( Roles . ToolTemp , ChatMessageEx . createToolCallResultAllInOne ( tcid , name , limitedData ) ) )
10741084 if ( this . chat_show ( cid ) ) {
1075- if ( gMe . tools . autoSecs > 0 ) {
1085+ if ( this . me . tools . autoSecs > 0 ) {
10761086 this . timers . toolcallResponseSubmitClick = setTimeout ( ( ) => {
10771087 this . elBtnUser . click ( )
1078- } , gMe . tools . autoSecs * this . TimePeriods . ToolCallAutoSecsTimeUnit )
1088+ } , this . me . tools . autoSecs * this . TimePeriods . ToolCallAutoSecsTimeUnit )
10791089 }
10801090 }
10811091 this . ui_reset_userinput ( false )
@@ -1113,7 +1123,7 @@ class MultiChatUI {
11131123 * @param {boolean } bSwitchSession
11141124 */
11151125 new_chat_session ( chatId , bSwitchSession = false ) {
1116- this . simpleChats [ chatId ] = new SimpleChat ( chatId ) ;
1126+ this . simpleChats [ chatId ] = new SimpleChat ( chatId , this . me ) ;
11171127 if ( bSwitchSession ) {
11181128 this . handle_session_switch ( chatId ) ;
11191129 }
@@ -1143,7 +1153,7 @@ class MultiChatUI {
11431153 // So if user wants to simulate a multi-chat based completion query,
11441154 // they will have to enter the full thing, as a suitable multiline
11451155 // user input/query.
1146- if ( ( apiEP == ApiEP . Type . Completion ) && ( gMe . chatProps . bCompletionFreshChatAlways ) ) {
1156+ if ( ( apiEP == ApiEP . Type . Completion ) && ( this . me . chatProps . bCompletionFreshChatAlways ) ) {
11471157 chat . clear ( ) ;
11481158 }
11491159
@@ -1167,7 +1177,7 @@ class MultiChatUI {
11671177 this . elInUser . disabled = true ;
11681178
11691179 try {
1170- let theResp = await chat . handle_chat_hs ( gMe . baseURL , apiEP , this . elDivChat )
1180+ let theResp = await chat . handle_chat_hs ( this . me . baseURL , apiEP , this . elDivChat )
11711181 if ( chatId == this . curChatId ) {
11721182 this . chat_show ( chatId ) ;
11731183 if ( theResp . trimmedContent . length > 0 ) {
@@ -1206,7 +1216,7 @@ class MultiChatUI {
12061216 chat . add ( new ChatMessageEx ( Roles . ToolTemp , ChatMessageEx . createToolCallResultAllInOne ( toolCallId , toolname , `Tool/Function call ${ toolname } taking too much time, aborting...` ) ) )
12071217 this . chat_show ( chat . chatId )
12081218 this . ui_reset_userinput ( false )
1209- } , gMe . tools . toolCallResponseTimeoutMS )
1219+ } , this . me . tools . toolCallResponseTimeoutMS )
12101220 }
12111221 }
12121222
@@ -1312,12 +1322,12 @@ const SearchURLS = {
13121322}
13131323
13141324
1315- class Me {
1325+ export class Me {
13161326
13171327 constructor ( ) {
13181328 this . baseURL = "http://127.0.0.1:8080" ;
13191329 this . defaultChatIds = [ "Default" , "Other" ] ;
1320- this . multiChat = new MultiChatUI ( ) ;
1330+ this . multiChat = new MultiChatUI ( this ) ;
13211331 this . tools = {
13221332 enabled : true ,
13231333 proxyUrl : "http://127.0.0.1:3128" ,
@@ -1462,25 +1472,3 @@ class Me {
14621472}
14631473
14641474
1465- /** @type {Me } */
1466- let gMe ;
1467-
1468- function startme ( ) {
1469- console . log ( "INFO:SimpleChat:StartMe:Starting..." ) ;
1470- gMe = new Me ( ) ;
1471- gMe . debug_disable ( ) ;
1472- // @ts -ignore
1473- document [ "gMe" ] = gMe ;
1474- // @ts -ignore
1475- document [ "du" ] = du ;
1476- // @ts -ignore
1477- document [ "tools" ] = tools ;
1478- tools . init ( ) . then ( ( toolNames ) => gMe . tools . toolNames = toolNames ) . then ( ( ) => gMe . multiChat . chat_show ( gMe . multiChat . curChatId ) )
1479- for ( let cid of gMe . defaultChatIds ) {
1480- gMe . multiChat . new_chat_session ( cid ) ;
1481- }
1482- gMe . multiChat . setup_ui ( gMe . defaultChatIds [ 0 ] , true ) ;
1483- gMe . multiChat . show_sessions ( ) ;
1484- }
1485-
1486- document . addEventListener ( "DOMContentLoaded" , startme ) ;
0 commit comments