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

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

Recent Commits to openclaw:main

fix(memory): respect QMD status timeout fix(scripts): timeout crabbox wrapper sanity checks refactor(telegram): keep topic thread mapping plugin-local fix(memory): fail open when embedding recall stalls feat(doctor): expose UI freshness health findings docs: expand MCP operator guide chore(ui): refresh fa control ui locale chore(ui): refresh nl control ui locale · openclaw/openclaw@53e0639 chore(ui): refresh vi control ui locale chore(ui): refresh pl control ui locale · openclaw/openclaw@ee39aa8 chore(ui): refresh th control ui locale chore(ui): refresh id control ui locale · openclaw/openclaw@fce45a2 chore(ui): refresh uk control ui locale chore(ui): refresh tr control ui locale · openclaw/openclaw@b335018 chore(ui): refresh ar control ui locale chore(ui): refresh it control ui locale · openclaw/openclaw@20ab73e chore(ui): refresh fr control ui locale · openclaw/openclaw@a041e39 chore(ui): refresh ko control ui locale · openclaw/openclaw@2e0d191 chore(ui): refresh ja-JP control ui locale · openclaw/openclaw@ec949a8 chore(ui): refresh es control ui locale · openclaw/openclaw@0b9193c chore(ui): refresh pt-BR control ui locale · openclaw/openclaw@aa56f59 chore(ui): refresh zh-TW control ui locale · openclaw/openclaw@10b4057 chore(ui): refresh zh-CN control ui locale · openclaw/openclaw@ecef6ae chore(ui): refresh de control ui locale · openclaw/openclaw@f456114 feat: improve MCP operator controls (#88536) · openclaw/openclaw@617c658 chore(lint): clean sms lint fallout · openclaw/openclaw@3258338 fix(ci): repair sms channel checks · openclaw/openclaw@3a4943e fix(e2e): make plugin sweep wrappers executable · openclaw/openclaw@84b025e fix(auto-reply): redact secrets in config show output (#88496) · openclaw/openclaw@a776de2 fix(ci): repair copilot sdk drift chore(lint): enable object and reassignment rules · openclaw/openclaw@f5eca3f docs: expand SMS channel setup guide · openclaw/openclaw@ea11b8a ci: harden Crabbox Testbox runs · openclaw/openclaw@d4f78c9 fix(webchat): preserve refresh-visible history and composer state (#8… fix(check): restore core typecheck feat: add Twilio SMS channel fix(telegram): support media message edits chore: remove stale unsafe assertion suppressions Revert "fix(ci): annotate unsafe boundary casts" fix(ci): keep unsafe assertion lint disabled Revert "fix(ci): clean core unsafe assertions" · openclaw/openclaw@4471335 test: remove channel test isolation hack fix(agents): clear stale compaction bindings fix(agents): skip below-target CLI compaction failures · openclaw/openclaw@5e1e029 chore: update dependencies · openclaw/openclaw@48ccc50 docs: add Skill Workshop guide docs: remove divider comments (#88115) fix(ci): clean core unsafe assertions fix(discord): deliver same-session channel replies fix(ci): annotate unsafe boundary casts · openclaw/openclaw@8a40f90 docs: add permission modes page · openclaw/openclaw@ae651e7 fix(ci): repair extension type drift · openclaw/openclaw@4d95ae3 perf: avoid blocking gateway bind on control ui build · openclaw/openclaw@e678225 chore(lint): enable structured clone rules · openclaw/openclaw@59694e8 Fix iMessage startup watch replay (#88406) · openclaw/openclaw@87664ed fix(ci): isolate timer-sensitive tests perf: lazy-load agent reply payload formatter · openclaw/openclaw@122ae5d refactor(telegram): persist plugin state in sqlite · openclaw/openclaw@930b371 chore(lint): enable additional cleanup rules · openclaw/openclaw@b9fe089 chore: remove stale dead code · openclaw/openclaw@444562b fix(ci): stabilize ui paste and telegram types · openclaw/openclaw@ce547bf fix(ci): satisfy strict nullish guards · openclaw/openclaw@d4d7fdb build(OpenClawKit): make ElevenLabsKit optional behind Talk trait · openclaw/openclaw@096bd13 chore(lint): enable more readability rules fix(ci): stop channel timers holding vitest open chore(lint): enable readability lint rules · openclaw/openclaw@deb7bc6 fix(ci): restore main validation · openclaw/openclaw@0211a3a perf: prewarm gateway runtime plugins · openclaw/openclaw@ade6e77 fix(slack): keep DM thread turns out of active steering · openclaw/openclaw@f1cb9f2 fix(commands): make /skill load workspace skills · openclaw/openclaw@667393b fix(telegram): align DM topic session routing · openclaw/openclaw@72c61bc test: keep timeout clamp checks under one second · openclaw/openclaw@b372af6 test: keep vitest cases under one second test: restore marketplace cleanup coverage · openclaw/openclaw@9f99acf fix(shared): restore number coercion barrel fix: clarify generated media reply prompts (#88458) · openclaw/openclaw@8a46790 fix(qa): clamp transport wait intervals fix(qa): clamp gateway restart polling fix(channels): clamp typing timers · openclaw/openclaw@92f1d90 fix(agents): clamp embedded run drain polling fix(sqlite): clamp WAL checkpoint intervals · openclaw/openclaw@287f531 fix(onboard): clamp gateway reachability polling · openclaw/openclaw@bb680a8 fix(feishu): clamp sequential queue timeouts · openclaw/openclaw@fab8d29 fix(nostr): bound seen tracker capacity · openclaw/openclaw@5b0036f fix(agents): clamp session suspension TTLs · openclaw/openclaw@11c050d fix(memory): clamp batch timeout minutes · openclaw/openclaw@84061c1 fix(gateway): clamp auth limiter prune intervals · openclaw/openclaw@a1d7a75 fix(memory): clamp sync interval timers · openclaw/openclaw@5c38c0c fix(channels): clamp draft stream throttles fix(gateway): clamp auth limiter durations fix(clickclack): normalize reconnect intervals fix(qa): clamp cron run poll intervals · openclaw/openclaw@83597b7 fix(gateway): bound health monitor intervals fix(auth): bound profile usage window expiries fix(auto-reply): clamp typing timers · openclaw/openclaw@db94eac fix(openai): convert realtime secret expiry · openclaw/openclaw@dca53af fix(heartbeat): advance stale scheduler deferrals · openclaw/openclaw@bbc4bee fix(build): preserve fresh startup metadata across rebuilds perf: cache log timestamp formatters fix(ui): localize tool error card label
fix(ui): prefer Talk source-reply final text · openclaw/openclaw@17c2e95
TurboTheTurt · 2026-05-31 · via Recent Commits to openclaw:main

@@ -197,6 +197,21 @@ type ChatPayload = {

197197

message?: unknown;

198198

};

199199200+

type AgentWaitResult = {

201+

status?: string;

202+

error?: string;

203+

stopReason?: string;

204+

endedAt?: number;

205+

pendingError?: boolean;

206+

timeoutPhase?: string;

207+

providerStarted?: boolean;

208+

aborted?: boolean;

209+

livenessState?: string;

210+

yielded?: boolean;

211+

};

212+213+

const EMPTY_FINAL_FALLBACK_GRACE_MS = 500;

214+200215

function extractTextFromMessage(message: unknown): string {

201216

if (!message || typeof message !== "object") {

202217

return "";

@@ -218,6 +233,37 @@ function extractTextFromMessage(message: unknown): string {

218233

return parts.join("\n\n").trim();

219234

}

220235236+

function getTerminalAgentWaitError(result: AgentWaitResult | undefined): Error | undefined {

237+

if (!result) {

238+

return undefined;

239+

}

240+

const message = result.error?.trim();

241+

if (result.status === "error") {

242+

return new Error(message || "OpenClaw tool call failed");

243+

}

244+

if (result.status !== "timeout" || result.pendingError) {

245+

return undefined;

246+

}

247+

const stopReason = result.stopReason?.trim();

248+

const timeoutPhase = result.timeoutPhase?.trim();

249+

const livenessState = result.livenessState?.trim();

250+

const hasTerminalTimeoutMetadata =

251+

result.endedAt !== undefined ||

252+

message !== undefined ||

253+

result.aborted === true ||

254+

(livenessState !== undefined && livenessState.length > 0) ||

255+

result.yielded === true ||

256+

(stopReason !== undefined && stopReason.length > 0) ||

257+

timeoutPhase === "preflight" ||

258+

timeoutPhase === "provider" ||

259+

timeoutPhase === "post_turn" ||

260+

result.providerStarted === true;

261+

if (hasTerminalTimeoutMetadata) {

262+

return new Error(message || "OpenClaw tool call timed out");

263+

}

264+

return undefined;

265+

}

266+221267

function waitForChatResult(params: {

222268

client: GatewayBrowserClient;

223269

runId: string;

@@ -231,15 +277,62 @@ function waitForChatResult(params: {

231277

return;

232278

}

233279

const timer = window.setTimeout(() => {

234-

cleanup();

235-

reject(new Error("OpenClaw tool call timed out"));

280+

settleReject(new Error("OpenClaw tool call timed out"));

236281

}, params.timeoutMs);

282+

let settled = false;

283+

let emptyFinalWaitStarted = false;

284+

let emptyFinalFallbackTimer: number | undefined;

237285

const onAbort = () => {

238-

cleanup();

239-

reject(new DOMException("OpenClaw tool call aborted", "AbortError"));

286+

settleReject(new DOMException("OpenClaw tool call aborted", "AbortError"));

240287

};

241288

params.signal?.addEventListener("abort", onAbort, { once: true });

242289

let unsubscribe: () => void = () => undefined;

290+

const settleResolve = (value: string) => {

291+

if (settled) {

292+

return;

293+

}

294+

settled = true;

295+

cleanup();

296+

resolve(value);

297+

};

298+

const settleReject = (error: Error | DOMException) => {

299+

if (settled) {

300+

return;

301+

}

302+

settled = true;

303+

cleanup();

304+

reject(error);

305+

};

306+

const waitForEmptyFinalFallback = () => {

307+

if (emptyFinalWaitStarted) {

308+

return;

309+

}

310+

emptyFinalWaitStarted = true;

311+

void params.client

312+

.request<AgentWaitResult>("agent.wait", {

313+

runId: params.runId,

314+

timeoutMs: params.timeoutMs,

315+

})

316+

.then((result) => {

317+

if (settled) {

318+

return;

319+

}

320+

const waitError = getTerminalAgentWaitError(result);

321+

if (waitError) {

322+

settleReject(waitError);

323+

return;

324+

}

325+

if (result?.status === "timeout") {

326+

return;

327+

}

328+

emptyFinalFallbackTimer = window.setTimeout(() => {

329+

settleResolve("OpenClaw finished with no text.");

330+

}, EMPTY_FINAL_FALLBACK_GRACE_MS);

331+

})

332+

.catch((error) => {

333+

settleReject(error instanceof Error ? error : new Error(String(error)));

334+

});

335+

};

243336

unsubscribe = params.client.addEventListener((evt: GatewayEventFrame) => {

244337

if (evt.event !== "chat") {

245338

return;

@@ -250,20 +343,25 @@ function waitForChatResult(params: {

250343

}

251344

emitRealtimeTalkAgentProgress(params.emitTalkEvent, payload);

252345

if (payload.state === "final") {

253-

cleanup();

254-

resolve(extractTextFromMessage(payload.message) || "OpenClaw finished with no text.");

346+

const finalText = extractTextFromMessage(payload.message);

347+

if (finalText) {

348+

settleResolve(finalText);

349+

return;

350+

}

351+

waitForEmptyFinalFallback();

255352

} else if (payload.state === "aborted") {

256-

cleanup();

257-

reject(

353+

settleReject(

258354

new DOMException(payload.errorMessage ?? "OpenClaw tool call aborted", "AbortError"),

259355

);

260356

} else if (payload.state === "error") {

261-

cleanup();

262-

reject(new Error(payload.errorMessage ?? "OpenClaw tool call failed"));

357+

settleReject(new Error(payload.errorMessage ?? "OpenClaw tool call failed"));

263358

}

264359

});

265360

function cleanup() {

266361

window.clearTimeout(timer);

362+

if (emptyFinalFallbackTimer !== undefined) {

363+

window.clearTimeout(emptyFinalFallbackTimer);

364+

}

267365

params.signal?.removeEventListener("abort", onAbort);

268366

unsubscribe();

269367

}