Spaces:
Running
Running
Clean up & Format
Browse files
app.py
CHANGED
|
@@ -22,7 +22,6 @@ class AppConfig:
|
|
| 22 |
API_TIMEOUT = 20
|
| 23 |
|
| 24 |
|
| 25 |
-
|
| 26 |
class DynamicState:
|
| 27 |
"""动态UI状态"""
|
| 28 |
|
|
@@ -72,18 +71,19 @@ class DynamicState:
|
|
| 72 |
)
|
| 73 |
self.label_passthrough = False
|
| 74 |
return output
|
| 75 |
-
|
| 76 |
def reset_workspace(self):
|
| 77 |
"""重置工作区状态"""
|
| 78 |
self.stream_completed = False
|
| 79 |
self.should_stream = False
|
| 80 |
self.in_cot = True
|
| 81 |
self.waiting_api = False
|
|
|
|
| 82 |
return self.ui_state_controller() + (
|
| 83 |
"",
|
| 84 |
"",
|
| 85 |
LANGUAGE_CONFIG["en"]["bot_default"],
|
| 86 |
-
DEFAULT_PERSISTENT
|
| 87 |
)
|
| 88 |
|
| 89 |
|
|
@@ -189,14 +189,17 @@ class ConvoState:
|
|
| 189 |
)
|
| 190 |
for chunk in response_stream:
|
| 191 |
chunk_content = chunk.choices[0].delta.content
|
| 192 |
-
if
|
|
|
|
|
|
|
|
|
|
| 193 |
dynamic_state.should_stream = False
|
| 194 |
if not dynamic_state.should_stream:
|
| 195 |
break
|
| 196 |
|
| 197 |
if chunk_content:
|
| 198 |
dynamic_state.waiting_api = False
|
| 199 |
-
full_response += chunk_content.replace("<think>","")
|
| 200 |
self.current["raw"] = full_response
|
| 201 |
# Update Convo State
|
| 202 |
think_complete = "</think>" in full_response
|
|
@@ -219,7 +222,9 @@ class ConvoState:
|
|
| 219 |
if self.result_editing_toggle:
|
| 220 |
editor_output = full_response
|
| 221 |
else:
|
| 222 |
-
editor_output = self.current["cot"]
|
|
|
|
|
|
|
| 223 |
yield editor_output, gr.update(
|
| 224 |
label=editor_label
|
| 225 |
), self.flatten_output()
|
|
@@ -227,13 +232,15 @@ class ConvoState:
|
|
| 227 |
interval = 1.0 / self.throughput
|
| 228 |
start_time = time.time()
|
| 229 |
while (
|
| 230 |
-
time.time() - start_time
|
| 231 |
-
|
|
|
|
|
|
|
| 232 |
time.sleep(0.005)
|
| 233 |
|
| 234 |
except Exception as e:
|
| 235 |
if str(e) == "list index out of range":
|
| 236 |
-
dynamic_state.stream_completed = True
|
| 237 |
else:
|
| 238 |
if str(e) == "The read operation timed out":
|
| 239 |
error_msg = lang_data["api_interrupted"]
|
|
@@ -244,7 +251,6 @@ class ConvoState:
|
|
| 244 |
self.is_error = True
|
| 245 |
dynamic_state.label_passthrough = True
|
| 246 |
|
| 247 |
-
|
| 248 |
finally:
|
| 249 |
dynamic_state.should_stream = False
|
| 250 |
if "response_stream" in locals():
|
|
@@ -256,17 +262,20 @@ class ConvoState:
|
|
| 256 |
)
|
| 257 |
editor_label = f"{lang_data['editor_label']} - {final_status}"
|
| 258 |
if not self.is_error:
|
| 259 |
-
yield editor_output, gr.update(
|
|
|
|
|
|
|
| 260 |
else:
|
| 261 |
-
yield editor_output, gr.update(
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
|
|
|
| 270 |
|
| 271 |
|
| 272 |
def update_interface_language(selected_lang, convo_state, dynamic_state):
|
|
@@ -315,18 +324,18 @@ def update_interface_language(selected_lang, convo_state, dynamic_state):
|
|
| 315 |
theme = gr.themes.Base(font="system-ui", primary_hue="stone")
|
| 316 |
|
| 317 |
with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
| 318 |
-
DEFAULT_PERSISTENT = {"prompt_input":"", "thought_editor":""}
|
| 319 |
convo_state = gr.State(ConvoState)
|
| 320 |
dynamic_state = gr.State(DynamicState)
|
| 321 |
persistent_state = gr.BrowserState(DEFAULT_PERSISTENT)
|
| 322 |
|
| 323 |
bot_default = LANGUAGE_CONFIG["en"]["bot_default"] + [
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
|
| 331 |
with gr.Row(variant=""):
|
| 332 |
title_md = gr.Markdown(
|
|
@@ -341,7 +350,6 @@ with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
|
| 341 |
container=False,
|
| 342 |
)
|
| 343 |
|
| 344 |
-
|
| 345 |
with gr.Row(equal_height=True):
|
| 346 |
with gr.Column(scale=1, min_width=400):
|
| 347 |
prompt_input = gr.Textbox(
|
|
@@ -393,10 +401,15 @@ with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
|
| 393 |
label=LANGUAGE_CONFIG["en"]["throughput_label"],
|
| 394 |
info=LANGUAGE_CONFIG["en"]["throughput_info"],
|
| 395 |
)
|
| 396 |
-
result_editing_toggle = gr.Checkbox(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 397 |
|
| 398 |
intro_md = gr.Markdown(LANGUAGE_CONFIG["en"]["introduction"], visible=False)
|
| 399 |
-
|
| 400 |
@demo.load(inputs=[persistent_state], outputs=[prompt_input, thought_editor])
|
| 401 |
def recover_persistent_state(persistant_state):
|
| 402 |
if persistant_state["prompt_input"] or persistant_state["thought_editor"]:
|
|
@@ -404,7 +417,6 @@ with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
|
| 404 |
else:
|
| 405 |
return gr.update(), gr.update()
|
| 406 |
|
| 407 |
-
|
| 408 |
# 交互逻辑
|
| 409 |
stateful_ui = (control_button, thought_editor, next_turn_btn)
|
| 410 |
|
|
@@ -426,7 +438,12 @@ with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
|
| 426 |
for response in convo_state.generate_ai_response(
|
| 427 |
prompt, content, dynamic_state
|
| 428 |
):
|
| 429 |
-
yield response + (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 430 |
|
| 431 |
gr.on(
|
| 432 |
[control_button.click, prompt_input.submit, thought_editor.submit],
|
|
@@ -453,24 +470,20 @@ with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
|
| 453 |
[dynamic_state],
|
| 454 |
stateful_ui + (thought_editor, prompt_input, chatbot, persistent_state),
|
| 455 |
concurrency_limit=None,
|
| 456 |
-
show_progress=False
|
| 457 |
)
|
| 458 |
|
| 459 |
def toggle_editor_result(convo_state, allow):
|
| 460 |
setattr(convo_state, "result_editing_toggle", allow)
|
| 461 |
if allow:
|
| 462 |
-
print(convo_state.current["raw"])
|
| 463 |
return gr.update(value=convo_state.current["raw"])
|
| 464 |
else:
|
| 465 |
-
print(convo_state.current["cot"])
|
| 466 |
return gr.update(value=convo_state.current["cot"])
|
| 467 |
|
| 468 |
-
|
| 469 |
-
|
| 470 |
result_editing_toggle.change(
|
| 471 |
toggle_editor_result,
|
| 472 |
inputs=[convo_state, result_editing_toggle],
|
| 473 |
-
outputs=[thought_editor]
|
| 474 |
)
|
| 475 |
|
| 476 |
lang_selector.change(
|
|
@@ -487,7 +500,7 @@ with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
|
| 487 |
next_turn_btn,
|
| 488 |
intro_md,
|
| 489 |
chatbot,
|
| 490 |
-
result_editing_toggle
|
| 491 |
],
|
| 492 |
concurrency_limit=None,
|
| 493 |
)
|
|
|
|
| 22 |
API_TIMEOUT = 20
|
| 23 |
|
| 24 |
|
|
|
|
| 25 |
class DynamicState:
|
| 26 |
"""动态UI状态"""
|
| 27 |
|
|
|
|
| 71 |
)
|
| 72 |
self.label_passthrough = False
|
| 73 |
return output
|
| 74 |
+
|
| 75 |
def reset_workspace(self):
|
| 76 |
"""重置工作区状态"""
|
| 77 |
self.stream_completed = False
|
| 78 |
self.should_stream = False
|
| 79 |
self.in_cot = True
|
| 80 |
self.waiting_api = False
|
| 81 |
+
|
| 82 |
return self.ui_state_controller() + (
|
| 83 |
"",
|
| 84 |
"",
|
| 85 |
LANGUAGE_CONFIG["en"]["bot_default"],
|
| 86 |
+
DEFAULT_PERSISTENT,
|
| 87 |
)
|
| 88 |
|
| 89 |
|
|
|
|
| 189 |
)
|
| 190 |
for chunk in response_stream:
|
| 191 |
chunk_content = chunk.choices[0].delta.content
|
| 192 |
+
if (
|
| 193 |
+
coordinator.should_pause_for_human(full_response)
|
| 194 |
+
and dynamic_state.in_cot
|
| 195 |
+
):
|
| 196 |
dynamic_state.should_stream = False
|
| 197 |
if not dynamic_state.should_stream:
|
| 198 |
break
|
| 199 |
|
| 200 |
if chunk_content:
|
| 201 |
dynamic_state.waiting_api = False
|
| 202 |
+
full_response += chunk_content.replace("<think>", "")
|
| 203 |
self.current["raw"] = full_response
|
| 204 |
# Update Convo State
|
| 205 |
think_complete = "</think>" in full_response
|
|
|
|
| 222 |
if self.result_editing_toggle:
|
| 223 |
editor_output = full_response
|
| 224 |
else:
|
| 225 |
+
editor_output = self.current["cot"] + (
|
| 226 |
+
"</think>" if think_complete else ""
|
| 227 |
+
)
|
| 228 |
yield editor_output, gr.update(
|
| 229 |
label=editor_label
|
| 230 |
), self.flatten_output()
|
|
|
|
| 232 |
interval = 1.0 / self.throughput
|
| 233 |
start_time = time.time()
|
| 234 |
while (
|
| 235 |
+
(time.time() - start_time) < interval
|
| 236 |
+
and dynamic_state.should_stream
|
| 237 |
+
and dynamic_state.in_cot
|
| 238 |
+
):
|
| 239 |
time.sleep(0.005)
|
| 240 |
|
| 241 |
except Exception as e:
|
| 242 |
if str(e) == "list index out of range":
|
| 243 |
+
dynamic_state.stream_completed = True
|
| 244 |
else:
|
| 245 |
if str(e) == "The read operation timed out":
|
| 246 |
error_msg = lang_data["api_interrupted"]
|
|
|
|
| 251 |
self.is_error = True
|
| 252 |
dynamic_state.label_passthrough = True
|
| 253 |
|
|
|
|
| 254 |
finally:
|
| 255 |
dynamic_state.should_stream = False
|
| 256 |
if "response_stream" in locals():
|
|
|
|
| 262 |
)
|
| 263 |
editor_label = f"{lang_data['editor_label']} - {final_status}"
|
| 264 |
if not self.is_error:
|
| 265 |
+
yield editor_output, gr.update(
|
| 266 |
+
label=editor_label
|
| 267 |
+
), self.flatten_output()
|
| 268 |
else:
|
| 269 |
+
yield editor_output, gr.update(
|
| 270 |
+
label=editor_label_error
|
| 271 |
+
), self.flatten_output() + [
|
| 272 |
+
{
|
| 273 |
+
"role": "assistant",
|
| 274 |
+
"content": error_msg,
|
| 275 |
+
"metadata": {"title": f"❌Error"},
|
| 276 |
+
}
|
| 277 |
+
]
|
| 278 |
+
self.is_error = False
|
| 279 |
|
| 280 |
|
| 281 |
def update_interface_language(selected_lang, convo_state, dynamic_state):
|
|
|
|
| 324 |
theme = gr.themes.Base(font="system-ui", primary_hue="stone")
|
| 325 |
|
| 326 |
with gr.Blocks(theme=theme, css_paths="styles.css") as demo:
|
| 327 |
+
DEFAULT_PERSISTENT = {"prompt_input": "", "thought_editor": ""}
|
| 328 |
convo_state = gr.State(ConvoState)
|
| 329 |
dynamic_state = gr.State(DynamicState)
|
| 330 |
persistent_state = gr.BrowserState(DEFAULT_PERSISTENT)
|
| 331 |
|
| 332 |
bot_default = LANGUAGE_CONFIG["en"]["bot_default"] + [
|
| 333 |
+
{
|
| 334 |
+
"role": "assistant",
|
| 335 |
+
"content": f"Running `{os.getenv('API_MODEL')}` @ {os.getenv('API_URL')} \n Performance subjects to API provider situation",
|
| 336 |
+
"metadata": {"title": f"API INFO"},
|
| 337 |
+
}
|
| 338 |
+
]
|
| 339 |
|
| 340 |
with gr.Row(variant=""):
|
| 341 |
title_md = gr.Markdown(
|
|
|
|
| 350 |
container=False,
|
| 351 |
)
|
| 352 |
|
|
|
|
| 353 |
with gr.Row(equal_height=True):
|
| 354 |
with gr.Column(scale=1, min_width=400):
|
| 355 |
prompt_input = gr.Textbox(
|
|
|
|
| 401 |
label=LANGUAGE_CONFIG["en"]["throughput_label"],
|
| 402 |
info=LANGUAGE_CONFIG["en"]["throughput_info"],
|
| 403 |
)
|
| 404 |
+
result_editing_toggle = gr.Checkbox(
|
| 405 |
+
label=LANGUAGE_CONFIG["en"]["result_editing_toggle"],
|
| 406 |
+
interactive=True,
|
| 407 |
+
scale=0,
|
| 408 |
+
container=False,
|
| 409 |
+
)
|
| 410 |
|
| 411 |
intro_md = gr.Markdown(LANGUAGE_CONFIG["en"]["introduction"], visible=False)
|
| 412 |
+
|
| 413 |
@demo.load(inputs=[persistent_state], outputs=[prompt_input, thought_editor])
|
| 414 |
def recover_persistent_state(persistant_state):
|
| 415 |
if persistant_state["prompt_input"] or persistant_state["thought_editor"]:
|
|
|
|
| 417 |
else:
|
| 418 |
return gr.update(), gr.update()
|
| 419 |
|
|
|
|
| 420 |
# 交互逻辑
|
| 421 |
stateful_ui = (control_button, thought_editor, next_turn_btn)
|
| 422 |
|
|
|
|
| 438 |
for response in convo_state.generate_ai_response(
|
| 439 |
prompt, content, dynamic_state
|
| 440 |
):
|
| 441 |
+
yield response + (
|
| 442 |
+
{
|
| 443 |
+
"prompt_input": convo_state.current["user"],
|
| 444 |
+
"thought_editor": convo_state.current["cot"],
|
| 445 |
+
},
|
| 446 |
+
)
|
| 447 |
|
| 448 |
gr.on(
|
| 449 |
[control_button.click, prompt_input.submit, thought_editor.submit],
|
|
|
|
| 470 |
[dynamic_state],
|
| 471 |
stateful_ui + (thought_editor, prompt_input, chatbot, persistent_state),
|
| 472 |
concurrency_limit=None,
|
| 473 |
+
show_progress=False,
|
| 474 |
)
|
| 475 |
|
| 476 |
def toggle_editor_result(convo_state, allow):
|
| 477 |
setattr(convo_state, "result_editing_toggle", allow)
|
| 478 |
if allow:
|
|
|
|
| 479 |
return gr.update(value=convo_state.current["raw"])
|
| 480 |
else:
|
|
|
|
| 481 |
return gr.update(value=convo_state.current["cot"])
|
| 482 |
|
|
|
|
|
|
|
| 483 |
result_editing_toggle.change(
|
| 484 |
toggle_editor_result,
|
| 485 |
inputs=[convo_state, result_editing_toggle],
|
| 486 |
+
outputs=[thought_editor],
|
| 487 |
)
|
| 488 |
|
| 489 |
lang_selector.change(
|
|
|
|
| 500 |
next_turn_btn,
|
| 501 |
intro_md,
|
| 502 |
chatbot,
|
| 503 |
+
result_editing_toggle,
|
| 504 |
],
|
| 505 |
concurrency_limit=None,
|
| 506 |
)
|