fix: persist master-agent wait state in chat
This commit is contained in:
@@ -64,6 +64,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
private boolean renderForcedScrollToBottom;
|
||||
private boolean conversationInfoReady;
|
||||
private boolean masterAgentReplyWaiting;
|
||||
private boolean masterAgentReplyTimedOut;
|
||||
private @Nullable String masterAgentReplyBaselineMessageId;
|
||||
private String currentScreenTitle;
|
||||
private String currentScreenSubtitle;
|
||||
@@ -327,15 +328,17 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
appendContent(BossUi.buildMessagePlaceholder(this, "还没有项目消息,先发一条开始对话。"));
|
||||
}
|
||||
|
||||
boolean masterAgentStillWaiting = isMasterAgentConversation()
|
||||
&& masterAgentReplyWaiting
|
||||
&& !ProjectChatUiState.hasReplyBeyondBaseline(project, masterAgentReplyBaselineMessageId);
|
||||
if (isMasterAgentConversation() && masterAgentReplyWaiting && !masterAgentStillWaiting) {
|
||||
masterAgentReplyWaiting = false;
|
||||
masterAgentReplyBaselineMessageId = null;
|
||||
boolean masterAgentHasReply = isMasterAgentConversation()
|
||||
&& ProjectChatUiState.hasReplyBeyondBaseline(project, masterAgentReplyBaselineMessageId);
|
||||
if (masterAgentHasReply) {
|
||||
clearMasterAgentReplyState();
|
||||
}
|
||||
if (masterAgentStillWaiting) {
|
||||
appendContent(buildMasterAgentThinkingPlaceholder());
|
||||
if (isMasterAgentConversation()) {
|
||||
if (masterAgentReplyWaiting) {
|
||||
appendContent(buildMasterAgentReplyStateView(false));
|
||||
} else if (masterAgentReplyTimedOut) {
|
||||
appendContent(buildMasterAgentReplyStateView(true));
|
||||
}
|
||||
}
|
||||
|
||||
setRefreshing(false);
|
||||
@@ -1471,8 +1474,31 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
private View buildMasterAgentThinkingPlaceholder() {
|
||||
return BossUi.buildHintPill(this, "主 Agent 思考中");
|
||||
private View buildMasterAgentReplyStateView(boolean timedOut) {
|
||||
LinearLayout container = new LinearLayout(this);
|
||||
container.setOrientation(LinearLayout.VERTICAL);
|
||||
container.addView(BossUi.buildCard(
|
||||
this,
|
||||
timedOut ? "主 Agent 回复超时" : "主 Agent 思考中",
|
||||
timedOut
|
||||
? "消息已经发送,但暂时还没有收到回复。你可以继续等待最新结果。"
|
||||
: "消息已发送,正在等待主 Agent 回复。",
|
||||
timedOut
|
||||
? "超时后不会丢失状态,收到新回复会自动清掉。"
|
||||
: "稍后收到回复后,这个状态会自动消失。"
|
||||
));
|
||||
if (timedOut) {
|
||||
Button retryButton = BossUi.buildMiniActionButton(this, "重试等待", true);
|
||||
retryButton.setOnClickListener(v -> retryMasterAgentReplyWait());
|
||||
container.addView(BossUi.buildInlineActionRow(this, retryButton));
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
private void clearMasterAgentReplyState() {
|
||||
masterAgentReplyWaiting = false;
|
||||
masterAgentReplyTimedOut = false;
|
||||
masterAgentReplyBaselineMessageId = null;
|
||||
}
|
||||
|
||||
private void scrollChatToBottom() {
|
||||
@@ -1866,7 +1892,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(true);
|
||||
showMessage(waitingMessage);
|
||||
executor.execute(() -> pollUntilReply(waitSpec, includeDispatchPlans));
|
||||
enqueueReplyWaitPoll(waitSpec.baselineMessageId, includeDispatchPlans);
|
||||
}
|
||||
|
||||
private void startMasterAgentReplyWait(
|
||||
@@ -1875,17 +1901,22 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
String waitingMessage
|
||||
) {
|
||||
masterAgentReplyWaiting = true;
|
||||
masterAgentReplyTimedOut = false;
|
||||
masterAgentReplyBaselineMessageId = waitSpec.baselineMessageId;
|
||||
composerSending = false;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(false);
|
||||
showMessage(waitingMessage);
|
||||
reload(true);
|
||||
replyWaitExecutor.execute(() -> pollUntilReply(waitSpec, includeDispatchPlans));
|
||||
enqueueReplyWaitPoll(waitSpec.baselineMessageId, includeDispatchPlans);
|
||||
}
|
||||
|
||||
protected void enqueueReplyWaitPoll(@Nullable String baselineMessageId, boolean includeDispatchPlans) {
|
||||
replyWaitExecutor.execute(() -> pollUntilReply(baselineMessageId, includeDispatchPlans));
|
||||
}
|
||||
|
||||
private void pollUntilReply(
|
||||
ProjectChatUiState.ReplyWaitSpec waitSpec,
|
||||
@Nullable String baselineMessageId,
|
||||
boolean includeDispatchPlans
|
||||
) {
|
||||
long deadlineAt = System.currentTimeMillis() + REPLY_WAIT_TIMEOUT_MS;
|
||||
@@ -1894,7 +1925,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
while (!Thread.currentThread().isInterrupted() && System.currentTimeMillis() < deadlineAt) {
|
||||
ProjectSnapshot snapshot = fetchProjectSnapshot(includeDispatchPlans);
|
||||
JSONObject project = snapshot.payload.optJSONObject("project");
|
||||
boolean hasReply = ProjectChatUiState.hasReplyBeyondBaseline(project, waitSpec.baselineMessageId);
|
||||
boolean hasReply = ProjectChatUiState.hasReplyBeyondBaseline(project, baselineMessageId);
|
||||
|
||||
if (!renderedInitialSnapshot || hasReply) {
|
||||
runOnUiThread(() -> {
|
||||
@@ -1910,10 +1941,7 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
|
||||
if (hasReply) {
|
||||
runOnUiThread(() -> {
|
||||
if (isMasterAgentConversation()) {
|
||||
masterAgentReplyWaiting = false;
|
||||
masterAgentReplyBaselineMessageId = null;
|
||||
}
|
||||
clearMasterAgentReplyState();
|
||||
composerSending = false;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(false);
|
||||
@@ -1928,19 +1956,19 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
runOnUiThread(() -> {
|
||||
if (isMasterAgentConversation()) {
|
||||
masterAgentReplyWaiting = false;
|
||||
masterAgentReplyBaselineMessageId = null;
|
||||
masterAgentReplyTimedOut = true;
|
||||
}
|
||||
composerSending = false;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(false);
|
||||
showMessage("对方还在处理中,稍后下拉刷新查看最新回复。");
|
||||
showMessage("主 Agent 回复超时,可重试等待最新回复。");
|
||||
reload(false);
|
||||
});
|
||||
} catch (Exception error) {
|
||||
runOnUiThread(() -> {
|
||||
if (isMasterAgentConversation()) {
|
||||
masterAgentReplyWaiting = false;
|
||||
masterAgentReplyBaselineMessageId = null;
|
||||
masterAgentReplyTimedOut = true;
|
||||
}
|
||||
composerSending = false;
|
||||
updateComposerSendButtonState();
|
||||
@@ -1951,6 +1979,20 @@ public class ProjectDetailActivity extends BossScreenActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void retryMasterAgentReplyWait() {
|
||||
if (!isMasterAgentConversation() || TextUtils.isEmpty(masterAgentReplyBaselineMessageId)) {
|
||||
return;
|
||||
}
|
||||
masterAgentReplyWaiting = true;
|
||||
masterAgentReplyTimedOut = false;
|
||||
composerSending = false;
|
||||
updateComposerSendButtonState();
|
||||
setRefreshing(false);
|
||||
showMessage("已重新开始等待主 Agent 回复");
|
||||
reload(true);
|
||||
enqueueReplyWaitPoll(masterAgentReplyBaselineMessageId, false);
|
||||
}
|
||||
|
||||
static ChromeBindings buildChromeBindings(
|
||||
ProjectChatUiState.ChromeState chromeState,
|
||||
boolean composerBusy
|
||||
|
||||
Reference in New Issue
Block a user