|
12 | 12 | -->
|
13 | 13 |
|
14 | 14 | <script>
|
15 |
| - const LITEVER = 159; |
| 15 | + const LITEVER = 160; |
16 | 16 | const urlParams = new URLSearchParams(window.location.search);
|
17 | 17 | const localflag = urlParams.get('local');
|
18 | 18 | const STORAGE_PREFIX = (localflag?"e_":"")+"kaihordewebui_";
|
|
3540 | 3540 | }
|
3541 | 3541 | }
|
3542 | 3542 |
|
| 3543 | + function oai_api_sync_req(targetep,oai_payload,oaiheaders) |
| 3544 | + { |
| 3545 | + fetch(targetep, { |
| 3546 | + method: 'POST', |
| 3547 | + headers: oaiheaders, |
| 3548 | + body: JSON.stringify(oai_payload), |
| 3549 | + referrerPolicy: 'no-referrer', |
| 3550 | + }) |
| 3551 | + .then((response) => response.json()) |
| 3552 | + .then((data) => { |
| 3553 | + console.log("sync finished response: " + JSON.stringify(data)); |
| 3554 | + if (custom_oai_key != "" && data.choices != null && data.choices.length > 0) { |
| 3555 | + let dch = data.choices[0]; |
| 3556 | + if (dch.text) { |
| 3557 | + synchro_polled_response = dch.text; |
| 3558 | + } |
| 3559 | + else if (dch.message) { |
| 3560 | + synchro_polled_response = dch.message.content; |
| 3561 | + |
| 3562 | + if(localsettings.opmode==1 && gametext_arr.length>0 && synchro_polled_response!="") |
| 3563 | + { |
| 3564 | + synchro_polled_response = cleanup_story_completion(synchro_polled_response); |
| 3565 | + } |
| 3566 | + } |
| 3567 | + else { |
| 3568 | + console.error("Error, unknown OAI response"); |
| 3569 | + clear_poll_flags(); |
| 3570 | + render_gametext(); |
| 3571 | + msgbox("Error, unknown OAI response"); |
| 3572 | + } |
| 3573 | + } |
| 3574 | + else { |
| 3575 | + //error occurred, maybe captcha failed |
| 3576 | + console.error("error occurred in OAI generation"); |
| 3577 | + clear_poll_flags(); |
| 3578 | + render_gametext(); |
| 3579 | + msgbox("Error occurred during text generation: " + formatError(data)); |
| 3580 | + } |
| 3581 | + }) |
| 3582 | + .catch((error) => { |
| 3583 | + console.error('Error:', error); |
| 3584 | + clear_poll_flags(); |
| 3585 | + render_gametext(); |
| 3586 | + msgbox("Error while submitting prompt: " + error); |
| 3587 | + }); |
| 3588 | + } |
| 3589 | + |
| 3590 | + function oai_api_stream_sse(sub_endpt,submit_payload,submit_headers) |
| 3591 | + { |
| 3592 | + synchro_pending_stream = ""; |
| 3593 | + let reqOpt = |
| 3594 | + {method: 'POST', |
| 3595 | + headers: submit_headers, |
| 3596 | + body: JSON.stringify(submit_payload)}; |
| 3597 | + if(globalabortcontroller) |
| 3598 | + { |
| 3599 | + reqOpt.signal = globalabortcontroller.signal; |
| 3600 | + } |
| 3601 | + fetch(sub_endpt, reqOpt) |
| 3602 | + .then(x => { |
| 3603 | + if(x.ok) |
| 3604 | + { |
| 3605 | + return x; |
| 3606 | + }else{ |
| 3607 | + return x.text().then(errdat => { |
| 3608 | + throw new Error('Error while SSE streaming: ' + errdat); |
| 3609 | + return null; |
| 3610 | + }).catch(err => { |
| 3611 | + throw new Error('Error while SSE streaming: ' + (x.statusText) + '\n' + err); |
| 3612 | + return null; |
| 3613 | + }); |
| 3614 | + } |
| 3615 | + }) |
| 3616 | + .then(resp => { |
| 3617 | + resp.body |
| 3618 | + .pipeThrough(new TextDecoderStream()) |
| 3619 | + .pipeThrough(new TransformStream({ |
| 3620 | + start(ctrl) { |
| 3621 | + ctrl.buf = ''; |
| 3622 | + }, |
| 3623 | + transform(chunk, ctrl) { |
| 3624 | + ctrl.buf += chunk; |
| 3625 | + let evs = []; |
| 3626 | + let m; |
| 3627 | + while ((m = /^data: (.*)\n\n/m.exec(ctrl.buf)) !== null) { |
| 3628 | + try{evs.push({data: JSON.parse(m[1])});} catch (e) {} |
| 3629 | + ctrl.buf = ctrl.buf.substring(m.index + m[0].length); |
| 3630 | + } |
| 3631 | + if (evs.length) { |
| 3632 | + ctrl.enqueue(evs); |
| 3633 | + } |
| 3634 | + } |
| 3635 | + })) |
| 3636 | + .pipeTo(new WritableStream({ |
| 3637 | + write(chunk) { |
| 3638 | + let was_empty = (synchro_pending_stream==""); |
| 3639 | + //cut stream if aborted |
| 3640 | + if(pending_response_id && pending_response_id != "-1" && pending_response_id != "") |
| 3641 | + { |
| 3642 | + for (let event of chunk) { |
| 3643 | + if (event.data && event.data.choices && event.data.choices.length>0) { |
| 3644 | + if(event.data.choices[0].text) |
| 3645 | + { |
| 3646 | + synchro_pending_stream += event.data.choices[0].text; |
| 3647 | + }else if(event.data.choices[0].delta && event.data.choices[0].delta.content) |
| 3648 | + { |
| 3649 | + synchro_pending_stream += event.data.choices[0].delta.content; |
| 3650 | + } |
| 3651 | + |
| 3652 | + if(event.data.choices[0].finish_reason=="stop") |
| 3653 | + { |
| 3654 | + last_stop_reason = "stop"; |
| 3655 | + } |
| 3656 | + } |
| 3657 | + } |
| 3658 | + } |
| 3659 | + if(was_empty && synchro_pending_stream!="") |
| 3660 | + { |
| 3661 | + render_gametext(false); |
| 3662 | + } |
| 3663 | + else |
| 3664 | + { |
| 3665 | + update_pending_stream_displays(); |
| 3666 | + } |
| 3667 | + }, |
| 3668 | + close() { //end of stream |
| 3669 | + synchro_polled_response = synchro_pending_stream; |
| 3670 | + let need_clean_output = (synchro_polled_response!="" && localsettings.opmode==1 && gametext_arr.length>0 && document.getElementById("useoaichatcompl").checked); |
| 3671 | + if(need_clean_output) |
| 3672 | + { |
| 3673 | + synchro_polled_response = cleanup_story_completion(synchro_polled_response); |
| 3674 | + } |
| 3675 | + synchro_pending_stream = ""; |
| 3676 | + poll_pending_response(); |
| 3677 | + //handle gen failures |
| 3678 | + if(resp.status==503) |
| 3679 | + { |
| 3680 | + msgbox("Error while submitting prompt: Server appears to be busy."); |
| 3681 | + } |
| 3682 | + }, |
| 3683 | + abort(error) { |
| 3684 | + console.error('Error:', error); |
| 3685 | + if(error.name!="AbortError") //aborts are silent. slightly diff logic |
| 3686 | + { |
| 3687 | + flush_streaming_text(); |
| 3688 | + msgbox("Error while submitting prompt: " + error); |
| 3689 | + } |
| 3690 | + clear_poll_flags(); |
| 3691 | + render_gametext(); |
| 3692 | + }, |
| 3693 | + })); |
| 3694 | + }) |
| 3695 | + .catch((error) => { |
| 3696 | + console.error('Error:', error); |
| 3697 | + if(error.name!="AbortError") //aborts are silent. slightly diff logic |
| 3698 | + { |
| 3699 | + flush_streaming_text(); |
| 3700 | + msgbox("Error while submitting prompt: " + error); |
| 3701 | + } |
| 3702 | + clear_poll_flags(); |
| 3703 | + render_gametext(); |
| 3704 | + }); |
| 3705 | + } |
| 3706 | + |
3543 | 3707 | function kobold_api_stream_sse(sub_endpt,submit_payload)
|
3544 | 3708 | {
|
3545 | 3709 | synchro_pending_stream = "";
|
|
3572 | 3736 | ctrl.buf += chunk;
|
3573 | 3737 | let evs = [];
|
3574 | 3738 | let m;
|
3575 |
| - while ((m = /^event: (.*)\ndata: (.*)\n\n/.exec(ctrl.buf)) !== null) { |
| 3739 | + while ((m = /^event: (.*)\ndata: (.*)\n\n/m.exec(ctrl.buf)) !== null) { |
3576 | 3740 | evs.push({event: m[1], data: JSON.parse(m[2])});
|
3577 | 3741 | ctrl.buf = ctrl.buf.substring(m.index + m[0].length);
|
3578 | 3742 | }
|
|
5152 | 5316 | }
|
5153 | 5317 | }
|
5154 | 5318 |
|
| 5319 | + function is_browser_supports_sse() |
| 5320 | + { |
| 5321 | + return (self.TransformStream!=null && self.TextDecoderStream!=null && self.WritableStream!=null); |
| 5322 | + } |
5155 | 5323 | function is_using_custom_ep()
|
5156 | 5324 | {
|
5157 | 5325 | return (custom_oai_key!=""||custom_kobold_endpoint!=""||custom_claude_key!=""||custom_palm_key!=""||custom_cohere_key!="");
|
5158 | 5326 | }
|
5159 |
| - |
5160 | 5327 | function is_using_kcpp_with_streaming()
|
5161 | 5328 | {
|
5162 | 5329 | return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.30") >= 0);
|
5163 | 5330 | }
|
5164 | 5331 | function is_using_kcpp_with_sse() //need 1.39 for multibyte fix
|
5165 | 5332 | {
|
5166 |
| - let browsersupported = (self.TransformStream!=null && self.TextDecoderStream!=null && self.WritableStream!=null); |
5167 |
| - return (browsersupported && custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.40") >= 0); |
| 5333 | + return (is_browser_supports_sse() && custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.40") >= 0); |
5168 | 5334 | }
|
5169 | 5335 | function is_using_kcpp_with_mirostat()
|
5170 | 5336 | {
|
|
7880 | 8046 | let ddval = document.getElementById("customapidropdown").value;
|
7881 | 8047 | switch(ddval)
|
7882 | 8048 | {
|
7883 |
| - case 3: |
| 8049 | + case "3": |
7884 | 8050 | return document.getElementById("custom_openrouter_model");
|
7885 |
| - case 7: |
| 8051 | + case "7": |
7886 | 8052 | return document.getElementById("custom_mistralai_model");
|
7887 | 8053 | default:
|
7888 | 8054 | return document.getElementById("custom_oai_model");
|
@@ -11750,15 +11916,36 @@
|
11750 | 11916 |
|
11751 | 11917 | function cleanup_story_completion(resp)
|
11752 | 11918 | {
|
11753 |
| - if(!gametext_arr[gametext_arr.length-1].endsWith(" ") && !gametext_arr[gametext_arr.length-1].endsWith("\n")) |
| 11919 | + if(gametext_arr.length>0) |
11754 | 11920 | {
|
11755 |
| - if(/^\.\.\.[a-zA-Z0-9]/.test(resp)) |
| 11921 | + //fix duplicate sentences |
| 11922 | + const sentenceEndings = /[.!?]/g; |
| 11923 | + let lastsentences = gametext_arr[gametext_arr.length-1].split(sentenceEndings); |
| 11924 | + lastsentences = lastsentences.map(lastsentences => lastsentences.trim()); //remove whitespace |
| 11925 | + lastsentences = lastsentences.filter(lastsentences => lastsentences.length > 0); |
| 11926 | + if(lastsentences.length>0) |
11756 | 11927 | {
|
11757 |
| - resp = resp.slice(3); |
| 11928 | + let lastsentence = lastsentences[lastsentences.length - 1]; |
| 11929 | + if(lastsentence.length>10 && resp.trim().startsWith(lastsentence)) //only match if its long enough and matches verbatim |
| 11930 | + { |
| 11931 | + let foundindex = resp.indexOf(lastsentence); |
| 11932 | + if (foundindex !== -1 && foundindex<5) { |
| 11933 | + resp = resp.substring(foundindex+lastsentence.length); //remove duplicated part |
| 11934 | + } |
| 11935 | + } |
11758 | 11936 | }
|
11759 |
| - if (/^[^!\"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~ \t\r\n\f\v]/.test(resp)) // List of common punctuation and whitespace |
| 11937 | + |
| 11938 | + //fix response lacking space |
| 11939 | + if(!gametext_arr[gametext_arr.length-1].endsWith(" ") && !gametext_arr[gametext_arr.length-1].endsWith("\n")) |
11760 | 11940 | {
|
11761 |
| - resp = " "+resp; |
| 11941 | + if(/^\.\.\.[a-zA-Z0-9]/.test(resp)) |
| 11942 | + { |
| 11943 | + resp = resp.slice(3); |
| 11944 | + } |
| 11945 | + if (/^[^!\"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~ \t\r\n\f\v]/.test(resp)) // List of common punctuation and whitespace |
| 11946 | + { |
| 11947 | + resp = " "+resp; |
| 11948 | + } |
11762 | 11949 | }
|
11763 | 11950 | }
|
11764 | 11951 | return resp;
|
@@ -11957,49 +12144,15 @@
|
11957 | 12144 | oaiheaders["HTTP-Referer"] = "https://lite.koboldai.net";
|
11958 | 12145 | }
|
11959 | 12146 |
|
11960 |
| - fetch(targetep, { |
11961 |
| - method: 'POST', |
11962 |
| - headers: oaiheaders, |
11963 |
| - body: JSON.stringify(oai_payload), |
11964 |
| - referrerPolicy: 'no-referrer', |
11965 |
| - }) |
11966 |
| - .then((response) => response.json()) |
11967 |
| - .then((data) => { |
11968 |
| - console.log("sync finished response: " + JSON.stringify(data)); |
11969 |
| - if (custom_oai_key != "" && data.choices != null && data.choices.length > 0) { |
11970 |
| - let dch = data.choices[0]; |
11971 |
| - if (dch.text) { |
11972 |
| - synchro_polled_response = dch.text; |
11973 |
| - } |
11974 |
| - else if (dch.message) { |
11975 |
| - synchro_polled_response = dch.message.content; |
11976 |
| - |
11977 |
| - if(localsettings.opmode==1 && gametext_arr.length>0 && synchro_polled_response!="") |
11978 |
| - { |
11979 |
| - synchro_polled_response = cleanup_story_completion(synchro_polled_response); |
11980 |
| - } |
11981 |
| - } |
11982 |
| - else { |
11983 |
| - console.error("Error, unknown OAI response"); |
11984 |
| - clear_poll_flags(); |
11985 |
| - render_gametext(); |
11986 |
| - msgbox("Error, unknown OAI response"); |
11987 |
| - } |
11988 |
| - } |
11989 |
| - else { |
11990 |
| - //error occurred, maybe captcha failed |
11991 |
| - console.error("error occurred in OAI generation"); |
11992 |
| - clear_poll_flags(); |
11993 |
| - render_gametext(); |
11994 |
| - msgbox("Error occurred during text generation: " + formatError(data)); |
11995 |
| - } |
11996 |
| - }) |
11997 |
| - .catch((error) => { |
11998 |
| - console.error('Error:', error); |
11999 |
| - clear_poll_flags(); |
12000 |
| - render_gametext(); |
12001 |
| - msgbox("Error while submitting prompt: " + error); |
12002 |
| - }); |
| 12147 | + if(is_browser_supports_sse() && document.getElementById("oaistreaming").checked) |
| 12148 | + { |
| 12149 | + oai_payload.stream = true; |
| 12150 | + oai_api_stream_sse(targetep,oai_payload,oaiheaders); |
| 12151 | + } |
| 12152 | + else |
| 12153 | + { |
| 12154 | + oai_api_sync_req(targetep,oai_payload,oaiheaders); |
| 12155 | + } |
12003 | 12156 | }
|
12004 | 12157 | else if (custom_claude_key != "")//handle for Claude
|
12005 | 12158 | {
|
@@ -17105,11 +17258,14 @@
|
17105 | 17258 | </select>
|
17106 | 17259 | <button type="button" class="btn btn-primary" style="display:inline;width:105px;" id="oaifetchlist" onclick="oai_fetch_models()">Fetch List</button>
|
17107 | 17260 | <button type="button" class="btn btn-primary" style="display:inline;width:105px;" id="oaiusecustom" onclick="select_custom_oai_model()">Use Custom</button>
|
17108 |
| - <input type="checkbox" id="oaiaddversion" onchange="" checked> |
17109 |
| - <div class="box-label" title="Add endpoint version">Add Endpoint Version</div> |
17110 |
| - <input type="checkbox" id="useoaichatcompl" onchange="toggleoaichatcompl()"> |
17111 |
| - <div class="box-label" id="useoaichatcompllabel">Use ChatCompletions API</div> |
17112 |
| - |
| 17261 | + <div style="display:inline-flex"> |
| 17262 | + <div><input type="checkbox" id="oaiaddversion" title="Add Endpoint Version Number" onchange="" checked> |
| 17263 | + <div class="box-label">Add Version Num</div></div> |
| 17264 | + <div><input type="checkbox" id="oaistreaming" title="Enable SSE Streaming" onchange=""> |
| 17265 | + <div class="box-label">Streaming</div></div> |
| 17266 | + <div><input type="checkbox" id="useoaichatcompl" title="Use ChatCompletions API" onchange="toggleoaichatcompl()"> |
| 17267 | + <div class="box-label" id="useoaichatcompllabel">ChatCompletions API</div></div> |
| 17268 | + </div> |
17113 | 17269 | <span id="useoaichatcomplbox" class="hidden" onload="toggleoaichatcompl();">
|
17114 | 17270 | <br>
|
17115 | 17271 | Main Message Role:
|
|
0 commit comments