Skip to content

Commit 0997587

Browse files
优化自动弹出后唤醒流程
1 parent 0bb667c commit 0997587

File tree

5 files changed

+168
-100
lines changed

5 files changed

+168
-100
lines changed

docs/功能迭代.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,4 @@
173173
2025年-10月-30日:启动本地后端时将上下文长度调整为记忆容量与并发数的乘积,防止多并发占用同一缓存。
174174
2025年-10月-30日:在软件技术说明书补充机体自动弹出(惰性卸载)的原理、倒计时交互与唤醒流程。
175175
2025年-10月-30日:在软件技术说明书补充本地代理 LocalProxyServer 的监听、唤醒与转发细节。
176+
2025年-10月-30日:优化自动弹出后唤醒流程,保留对话输出并继续当前会话。唤醒模型时临时禁用主界面的发送与装载等按钮。

src/widget/widget.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ Widget::Widget(QWidget *parent, QString applicationDirPath_)
231231

232232
backendOnline_ = false;
233233
lazyWakeInFlight_ = false;
234+
applyWakeUiLock(false);
234235
if (proxyServer_) proxyServer_->setBackendAvailable(false);
235236
const bool wasLazyUnloaded = lazyUnloaded_;
236237
const bool lazyStop = lazyUnloadPreserveState_ || wasLazyUnloaded;
@@ -585,6 +586,8 @@ void Widget::recv_freeover_loadlater()
585586
void Widget::preLoad()
586587
{
587588
is_load = false; // 重置is_load标签
589+
preserveConversationOnNextReady_ = false; // Fresh load starts a new chat
590+
skipUnlockLoadIntro_ = false; // Ensure unlockLoad prints system prompt
588591
flushPendingStream();
589592
if (ui_state == CHAT_STATE)
590593
{

src/widget/widget.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class Widget : public QWidget
169169
void ui_state_normal(); // 待机界面状态
170170
void ui_state_recoding(); // 录音界面状态
171171
void unlockButtonsAfterError(); // 异常后解锁:强制开放“约定/设置/装载”
172+
void applyWakeUiLock(bool locked); // 锁定或解锁唤醒期间的主要控件
172173

173174
// 模型控制相关
174175
EVA_CHATS_TEMPLATE bot_chat; // 经过模型自带模板格式化后的内容
@@ -248,8 +249,11 @@ class Widget : public QWidget
248249
QString getFirstNonLoopbackIPv4Address(); // 获取本机第一个ip地址
249250
bool lastServerRestart_ = false; // 标记最近一次 ensureLocalServer 是否触发了重启
250251
bool ignoreNextServerStopped_ = false; // 忽略一次 serverStopped(用于计划内重启时旧进程的退出)
251-
bool suppressStateClearOnStop_ = false; // Skip clearing state log when shutdown is an automatic lazy unload
252-
bool lazyUnloadPreserveState_ = false; // Remember to keep existing state lines after auto lazy unload stops
252+
bool suppressStateClearOnStop_ = false; // Skip clearing state log when shutdown is an automatic lazy unload
253+
bool lazyUnloadPreserveState_ = false; // Remember to keep existing state lines after auto lazy unload stops
254+
bool preserveConversationOnNextReady_ = false; // Resume chat log after lazy auto eject wakes backend
255+
bool skipUnlockLoadIntro_ = false; // Skip system prompt injection when resuming existing chat
256+
bool wakeUiLocked_ = false; // Temporarily disable main controls while backend wakes up
253257
QString activeServerHost_; // 当前本地后端的实际绑定地址
254258
QString activeServerPort_; // 当前本地后端的实际端口
255259
QString activeBackendPort_;

src/widget/widget_slots.cpp

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,11 @@ void Widget::ensureLocalServer(bool lazyWake)
417417
ensureTimer.start();
418418

419419
cancelLazyUnload(QStringLiteral("ensureLocalServer entry"));
420-
if (lazyWake) lazyWakeInFlight_ = true;
420+
if (lazyWake)
421+
{
422+
lazyWakeInFlight_ = true;
423+
applyWakeUiLock(true);
424+
}
421425

422426
if (!firstAutoNglEvaluated_ && !serverManager->isRunning())
423427
{
@@ -552,6 +556,7 @@ void Widget::ensureLocalServer(bool lazyWake)
552556
initiatePortFallback();
553557
}
554558
lazyWakeInFlight_ = false;
559+
applyWakeUiLock(false);
555560
return;
556561
}
557562

@@ -610,7 +615,11 @@ void Widget::ensureLocalServer(bool lazyWake)
610615
if (proxyServer_) proxyServer_->setBackendAvailable(backendOnline_);
611616
if (!lazyWake && backendOnline_) markBackendActivity();
612617

613-
if (!lastServerRestart_ && backendRunning) lazyWakeInFlight_ = false;
618+
if (!lastServerRestart_ && backendRunning)
619+
{
620+
lazyWakeInFlight_ = false;
621+
applyWakeUiLock(false);
622+
}
614623

615624
apis.api_endpoint = formatLocalEndpoint(activeServerHost_, activeServerPort_);
616625
apis.api_key = "";
@@ -824,9 +833,17 @@ void Widget::performLazyUnloadInternal(bool forced)
824833
emit ui2tool_cancelActive();
825834
toolInvocationActive_ = false;
826835
}
836+
const bool hasUi = ui && ui->output;
837+
const bool hasDocument = hasUi && ui->output->document();
838+
const bool hasRenderedContent = hasDocument && !ui->output->document()->isEmpty();
839+
const bool hasConversationHistory = !ui_messagesArray.isEmpty();
840+
const bool preserveAfterWake = (ui_state == CHAT_STATE) && (hasConversationHistory || hasRenderedContent);
827841
lazyUnloaded_ = true;
828-
if (!forced) lazyUnloadPreserveState_ = true;
842+
if (preserveAfterWake)
843+
lazyUnloadPreserveState_ = true;
844+
preserveConversationOnNextReady_ = preserveAfterWake; // Resume chat log after lazy wake
829845
lazyWakeInFlight_ = false;
846+
applyWakeUiLock(false);
830847
backendOnline_ = false;
831848
if (proxyServer_) proxyServer_->setBackendAvailable(false);
832849
reflash_state("ui:" + jtr("auto eject stop backend"), SIGNAL_SIGNAL);
@@ -928,6 +945,7 @@ void Widget::onServerReady(const QString &endpoint)
928945
backendOnline_ = true;
929946
lazyUnloaded_ = false;
930947
lazyWakeInFlight_ = false;
948+
applyWakeUiLock(false);
931949
cancelLazyUnload(QStringLiteral("backend ready"));
932950
markBackendActivity();
933951
updateProxyBackend(backendListenHost_, activeBackendPort_);
@@ -961,31 +979,38 @@ void Widget::onServerReady(const QString &endpoint)
961979
load_time = load_timer.isValid() ? (load_timer.nsecsElapsed() / 1e9) : 0.0;
962980
ui_mode = LOCAL_MODE;
963981

