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

推荐订阅源

V
V2EX
博客园 - 叶小钗
Last Week in AI
Last Week in AI
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
P
Proofpoint News Feed
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
量子位
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
Apple Machine Learning Research
Apple Machine Learning Research
Jina AI
Jina AI
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
D
DataBreaches.Net
博客园_首页
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow 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: table-drive lifecycle state tests · openclaw/op...
vincentkoc · 2026-06-02 · via Recent Commits to openclaw:main

@@ -5,6 +5,54 @@ import {

55

isStaleLifecycleEventForSession,

66

} from "./session-lifecycle-state.js";

778+

type PersistedLifecycleInput = Parameters<typeof derivePersistedSessionLifecyclePatch>[0];

9+

type PersistedLifecycleData = PersistedLifecycleInput["event"]["data"];

10+

type PersistedLifecyclePatch = NonNullable<ReturnType<typeof derivePersistedSessionLifecyclePatch>>;

11+

type PersistedLifecycleStatus = PersistedLifecyclePatch["status"];

12+13+

type PersistedLifecycleCase = {

14+

name: string;

15+

data: PersistedLifecycleData;

16+

status: PersistedLifecycleStatus;

17+

abortedLastRun: boolean;

18+

};

19+20+

function terminalPatch(

21+

startedAt: number,

22+

endedAt: number,

23+

status: PersistedLifecycleStatus,

24+

abortedLastRun: boolean,

25+

): PersistedLifecyclePatch {

26+

return {

27+

updatedAt: endedAt,

28+

status,

29+

startedAt,

30+

endedAt,

31+

runtimeMs: endedAt - startedAt,

32+

abortedLastRun,

33+

};

34+

}

35+36+

function expectPersistedLifecyclePatch(options: {

37+

entry?: Partial<PersistedLifecycleInput["entry"]>;

38+

data: PersistedLifecycleData;

39+

expected: ReturnType<typeof derivePersistedSessionLifecyclePatch>;

40+

}): void {

41+

expect(

42+

derivePersistedSessionLifecyclePatch({

43+

entry: {

44+

updatedAt: 1_000,

45+

startedAt: 1_050,

46+

...options.entry,

47+

},

48+

event: {

49+

ts: 2_000,

50+

data: options.data,

51+

},

52+

}),

53+

).toEqual(options.expected);

54+

}

55+856

