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

推荐订阅源

D
DataBreaches.Net
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
博客园 - 聂微东
Microsoft Azure Blog
Microsoft Azure Blog
V
Visual Studio Blog
IT之家
IT之家
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
B
Blog
爱范儿
爱范儿
阮一峰的网络日志
阮一峰的网络日志
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
H
Help Net Security
J
Java Code Geeks
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
B
Blog RSS Feed
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
Apple Machine Learning Research
Apple Machine Learning Research

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: share talk transcription relay test setup · ope...
vincentkoc · 2026-06-02 · via Recent Commits to openclaw:main

@@ -11,6 +11,58 @@ import {

11111212

type BroadcastEvent = { event: string; payload: unknown; connIds: string[] };

131314+

function createSttSessionMock(connect: () => Promise<void> = async () => {}) {

15+

return {

16+

connect: vi.fn(connect),

17+

sendAudio: vi.fn(),

18+

close: vi.fn(),

19+

isConnected: vi.fn(() => true),

20+

};

21+

}

22+23+

function createTranscriptionProvider(

24+

sttSession: ReturnType<typeof createSttSessionMock>,

25+

onRequest?: (req: RealtimeTranscriptionSessionCreateRequest) => void,

26+

): RealtimeTranscriptionProviderPlugin {

27+

return {

28+

id: "stt-test",

29+

label: "STT Test",

30+

isConfigured: () => true,

31+

createSession: vi.fn((req) => {

32+

onRequest?.(req);

33+

return sttSession;

34+

}),

35+

};

36+

}

37+38+

function createBroadcastContext() {

39+

const events: BroadcastEvent[] = [];

40+

const context = {

41+

getRuntimeConfig: () => ({}),

42+

broadcastToConnIds: (event: string, payload: unknown, connIds: ReadonlySet<string>) => {

43+

events.push({ event, payload, connIds: [...connIds] });

44+

},

45+

} as never;

46+

return { context, events };

47+

}

48+49+

async function createStartedRelaySession(

50+

sttSession: ReturnType<typeof createSttSessionMock>,

51+

providerConfig: Record<string, unknown>,

52+

onRequest?: (req: RealtimeTranscriptionSessionCreateRequest) => void,

53+

) {

54+

const provider = createTranscriptionProvider(sttSession, onRequest);

55+

const { context, events } = createBroadcastContext();

56+

const session = createTalkTranscriptionRelaySession({

57+

context,

58+

connId: "conn-1",

59+

provider,

60+

providerConfig,

61+

});

62+

await Promise.resolve();

63+

return { provider, events, session };

64+

}

65+1466

function isRecord(value: unknown): value is Record<string, unknown> {

1567

return typeof value === "object" && value !== null && !Array.isArray(value);

1668

}

@@ -73,40 +125,14 @@ describe("talk transcription gateway relay", () => {

7312574126

it("bridges browser audio into a transcription-only Talk event stream", async () => {

75127

let sttRequest: RealtimeTranscriptionSessionCreateRequest | undefined;

76-

const sttSession = {

77-

connect: vi.fn(async () => {

78-

sttRequest?.onSpeechStart?.();

79-

sttRequest?.onPartial?.("hel");

80-

sttRequest?.onTranscript?.("hello world");

81-

}),

82-

sendAudio: vi.fn(),

83-

close: vi.fn(),

84-

isConnected: vi.fn(() => true),

85-

};

86-

const provider: RealtimeTranscriptionProviderPlugin = {

87-

id: "stt-test",

88-

label: "STT Test",

89-

isConfigured: () => true,

90-

createSession: (req) => {

91-

sttRequest = req;

92-

return sttSession;

93-

},

94-

};

95-

const events: Array<{ event: string; payload: unknown; connIds: string[] }> = [];

96-

const context = {

97-

getRuntimeConfig: () => ({}),

98-

broadcastToConnIds: (event: string, payload: unknown, connIds: ReadonlySet<string>) => {

99-

events.push({ event, payload, connIds: [...connIds] });

100-

},

101-

} as never;

102-103-

const session = createTalkTranscriptionRelaySession({

104-

context,

105-

connId: "conn-1",

106-

provider,

107-

providerConfig: { model: "stt-model" },

128+

const sttSession = createSttSessionMock(async () => {

129+

sttRequest?.onSpeechStart?.();

130+

sttRequest?.onPartial?.("hel");

131+

sttRequest?.onTranscript?.("hello world");

132+

});

133+

const { events, session } = await createStartedRelaySession(sttSession, { model: "stt-model" }, (req) => {

134+

sttRequest = req;

108135

});

109-

await Promise.resolve();

110136111137

expectRecordFields(session, "session", {

112138

provider: "stt-test",

@@ -202,22 +228,8 @@ describe("talk transcription gateway relay", () => {

202228

});

203229204230

it("rejects provider configs that do not match relay audio input", () => {

205-

const sttSession = {

206-

connect: vi.fn(async () => {}),

207-

sendAudio: vi.fn(),

208-

close: vi.fn(),

209-

isConnected: vi.fn(() => true),

210-

};

211-

const provider: RealtimeTranscriptionProviderPlugin = {

212-

id: "stt-test",

213-

label: "STT Test",

214-

isConfigured: () => true,

215-

createSession: vi.fn(() => sttSession),

216-

};

217-

const context = {

218-

getRuntimeConfig: () => ({}),

219-

broadcastToConnIds: vi.fn(),

220-

} as never;

231+

const provider = createTranscriptionProvider(createSttSessionMock());

232+

const { context } = createBroadcastContext();

221233222234

expect(() =>

223235

createTalkTranscriptionRelaySession({

@@ -233,22 +245,8 @@ describe("talk transcription gateway relay", () => {

233245

it("rejects session creation when transcription expiry would exceed Date range", () => {

234246

vi.useFakeTimers();

235247

vi.setSystemTime(new Date(8_640_000_000_000_000));

236-

const sttSession = {

237-

connect: vi.fn(async () => {}),

238-

sendAudio: vi.fn(),

239-

close: vi.fn(),

240-

isConnected: vi.fn(() => true),

241-

};

242-

const provider: RealtimeTranscriptionProviderPlugin = {

243-

id: "stt-test",

244-

label: "STT Test",

245-

isConfigured: () => true,

246-

createSession: vi.fn(() => sttSession),

247-

};

248-

const context = {

249-

getRuntimeConfig: () => ({}),

250-

broadcastToConnIds: vi.fn(),

251-

} as never;

248+

const provider = createTranscriptionProvider(createSttSessionMock());

249+

const { context } = createBroadcastContext();

252250253251

expect(() =>

254252

createTalkTranscriptionRelaySession({

@@ -263,38 +261,12 @@ describe("talk transcription gateway relay", () => {

263261264262

it("cancels an active transcription turn and closes the provider session", async () => {

265263

let sttRequest: RealtimeTranscriptionSessionCreateRequest | undefined;

266-

const sttSession = {

267-

connect: vi.fn(async () => {

268-

sttRequest?.onSpeechStart?.();

269-

}),

270-

sendAudio: vi.fn(),

271-

close: vi.fn(),

272-

isConnected: vi.fn(() => true),

273-

};

274-

const provider: RealtimeTranscriptionProviderPlugin = {

275-

id: "stt-test",

276-

label: "STT Test",

277-

isConfigured: () => true,

278-

createSession: (req) => {

279-

sttRequest = req;

280-

return sttSession;

281-

},

282-

};

283-

const events: Array<{ event: string; payload: unknown; connIds: string[] }> = [];

284-

const context = {

285-

getRuntimeConfig: () => ({}),

286-

broadcastToConnIds: (event: string, payload: unknown, connIds: ReadonlySet<string>) => {

287-

events.push({ event, payload, connIds: [...connIds] });

288-

},

289-

} as never;

290-291-

const session = createTalkTranscriptionRelaySession({

292-

context,

293-

connId: "conn-1",

294-

provider,

295-

providerConfig: {},

264+

const sttSession = createSttSessionMock(async () => {

265+

sttRequest?.onSpeechStart?.();

266+

});

267+

const { events, session } = await createStartedRelaySession(sttSession, {}, (req) => {

268+

sttRequest = req;

296269

});

297-

await Promise.resolve();

298270299271

cancelTalkTranscriptionRelayTurn({

300272

transcriptionSessionId: session.transcriptionSessionId,