982+
const bool preserveConversation = preserveConversationOnNextReady_;
983+
preserveConversationOnNextReady_ = false;
984+
skipUnlockLoadIntro_ = preserveConversation;
985+
964986
flushPendingStream();
965-
ui->output->clear();
966-
ui_messagesArray = QJsonArray();
967-
{
968-
QJsonObject systemMessage;
969-
systemMessage.insert("role", DEFAULT_SYSTEM_NAME);
970-
systemMessage.insert("content", ui_DATES.date_prompt);
971-
ui_messagesArray.append(systemMessage);
972-
if (history_ && ui_state == CHAT_STATE)
987+
if (!preserveConversation)
988+
{
989+
ui->output->clear();
990+
ui_messagesArray = QJsonArray();
973991
{
974-
SessionMeta meta;
975-
meta.id = QString::number(QDateTime::currentMSecsSinceEpoch());
976-
meta.title = "";
977-
meta.endpoint = frontendEndpoint;
978-
meta.model = ui_SETTINGS.modelpath;
979-
meta.system = ui_DATES.date_prompt;
980-
meta.n_ctx = ui_SETTINGS.nctx;
981-
meta.slot_id = -1;
982-
meta.startedAt = QDateTime::currentDateTime();
983-
history_->begin(meta);
984-
history_->appendMessage(systemMessage);
985-
currentSlotId_ = -1;
992+
QJsonObject systemMessage;
993+
systemMessage.insert("role", DEFAULT_SYSTEM_NAME);
994+
systemMessage.insert("content", ui_DATES.date_prompt);
995+
ui_messagesArray.append(systemMessage);
996+
if (history_ && ui_state == CHAT_STATE)
997+
{
998+
SessionMeta meta;
999+
meta.id = QString::number(QDateTime::currentMSecsSinceEpoch());
1000+
meta.title = "";
1001+
meta.endpoint = frontendEndpoint;
1002+
meta.model = ui_SETTINGS.modelpath;
1003+
meta.system = ui_DATES.date_prompt;
1004+
meta.n_ctx = ui_SETTINGS.nctx;
1005+
meta.slot_id = -1;
1006+
meta.startedAt = QDateTime::currentDateTime();
1007+
history_->begin(meta);
1008+
history_->appendMessage(systemMessage);
1009+
currentSlotId_ = -1;
1010+
}
9861011
}
1012+
bot_predecode_content = ui_DATES.date_prompt; // 使用系统指令作为“预解码内容”展示
9871013
}
988-
bot_predecode_content = ui_DATES.date_prompt; // 使用系统指令作为“预解码内容”展示
9891014
is_load = true;
9901015
// After fresh load, the first "all slots are idle" is an idle baseline -> ignore once
9911016
lastServerRestart_ = false; // 一次重启流程结束
@@ -1585,6 +1610,7 @@ void Widget::onServerStartFailed(const QString &reason)
15851610
{
15861611
backendOnline_ = false;
15871612
lazyWakeInFlight_ = false;
1613+
applyWakeUiLock(false);
15881614
if (proxyServer_) proxyServer_->setBackendAvailable(false);
15891615
cancelLazyUnload(QStringLiteral("backend start failed"));
15901616
pendingSendAfterWake_ = false;
@@ -1658,6 +1684,11 @@ void Widget::unlockLoad()
16581684
ui->cpu_bar->setToolTip(jtr("nthread/maxthread") + " " + QString::number(ui_SETTINGS.nthread) + "/" + QString::number(max_thread));
16591685
auto_save_user();
16601686
ui_state_normal();
1687+
if (skipUnlockLoadIntro_)
1688+
{
1689+
skipUnlockLoadIntro_ = false; // Already showing prior chat, do not inject system prompt
1690+
return;
1691+
}
16611692
// Record a system header and show system prompt as pre-decode content
16621693
int __idx = recordCreate(RecordRole::System);
16631694
appendRoleHeader(QStringLiteral("system"));

0 commit comments

Comments
 (0)