XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

Support <think> token in OpenaiTemplate Fix image selection on mobile Support boxed inline MathJax

0bdfd990
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

3 个文件 +55 -26
Modified g4f/Provider/needs_auth/OpenaiTemplate.py +14 -2
@@ -1,13 +1,14 @@
1 1 from __future__ import annotations
2 2
3 3 import json
4 import time
4 5 import requests
5 6
6 7 from ..helper import filter_none
7 8 from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
8 9 from ...typing import Union, Optional, AsyncResult, Messages, ImagesType
9 10 from ...requests import StreamSession, raise_for_status
10 from ...providers.response import FinishReason, ToolCalls, Usage
11 from ...providers.response import FinishReason, ToolCalls, Usage, Reasoning
11 12 from ...errors import MissingAuthError, ResponseError
12 13 from ...image import to_data_uri
13 14 from ... import debug
@@ -121,6 +122,7 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
121 122 elif content_type.startswith("text/event-stream"):
122 123 await raise_for_status(response)
123 124 first = True
125 is_thinking = 0
124 126 async for line in response.iter_lines():
125 127 if line.startswith(b"data: "):
126 128 chunk = line[6:]
@@ -135,7 +137,17 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
135 137 delta = delta.lstrip()
136 138 if delta:
137 139 first = False
138 yield delta
140 if is_thinking:
141 if "</think>" in delta:
142 yield Reasoning(None, f"Finished in {round(time.time()-is_thinking, 2)} seconds")
143 is_thinking = 0
144 else:
145 yield Reasoning(delta)
146 elif "<think>" in delta:
147 is_thinking = time.time()
148 yield Reasoning(None, "Is thinking...")
149 else:
150 yield delta
139 151 if "usage" in data and data["usage"]:
140 152 yield Usage(**data["usage"])
141 153 if "finish_reason" in choice and choice["finish_reason"] is not None:
Modified g4f/gui/client/index.html +6 -2
@@ -25,7 +25,11 @@
25 25 chtml: {
26 26 scale: 1,
27 27 displayAlign: 'left'
28 }
28 },
29 tex: {
30 inlineMath: [['$', '$'], ['\\(', '\\)']],
31 displayMath: [['$$', '$$'], ['\\[', '\\]']]
32 },
29 33 };
30 34 </script>
31 35 <script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" async></script>
@@ -246,7 +250,7 @@
246 250 <textarea id="message-input" placeholder="Ask a question" cols="30" rows="10"
247 251 style="white-space: pre-wrap;resize: none;"></textarea>
248 252 <label class="file-label image-label" for="image" title="">
249 <input type="file" id="image" name="image" accept="image/*" required multiple capture="filesystem"/>
253 <input type="file" id="image" name="image" accept="image/*" required/>
250 254 <i class="fa-regular fa-image"></i>
251 255 </label>
252 256 <label class="file-label image-label" for="camera">
Modified g4f/gui/client/static/js/chat.v1.js +35 -22
@@ -73,13 +73,14 @@ if (window.markdownit) {
73 73 }
74 74
75 75 function render_reasoning(reasoning, final = false) {
76 const inner_text = reasoning.text ? `<div class="reasoning_text${final ? " final hidden" : ""}">
77 ${markdown_render(reasoning.text)}
78 </div>` : "";
76 79 return `<div class="reasoning_body">
77 80 <div class="reasoning_title">
78 81 <strong>Reasoning <i class="fa-solid fa-brain"></i>:</strong> ${escapeHtml(reasoning.status)}
79 82 </div>
80 <div class="reasoning_text${final ? " final hidden" : ""}">
81 ${markdown_render(reasoning.text)}
82 </div>
83 ${inner_text}
83 84 </div>`;
84 85 }
85 86
@@ -342,7 +343,9 @@ const register_message_buttons = async () => {
342 343 el.dataset.click = "true";
343 344 el.addEventListener("click", async () => {
344 345 let text_el = el.parentElement.querySelector(".reasoning_text");
345 text_el.classList[text_el.classList.contains("hidden") ? "remove" : "add"]("hidden");
346 if (text_el) {
347 text_el.classList[text_el.classList.contains("hidden") ? "remove" : "add"]("hidden");
348 }
346 349 })
347 350 }
348 351 });
@@ -495,20 +498,21 @@ const prepare_messages = (messages, message_index = -1, do_continue = false, do_
495 498 }
496 499 }
497 500 // Combine assistant messages
498 let last_message;
499 let new_messages = [];
500 messages.forEach((message) => {
501 message_copy = { ...message };
502 if (last_message) {
503 if (last_message["role"] == message["role"] && message["role"] == "assistant") {
504 message_copy["content"] = last_message["content"] + message_copy["content"];
505 new_messages.pop();
506 }
507 }
508 last_message = message_copy;
509 new_messages.push(last_message);
510 });
511 messages = new_messages;
501 // let last_message;
502 // let new_messages = [];
503 // messages.forEach((message) => {
504 // message_copy = { ...message };
505 // if (last_message) {
506 // if (last_message["role"] == message["role"] && message["role"] == "assistant") {
507 // message_copy["content"] = last_message["content"] + message_copy["content"];
508 // new_messages.pop();
509 // }
510 // }
511 // last_message = message_copy;
512 // new_messages.push(last_message);
513 // });
514 // messages = new_messages;
515 // console.log(2, messages);
512 516
513 517 // Insert system prompt as first message
514 518 let final_messages = [];
@@ -555,14 +559,15 @@ const prepare_messages = (messages, message_index = -1, do_continue = false, do_
555 559 delete new_message.continue;
556 560 // Append message to new messages
557 561 if (do_filter && !new_message.regenerate) {
558 new_messages.push(new_message)
562 final_messages.push(new_message)
559 563 } else if (!do_filter) {
560 new_messages.push(new_message)
564 final_messages.push(new_message)
561 565 }
562 566 }
563 567 });
568 console.log(4, final_messages);
564 569
565 return new_messages;
570 return final_messages;
566 571 }
567 572
568 573 async function load_provider_parameters(provider) {
@@ -1721,7 +1726,11 @@ function count_words_and_tokens(text, model, completion_tokens, prompt_tokens) {
1721 1726 function update_message(content_map, message_id, content = null, scroll = true) {
1722 1727 content_map.update_timeouts.push(setTimeout(() => {
1723 1728 if (!content) {
1724 content = markdown_render(message_storage[message_id]);
1729 if (reasoning_storage[message_id]) {
1730 content = render_reasoning(reasoning_storage[message_id], true) + markdown_render(message_storage[message_id]);
1731 } else {
1732 content = markdown_render(message_storage[message_id]);
1733 }
1725 1734 let lastElement, lastIndex = null;
1726 1735 for (element of ['</p>', '</code></pre>', '</p>\n</li>\n</ol>', '</li>\n</ol>', '</li>\n</ul>']) {
1727 1736 const index = content.lastIndexOf(element)
@@ -2186,6 +2195,10 @@ fileInput.addEventListener('change', async (event) => {
2186 2195 }
2187 2196 });
2188 2197
2198 if (!window.matchMedia("(pointer:coarse)").matches) {
2199 document.getElementById("image").setAttribute("multiple", "multiple");
2200 }
2201
2189 2202 chatPrompt?.addEventListener("input", async () => {
2190 2203 await save_system_message();
2191 2204 });