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

推荐订阅源

G
Google Developers Blog
博客园 - 聂微东
J
Java Code Geeks
Engineering at Meta
Engineering at Meta
Jina AI
Jina AI
D
Docker
B
Blog
S
SegmentFault 最新的问题
宝玉的分享
宝玉的分享
D
DataBreaches.Net
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Y
Y Combinator Blog
N
Netflix TechBlog - Medium
月光博客
月光博客
F
Fortinet All Blogs
爱范儿
爱范儿
H
Help Net Security
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
WordPress大学
WordPress大学
The Cloudflare Blog
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
U
Unit 42

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
fix(agents): suppress abandoned requester completion hand...
steipete · 2026-05-28 · via Recent Commits to openclaw:main

@@ -24,10 +24,14 @@ import {

2424

ACTIVE_EMBEDDED_RUN_SESSION_IDS_BY_FILE,

2525

ACTIVE_EMBEDDED_RUN_SESSION_IDS_BY_KEY,

2626

ACTIVE_EMBEDDED_RUN_SNAPSHOTS,

27+

ABANDONED_EMBEDDED_RUNS_BY_SESSION_ID,

28+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_FILE,

29+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_KEY,

2730

EMBEDDED_RUN_MODEL_SWITCH_REQUESTS,

2831

EMBEDDED_RUN_WAITERS,

2932

getActiveEmbeddedRunCount,

3033

type ActiveEmbeddedRunSnapshot,

34+

type AbandonedEmbeddedRun,

3135

type EmbeddedAgentQueueHandle,

3236

type EmbeddedAgentQueueMessageOptions,

3337

type EmbeddedRunModelSwitchRequest,

@@ -136,6 +140,135 @@ function setActiveRunSessionFile(sessionFile: string | undefined, sessionId: str

136140

);

137141

}

138142143+

function clearEmbeddedRunAbandonmentBySessionId(sessionId: string): void {

144+

const abandonedRun = ABANDONED_EMBEDDED_RUNS_BY_SESSION_ID.get(sessionId);

145+

if (!abandonedRun) {

146+

return;

147+

}

148+

ABANDONED_EMBEDDED_RUNS_BY_SESSION_ID.delete(sessionId);

149+

const normalizedSessionKey = abandonedRun.sessionKey?.trim();

150+

if (

151+

normalizedSessionKey &&

152+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_KEY.get(normalizedSessionKey) === sessionId

153+

) {

154+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_KEY.delete(normalizedSessionKey);

155+

}

156+

const normalizedSessionFile = abandonedRun.sessionFile?.trim();

157+

if (normalizedSessionFile) {

158+

const sessionFileKey = resolveEmbeddedSessionFileKey(normalizedSessionFile);

159+

if (ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_FILE.get(sessionFileKey) === sessionId) {

160+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_FILE.delete(sessionFileKey);

161+

}

162+

}

163+

}

164+165+

function clearEmbeddedRunAbandonmentBySessionKey(sessionKey: string | undefined): void {

166+

const normalizedSessionKey = sessionKey?.trim();

167+

if (!normalizedSessionKey) {

168+

return;

169+

}

170+

const sessionId = ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_KEY.get(normalizedSessionKey);

171+

if (sessionId) {

172+

clearEmbeddedRunAbandonmentBySessionId(sessionId);

173+

}

174+

}

175+176+

function clearEmbeddedRunAbandonmentBySessionFile(sessionFile: string | undefined): void {

177+

const normalizedSessionFile = sessionFile?.trim();

178+

if (!normalizedSessionFile) {

179+

return;

180+

}

181+

const sessionFileKey = resolveEmbeddedSessionFileKey(normalizedSessionFile);

182+

const sessionId = ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_FILE.get(sessionFileKey);

183+

if (sessionId) {

184+

clearEmbeddedRunAbandonmentBySessionId(sessionId);

185+

}

186+

}

187+188+

export function clearEmbeddedRunAbandonment(params: {

189+

sessionId?: string;

190+

sessionKey?: string;

191+

sessionFile?: string;

192+

}): void {

193+

const normalizedSessionId = params.sessionId?.trim();

194+

if (normalizedSessionId) {

195+

clearEmbeddedRunAbandonmentBySessionId(normalizedSessionId);

196+

}

197+

clearEmbeddedRunAbandonmentBySessionKey(params.sessionKey);

198+

clearEmbeddedRunAbandonmentBySessionFile(params.sessionFile);

199+

}

