返回提交历史
Modified
g4f/Provider/needs_auth/OpenaiTemplate.py
+14
-2
Modified
g4f/gui/client/index.html
+6
-2
Modified
g4f/gui/client/static/js/chat.v1.js
+35
-22
XFEstudio/gpt4free
Support <think> token in OpenaiTemplate Fix image selection on mobile Support boxed inline MathJax
0bdfd990
代码差异
3 个文件
+55
-26
@@ -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:
@@ -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">
@@ -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
});