describe("session lifecycle state", () => {

957

it("treats a pre-reset run's lifecycle event as stale once the row's sessionId rotated (#88538)", () => {

1058

expect(

@@ -81,168 +129,82 @@ describe("session lifecycle state", () => {

81129

});

8213083131

it("maps aborted stop reasons to killed", () => {

84-

expect(

85-

derivePersistedSessionLifecyclePatch({

86-

entry: {

87-

updatedAt: 1_000,

88-

startedAt: 1_100,

89-

},

90-

event: {

91-

ts: 2_000,

92-

data: {

93-

phase: "end",

94-

endedAt: 1_800,

95-

stopReason: "aborted",

96-

},

97-

},

98-

}),

99-

).toEqual({

100-

updatedAt: 1_800,

101-

status: "killed",

102-

startedAt: 1_100,

103-

endedAt: 1_800,

104-

runtimeMs: 700,

105-

abortedLastRun: true,

132+

expectPersistedLifecyclePatch({

133+

entry: { startedAt: 1_100 },

134+

data: {

135+

phase: "end",

136+

endedAt: 1_800,

137+

stopReason: "aborted",

138+

},

139+

expected: terminalPatch(1_100, 1_800, "killed", true),

106140

});

107141

});

108142109-

it("maps aborted lifecycle end events without stopReason to timeout", () => {

110-

expect(

111-

derivePersistedSessionLifecyclePatch({

112-

entry: {

113-

updatedAt: 1_000,

114-

startedAt: 1_050,

115-

},

116-

event: {

117-

ts: 2_000,

118-

data: {

119-

phase: "end",

120-

endedAt: 1_550,

121-

aborted: true,

122-

},

123-

},

124-

}),

125-

).toEqual({

126-

updatedAt: 1_550,

143+

it.each<PersistedLifecycleCase>([

144+

{

145+

name: "maps aborted lifecycle end events without stopReason to timeout",

146+

data: {

147+

phase: "end",

148+

endedAt: 1_550,

149+

aborted: true,

150+

},

127151

status: "timeout",

128-

startedAt: 1_050,

129-

endedAt: 1_550,

130-

runtimeMs: 500,

131152

abortedLastRun: false,

132-

});

133-

});

134-135-

it("keeps provider hard timeouts stronger than rpc cancellation metadata", () => {

136-

expect(

137-

derivePersistedSessionLifecyclePatch({

138-

entry: {

139-

updatedAt: 1_000,

140-

startedAt: 1_050,

141-

},

142-

event: {

143-

ts: 2_000,

144-

data: {

145-

phase: "end",

146-

aborted: true,

147-

stopReason: "rpc",

148-

timeoutPhase: "provider",

149-

providerStarted: true,

150-

endedAt: 1_550,

151-

},

152-

},

153-

}),

154-

).toEqual({

155-

updatedAt: 1_550,

153+

},

154+

{

155+

name: "keeps provider hard timeouts stronger than rpc cancellation metadata",

156+

data: {

157+

phase: "end",

158+

aborted: true,

159+

stopReason: "rpc",

160+

timeoutPhase: "provider",

161+

providerStarted: true,

162+

endedAt: 1_550,

163+

},

156164

status: "timeout",

157-

startedAt: 1_050,

158-

endedAt: 1_550,

159-

runtimeMs: 500,

160165

abortedLastRun: false,

161-

});

162-

});

163-164-

it("maps non-hard rpc lifecycle aborts to killed sessions", () => {

165-

expect(

166-

derivePersistedSessionLifecyclePatch({

167-

entry: {

168-

updatedAt: 1_000,

169-

startedAt: 1_050,

170-

},

171-

event: {

172-

ts: 2_000,

173-

data: {

174-

phase: "end",

175-

aborted: true,

176-

stopReason: "rpc",

177-

timeoutPhase: "queue",

178-

providerStarted: false,

179-

endedAt: 1_550,

180-

},

181-

},

182-

}),

183-

).toEqual({

184-

updatedAt: 1_550,

166+

},

167+

{

168+

name: "maps non-hard rpc lifecycle aborts to killed sessions",

169+

data: {

170+

phase: "end",

171+

aborted: true,

172+

stopReason: "rpc",

173+

timeoutPhase: "queue",

174+

providerStarted: false,

175+

endedAt: 1_550,

176+

},

185177

status: "killed",

186-

startedAt: 1_050,

187-

endedAt: 1_550,

188-

runtimeMs: 500,

189178

abortedLastRun: true,

190-

});

191-

});

192-193-

it("maps provider timeout lifecycle errors to timed out sessions", () => {

194-

expect(

195-

derivePersistedSessionLifecyclePatch({

196-

entry: {

197-

updatedAt: 1_000,

198-

startedAt: 1_050,

199-

},

200-

event: {

201-

ts: 2_000,

202-

data: {

203-

phase: "error",

204-

error: "provider request timed out",

205-

livenessState: "blocked",

206-

timeoutPhase: "provider",

207-

providerStarted: true,

208-

endedAt: 1_550,

209-

},

210-

},

211-

}),

212-

).toEqual({

213-

updatedAt: 1_550,

179+

},

180+

{

181+

name: "maps provider timeout lifecycle errors to timed out sessions",

182+

data: {

183+

phase: "error",

184+

error: "provider request timed out",

185+

livenessState: "blocked",

186+

timeoutPhase: "provider",

187+

providerStarted: true,

188+

endedAt: 1_550,

189+

},

214190

status: "timeout",

215-

startedAt: 1_050,

216-

endedAt: 1_550,

217-

runtimeMs: 500,

218191

abortedLastRun: false,

219-

});

220-

});

221-222-

it("maps provider timeout lifecycle end metadata to timed out sessions", () => {

223-

expect(

224-

derivePersistedSessionLifecyclePatch({

225-

entry: {

226-

updatedAt: 1_000,

227-

startedAt: 1_050,

228-

},

229-

event: {

230-

ts: 2_000,

231-

data: {

232-

phase: "end",

233-

timeoutPhase: "provider",

234-

providerStarted: true,

235-

endedAt: 1_550,

236-

},

237-

},

238-

}),

239-

).toEqual({

240-

updatedAt: 1_550,

192+

},

193+

{

194+

name: "maps provider timeout lifecycle end metadata to timed out sessions",

195+

data: {

196+

phase: "end",

197+

timeoutPhase: "provider",

198+

providerStarted: true,

199+

endedAt: 1_550,

200+

},

241201

status: "timeout",

242-

startedAt: 1_050,

243-

endedAt: 1_550,

244-

runtimeMs: 500,

245202

abortedLastRun: false,

203+

},

204+

])("$name", ({ data, status, abortedLastRun }) => {

205+

expectPersistedLifecyclePatch({

206+

data,

207+

expected: terminalPatch(1_050, 1_550, status, abortedLastRun),

246208

});

247209

});

248210

});