

























@@ -1148,11 +1148,14 @@ export async function runReplyAgent(params: {
11481148throw error;
11491149}
11501150let runFollowupTurn = queuedRunFollowupTurn;
1151-let shouldDrainFollowupsAfterReplyOperationClears = false;
1152-const returnAfterReplyOperationClearsThenDrainFollowups = <T>(value: T): T => {
1153-shouldDrainFollowupsAfterReplyOperationClears = true;
1151+let shouldDrainQueuedFollowupsAfterClear = false;
1152+const returnWithQueuedFollowupDrain = <T>(value: T): T => {
1153+shouldDrainQueuedFollowupsAfterClear = true;
11541154return value;
11551155};
1156+const drainQueuedFollowupsAfterClear = () => {
1157+scheduleFollowupDrain(queueKey, runFollowupTurn);
1158+};
11561159const prePreflightCompactionCount = activeSessionEntry?.compactionCount ?? 0;
11571160let preflightCompactionApplied = false;
11581161@@ -1288,7 +1291,7 @@ export async function runReplyAgent(params: {
12881291if (!replyOperation.result) {
12891292replyOperation.fail("run_failed", new Error("reply operation exited with final payload"));
12901293}
1291-return returnAfterReplyOperationClearsThenDrainFollowups(runOutcome.payload);
1294+return returnWithQueuedFollowupDrain(runOutcome.payload);
12921295}
1293129612941297const {
@@ -1421,7 +1424,7 @@ export async function runReplyAgent(params: {
14211424// Otherwise, a late typing trigger (e.g. from a tool callback) can outlive the run and
14221425// keep the typing indicator stuck.
14231426if (payloadArray.length === 0) {
1424-return returnAfterReplyOperationClearsThenDrainFollowups(undefined);
1427+return returnWithQueuedFollowupDrain(undefined);
14251428}
1426142914271430const currentMessageId = sessionCtx.MessageSidFull ?? sessionCtx.MessageSid;
@@ -1453,7 +1456,7 @@ export async function runReplyAgent(params: {
14531456didLogHeartbeatStrip = payloadResult.didLogHeartbeatStrip;
1454145714551458if (replyPayloads.length === 0) {
1456-return returnAfterReplyOperationClearsThenDrainFollowups(undefined);
1459+return returnWithQueuedFollowupDrain(undefined);
14571460}
1458146114591462const successfulCronAdds = runResult.successfulCronAdds ?? 0;
@@ -1870,7 +1873,7 @@ export async function runReplyAgent(params: {
18701873}
18711874}
187218751873-const result = returnAfterReplyOperationClearsThenDrainFollowups(
1876+const result = returnWithQueuedFollowupDrain(
18741877finalPayloads.length === 1 ? finalPayloads[0] : finalPayloads,
18751878);
18761879@@ -1880,36 +1883,35 @@ export async function runReplyAgent(params: {
18801883replyOperation.result?.kind === "aborted" &&
18811884replyOperation.result.code === "aborted_for_restart"
18821885) {
1883-return returnAfterReplyOperationClearsThenDrainFollowups({
1886+return returnWithQueuedFollowupDrain({
18841887text: "⚠️ Gateway is restarting. Please wait a few seconds and try again.",
18851888});
18861889}
18871890if (replyOperation.result?.kind === "aborted") {
1888-return returnAfterReplyOperationClearsThenDrainFollowups({ text: SILENT_REPLY_TOKEN });
1891+return returnWithQueuedFollowupDrain({ text: SILENT_REPLY_TOKEN });
18891892}
18901893if (error instanceof GatewayDrainingError) {
18911894replyOperation.fail("gateway_draining", error);
1892-return returnAfterReplyOperationClearsThenDrainFollowups({
1895+return returnWithQueuedFollowupDrain({
18931896text: "⚠️ Gateway is restarting. Please wait a few seconds and try again.",
18941897});
18951898}
18961899if (error instanceof CommandLaneClearedError) {
18971900replyOperation.fail("command_lane_cleared", error);
1898-return returnAfterReplyOperationClearsThenDrainFollowups({
1901+return returnWithQueuedFollowupDrain({
18991902text: "⚠️ Gateway is restarting. Please wait a few seconds and try again.",
19001903});
19011904}
19021905replyOperation.fail("run_failed", error);
19031906// Keep the followup queue moving even when an unexpected exception escapes
19041907// the run path; the caller still receives the original error.
1905-returnAfterReplyOperationClearsThenDrainFollowups(undefined);
1908+returnWithQueuedFollowupDrain(undefined);
19061909throw error;
19071910} finally {
1908-replyOperation.complete();
1909-if (shouldDrainFollowupsAfterReplyOperationClears) {
1910-// Same-session follow-up turns create their own ReplyOperation; start them
1911-// only after this run clears the active-run guard.
1912-scheduleFollowupDrain(queueKey, runFollowupTurn);
1911+if (shouldDrainQueuedFollowupsAfterClear) {
1912+replyOperation.completeThen(drainQueuedFollowupsAfterClear);
1913+} else {
1914+replyOperation.complete();
19131915}
19141916blockReplyPipeline?.stop();
19151917typing.markRunComplete();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。