惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
云风的 BLOG
云风的 BLOG
小众软件
小众软件
V
V2EX
博客园 - Franky
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
量子位
博客园 - 【当耐特】
雷峰网
雷峰网
WordPress大学
WordPress大学
Jina AI
Jina AI
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
Visual Studio Blog
Microsoft Security Blog
Microsoft Security Blog

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
refactor(channels): share turn dispatch results · opencla...
steipete · 2026-04-30 · via Recent Commits to openclaw:main

File tree

  • docs/.generated

  • extensions

    • discord/src/monitor

    • imessage/src/monitor

    • line/src

    • matrix/src/matrix/monitor

    • msteams/src/monitor-handler

    • signal/src/monitor

    • slack/src/monitor/message-handler

    • telegram/src

    • whatsapp/src/auto-reply/monitor

  • src

    • channels

      • plugins/contracts

      • turn

    • plugin-sdk

      • test-helpers

Original file line numberDiff line numberDiff line change

@@ -1,2 +1,2 @@

1-

81de442c9e0c902621f316297af3ad6c48a07c0c6bbfa5ca984419cfdb7f4292 plugin-sdk-api-baseline.json

2-

136836d047bd0fb0723047945fdbd931a9128552ff49e8a27937d54dba0e9709 plugin-sdk-api-baseline.jsonl

1+

ae28566c922ce79527943b069abc199de28e3898ec08eea12c4ff6050795f276 plugin-sdk-api-baseline.json

2+

79446b23832949553b23e7cf92be37b81c69d123fc09bed6f8fc04bd98e9257d plugin-sdk-api-baseline.jsonl

Original file line numberDiff line numberDiff line change

@@ -13,7 +13,10 @@ import {

1313

} from "openclaw/plugin-sdk/channel-reply-pipeline";

1414

import { resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-streaming";

1515

import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";

16-

import { runPreparedInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";

16+

import {

17+

hasFinalInboundReplyDispatch,

18+

runPreparedInboundReplyTurn,

19+

} from "openclaw/plugin-sdk/inbound-reply-dispatch";

1720

import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";

1821

import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";

1922

import { resolveChunkMode } from "openclaw/plugin-sdk/reply-chunking";

@@ -643,7 +646,7 @@ export async function processDiscordMessage(

643646

return;

644647

}

645648
646-

if (!dispatchResult?.queuedFinal) {

649+

if (!hasFinalInboundReplyDispatch(dispatchResult)) {

647650

if (isGuildMessage) {

648651

clearHistoryEntriesIfEnabled({

649652

historyMap: guildHistories,

Original file line numberDiff line numberDiff line change

@@ -12,7 +12,10 @@ import {

1212

} from "openclaw/plugin-sdk/conversation-runtime";

1313

import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";

1414

import { normalizeScpRemoteHost } from "openclaw/plugin-sdk/host-runtime";

15-

import { runPreparedInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";

15+

import {

16+

hasFinalInboundReplyDispatch,

17+

runPreparedInboundReplyTurn,

18+

} from "openclaw/plugin-sdk/inbound-reply-dispatch";

1619

import { isInboundPathAllowed, kindFromMime } from "openclaw/plugin-sdk/media-runtime";

1720

import {

1821

clearHistoryEntriesIfEnabled,

@@ -487,9 +490,7 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P

487490

},

488491

}),

489492

});

490-

const queuedFinal = dispatchResult.queuedFinal;

491-
492-

if (!queuedFinal) {

493+

if (!hasFinalInboundReplyDispatch(dispatchResult)) {

493494

if (decision.isGroup && decision.historyKey) {

494495

clearHistoryEntriesIfEnabled({

495496

historyMap: groupHistories,

Original file line numberDiff line numberDiff line change

@@ -2,7 +2,10 @@ import type { webhook } from "@line/bot-sdk";

22

import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";

33

import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";

44

import { recordInboundSession } from "openclaw/plugin-sdk/conversation-runtime";

5-

import { runPreparedInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";

5+

import {

6+

hasFinalInboundReplyDispatch,

7+

runPreparedInboundReplyTurn,

8+

} from "openclaw/plugin-sdk/inbound-reply-dispatch";

69

import {

710

dispatchReplyWithBufferedBlockDispatcher,

811

chunkMarkdownText,

@@ -306,9 +309,7 @@ export async function monitorLineProvider(

306309

},

307310

}),

308311

});

309-

const queuedFinal = dispatchResult.queuedFinal;

310-
311-

if (!queuedFinal) {

312+

if (!hasFinalInboundReplyDispatch(dispatchResult)) {

312313

logVerbose(`line: no response generated for message from ${ctxPayload.From}`);

313314

}

314315

} catch (err) {

Original file line numberDiff line numberDiff line change

@@ -3,6 +3,7 @@ import {

33

evaluateSupplementalContextVisibility,

44

resolveChannelContextVisibilityMode,

55

} from "openclaw/plugin-sdk/context-visibility-runtime";

6+

import { hasFinalInboundReplyDispatch } from "openclaw/plugin-sdk/inbound-reply-dispatch";

67

import type { GetReplyOptions } from "openclaw/plugin-sdk/reply-runtime";

78

import {

89

loadSessionStore,

@@ -1963,7 +1964,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam

19631964

if (isRoom && triggerSnapshot) {

19641965

roomHistoryTracker.consumeHistory(_route.agentId, roomId, triggerSnapshot, _messageId);

19651966

}

1966-

if (!queuedFinal) {

1967+

if (!hasFinalInboundReplyDispatch({ queuedFinal, counts })) {

19671968

await commitInboundEventIfClaimed();

19681969

return;

19691970

}

Original file line numberDiff line numberDiff line change

@@ -11,7 +11,11 @@ import {

1111

shouldIncludeSupplementalContext,

1212

} from "openclaw/plugin-sdk/context-visibility-runtime";

1313

import { evaluateSenderGroupAccessForPolicy } from "openclaw/plugin-sdk/group-access";

14-

import { dispatchReplyFromConfigWithSettledDispatcher } from "openclaw/plugin-sdk/inbound-reply-dispatch";

14+

import {

15+

dispatchReplyFromConfigWithSettledDispatcher,

16+

hasFinalInboundReplyDispatch,

17+

resolveInboundReplyDispatchCounts,

18+

} from "openclaw/plugin-sdk/inbound-reply-dispatch";

1519

import {

1620

buildPendingHistoryContextFromMap,

1721

clearHistoryEntriesIfEnabled,

@@ -864,11 +868,12 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {

864868

}),

865869

});

866870

const queuedFinal = dispatchResult?.queuedFinal ?? false;

867-

const counts = dispatchResult?.counts ?? { tool: 0, block: 0, final: 0 };

871+

const counts = resolveInboundReplyDispatchCounts(dispatchResult);

872+

const hasFinalResponse = hasFinalInboundReplyDispatch(dispatchResult);

868873
869874

log.info("dispatch complete", { queuedFinal, counts });

870875
871-

if (!queuedFinal) {

876+

if (!hasFinalResponse) {

872877

if (isRoomish && historyKey) {

873878

clearHistoryEntriesIfEnabled({

874879

historyMap: conversationHistories,

Original file line numberDiff line numberDiff line change

@@ -25,7 +25,10 @@ import {

2525

toInternalMessageReceivedContext,

2626

triggerInternalHook,

2727

} from "openclaw/plugin-sdk/hook-runtime";

28-

import { runPreparedInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";

28+

import {

29+

hasFinalInboundReplyDispatch,

30+

runPreparedInboundReplyTurn,

31+

} from "openclaw/plugin-sdk/inbound-reply-dispatch";

2932

import { kindFromMime } from "openclaw/plugin-sdk/media-runtime";

3033

import {

3134

buildPendingHistoryContextFromMap,

@@ -351,8 +354,7 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {

351354

}

352355

},

353356

});

354-

const queuedFinal = dispatchResult?.queuedFinal ?? false;

355-

if (!queuedFinal) {

357+

if (!hasFinalInboundReplyDispatch(dispatchResult)) {

356358

if (entry.isGroup && historyKey) {

357359

clearHistoryEntriesIfEnabled({

358360

historyMap: deps.groupHistories,

Original file line numberDiff line numberDiff line change

@@ -18,7 +18,10 @@ import {

1818

resolveChannelStreamingPreviewToolProgress,

1919

} from "openclaw/plugin-sdk/channel-streaming";

2020

import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";

21-

import { runPreparedInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";

21+

import {

22+

hasVisibleInboundReplyDispatch,

23+

runPreparedInboundReplyTurn,

24+

} from "openclaw/plugin-sdk/inbound-reply-dispatch";

2225

import { resolveAgentOutboundIdentity } from "openclaw/plugin-sdk/outbound-runtime";

2326

import { clearHistoryEntriesIfEnabled } from "openclaw/plugin-sdk/reply-history";

2427

import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";

@@ -1099,12 +1102,13 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag

10991102

}

11001103

}

11011104
1102-

const anyReplyDelivered =

1103-

observedReplyDelivery ||

1104-

queuedFinal ||

1105-

streamFallbackDelivered ||

1106-

(counts.block ?? 0) > 0 ||

1107-

(counts.final ?? 0) > 0;

1105+

const anyReplyDelivered = hasVisibleInboundReplyDispatch(

1106+

{ queuedFinal, counts },

1107+

{

1108+

observedReplyDelivery,

1109+

fallbackDelivered: streamFallbackDelivered,

1110+

},

1111+

);

11081112
11091113

if (statusReactionsEnabled) {

11101114

if (dispatchError) {

Original file line numberDiff line numberDiff line change

@@ -17,7 +17,10 @@ import type {

1717

TelegramAccountConfig,

1818

} from "openclaw/plugin-sdk/config-types";

1919

import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";

20-

import { runPreparedInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";

20+

import {

21+

hasFinalInboundReplyDispatch,

22+

runPreparedInboundReplyTurn,

23+

} from "openclaw/plugin-sdk/inbound-reply-dispatch";

2124

import {

2225

createOutboundPayloadPlan,

2326

projectOutboundPayloadPlanForDelivery,

@@ -1306,7 +1309,13 @@ export const dispatchTelegramMessage = async ({

13061309

});

13071310

}

13081311
1309-

const hasFinalResponse = queuedFinal || sentFallback || deliverySummary.delivered;

1312+

const hasFinalResponse = hasFinalInboundReplyDispatch(

1313+

{ queuedFinal },

1314+

{

1315+

fallbackDelivered: sentFallback,

1316+

deliverySummaryDelivered: deliverySummary.delivered,

1317+

},

1318+

);

13101319
13111320

if (statusReactionController && !hasFinalResponse) {

13121321

void finalizeTelegramStatusReaction({ outcome: "error", hasFinalResponse: false }).catch(

Original file line numberDiff line numberDiff line change

@@ -1,3 +1,4 @@

1+

import { hasVisibleInboundReplyDispatch } from "openclaw/plugin-sdk/inbound-reply-dispatch";

12

import {

23

type DeliverableWhatsAppOutboundPayload,

34

normalizeWhatsAppOutboundPayload,

@@ -388,8 +389,7 @@ export async function dispatchWhatsAppBufferedReply(params: {

388389

},

389390

});

390391
391-

const didQueueVisibleReply =

392-

queuedFinal || counts.tool > 0 || counts.block > 0 || counts.final > 0;

392+

const didQueueVisibleReply = hasVisibleInboundReplyDispatch({ queuedFinal, counts });

393393

if (!didQueueVisibleReply) {

394394

if (params.shouldClearGroupHistory) {

395395

params.groupHistories.set(params.groupHistoryKey, []);