200+201+

export function markEmbeddedRunAbandoned(params: {

202+

sessionId: string;

203+

sessionKey?: string;

204+

sessionFile?: string;

205+

reason: AbandonedEmbeddedRun["reason"];

206+

}): void {

207+

const sessionId = params.sessionId.trim();

208+

if (!sessionId) {

209+

return;

210+

}

211+

clearEmbeddedRunAbandonment({

212+

sessionId,

213+

sessionKey: params.sessionKey,

214+

sessionFile: params.sessionFile,

215+

});

216+

const abandonedRun: AbandonedEmbeddedRun = {

217+

sessionId,

218+

abandonedAtMs: Date.now(),

219+

reason: params.reason,

220+

...(params.sessionKey?.trim() ? { sessionKey: params.sessionKey.trim() } : {}),

221+

...(params.sessionFile?.trim() ? { sessionFile: params.sessionFile.trim() } : {}),

222+

};

223+

ABANDONED_EMBEDDED_RUNS_BY_SESSION_ID.set(sessionId, abandonedRun);

224+

if (abandonedRun.sessionKey) {

225+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_KEY.set(abandonedRun.sessionKey, sessionId);

226+

}

227+

if (abandonedRun.sessionFile) {

228+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_FILE.set(

229+

resolveEmbeddedSessionFileKey(abandonedRun.sessionFile),

230+

sessionId,

231+

);

232+

}

233+

}

234+235+

export function markActiveEmbeddedRunAbandoned(params: {

236+

sessionId: string;

237+

handle: EmbeddedAgentQueueHandle;

238+

sessionKey?: string;

239+

sessionFile?: string;

240+

reason: AbandonedEmbeddedRun["reason"];

241+

}): boolean {

242+

const sessionId = params.sessionId.trim();

243+

if (!sessionId || ACTIVE_EMBEDDED_RUNS.get(sessionId) !== params.handle) {

244+

return false;

245+

}

246+

markEmbeddedRunAbandoned(params);

247+

return true;

248+

}

249+250+

export function isEmbeddedRunAbandoned(params: {

251+

sessionId?: string;

252+

sessionKey?: string;

253+

sessionFile?: string;

254+

}): boolean {

255+

const normalizedSessionId = params.sessionId?.trim();

256+

if (normalizedSessionId && ABANDONED_EMBEDDED_RUNS_BY_SESSION_ID.has(normalizedSessionId)) {

257+

return true;

258+

}

259+

const normalizedSessionKey = params.sessionKey?.trim();

260+

if (normalizedSessionKey && ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_KEY.has(normalizedSessionKey)) {

261+

return true;

262+

}

263+

const normalizedSessionFile = params.sessionFile?.trim();

264+

return Boolean(

265+

normalizedSessionFile &&

266+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_FILE.has(

267+

resolveEmbeddedSessionFileKey(normalizedSessionFile),

268+

),

269+

);

270+

}

271+139272

function clearActiveRunSessionFiles(sessionId: string, sessionFile?: string): void {

140273

const normalizedSessionFile = sessionFile?.trim();

141274

if (normalizedSessionFile) {

@@ -586,6 +719,7 @@ export function setActiveEmbeddedRun(

586719

sessionFile?: string,

587720

) {

588721

const wasActive = ACTIVE_EMBEDDED_RUNS.has(sessionId);

722+

clearEmbeddedRunAbandonment({ sessionId, sessionKey, sessionFile });

589723

ACTIVE_EMBEDDED_RUNS.set(sessionId, handle);

590724

setActiveRunSessionKey(sessionKey, sessionId);

591725

clearActiveRunSessionFiles(sessionId);

@@ -692,6 +826,9 @@ export const testing = {

692826

ACTIVE_EMBEDDED_RUN_SNAPSHOTS.clear();

693827

ACTIVE_EMBEDDED_RUN_SESSION_IDS_BY_KEY.clear();

694828

ACTIVE_EMBEDDED_RUN_SESSION_IDS_BY_FILE.clear();

829+

ABANDONED_EMBEDDED_RUNS_BY_SESSION_ID.clear();

830+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_KEY.clear();

831+

ABANDONED_EMBEDDED_RUN_SESSION_IDS_BY_FILE.clear();

695832

EMBEDDED_RUN_MODEL_SWITCH_REQUESTS.clear();

696833

},

697834

};