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

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
B
Blog
A
About on SuperTechFans
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
IT之家
IT之家
D
Docker
Google DeepMind News
Google DeepMind News
罗磊的独立博客
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
博客园 - 司徒正美
Engineering at Meta
Engineering at Meta

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
test: tighten openrouter provider assertions · openclaw/o...
steipete · 2026-05-11 · via Recent Commits to openclaw:main

@@ -30,18 +30,18 @@ describe("openrouter provider hooks", () => {

3030

kind: "video_generation",

3131

});

323233-

expect(providers).toEqual([expect.objectContaining({ id: "openrouter" })]);

34-

expect(speechProviders).toEqual([expect.objectContaining({ id: "openrouter" })]);

35-

expect(mediaProviders).toEqual([expect.objectContaining({ id: "openrouter" })]);

36-

expect(imageProviders).toEqual([expect.objectContaining({ id: "openrouter" })]);

37-

expect(videoProviders).toEqual([expect.objectContaining({ id: "openrouter" })]);

38-

expect(modelCatalogProvider.liveCatalog).toEqual(expect.any(Function));

33+

expect(providers.map((provider) => provider.id)).toEqual(["openrouter"]);

34+

expect(speechProviders.map((provider) => provider.id)).toEqual(["openrouter"]);

35+

expect(mediaProviders.map((provider) => provider.id)).toEqual(["openrouter"]);

36+

expect(imageProviders.map((provider) => provider.id)).toEqual(["openrouter"]);

37+

expect(videoProviders.map((provider) => provider.id)).toEqual(["openrouter"]);

38+

expect(modelCatalogProvider.liveCatalog).toBeTypeOf("function");

3939

});

40404141

it("includes current Kimi models in the bundled catalog", () => {

42-

expect(buildOpenrouterProvider().models?.map((model) => model.id)).toEqual(

43-

expect.arrayContaining(["moonshotai/kimi-k2.6", "moonshotai/kimi-k2.5"]),

44-

);

42+

const modelIds = buildOpenrouterProvider().models?.map((model) => model.id) ?? [];

43+

expect(modelIds).toContain("moonshotai/kimi-k2.6");

44+

expect(modelIds).toContain("moonshotai/kimi-k2.5");

4545

});

46464747

it("uses the canonical prefixed OpenRouter auto model id", () => {

@@ -50,9 +50,9 @@ describe("openrouter provider hooks", () => {

5050

});

51515252

it("does not include retired stealth models in the bundled catalog", () => {

53-

expect(buildOpenrouterProvider().models?.map((model) => model.id)).not.toEqual(

54-

expect.arrayContaining(["openrouter/hunter-alpha", "openrouter/healer-alpha"]),

55-

);

53+

const modelIds = buildOpenrouterProvider().models?.map((model) => model.id) ?? [];

54+

expect(modelIds).not.toContain("openrouter/hunter-alpha");

55+

expect(modelIds).not.toContain("openrouter/healer-alpha");

5656

});

57575858

it("keeps stale Hunter Alpha configs out of OpenRouter proxy reasoning", () => {

@@ -137,58 +137,49 @@ describe("openrouter provider hooks", () => {

137137

it("canonicalizes stale OpenRouter /v1 config and runtime metadata", async () => {

138138

const provider = await registerSingleProviderPlugin(openrouterPlugin);

139139140-

expect(

141-

provider.normalizeConfig?.({

142-

provider: "openrouter",

143-

providerConfig: {

144-

api: "openai-completions",

145-

baseUrl: "https://openrouter.ai/v1/",

146-

models: [],

147-

},

148-

} as never),

149-

).toMatchObject({

150-

baseUrl: "https://openrouter.ai/api/v1",

151-

});

140+

const normalizedConfig = provider.normalizeConfig?.({

141+

provider: "openrouter",

142+

providerConfig: {

143+

api: "openai-completions",

144+

baseUrl: "https://openrouter.ai/v1/",

145+

models: [],

146+

},

147+

} as never);

148+

expect(normalizedConfig?.baseUrl).toBe("https://openrouter.ai/api/v1");

152149153-

expect(

154-

provider.normalizeResolvedModel?.({

150+

const normalizedGptModel = provider.normalizeResolvedModel?.({

151+

provider: "openrouter",

152+

model: {

155153

provider: "openrouter",

156-

model: {

157-

provider: "openrouter",

158-

id: "openai/gpt-5.4",

159-

name: "openai/gpt-5.4",

160-

api: "openai-completions",

161-

baseUrl: "https://openrouter.ai/v1",

162-

reasoning: true,

163-

input: ["text", "image"],

164-

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

165-

contextWindow: 200_000,

166-

maxTokens: 8192,

167-

},

168-

} as never),

169-

).toMatchObject({

170-

baseUrl: "https://openrouter.ai/api/v1",

171-

});

154+

id: "openai/gpt-5.4",

155+

name: "openai/gpt-5.4",

156+

api: "openai-completions",

157+

baseUrl: "https://openrouter.ai/v1",

158+

reasoning: true,

159+

input: ["text", "image"],

160+

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

161+

contextWindow: 200_000,

162+

maxTokens: 8192,

163+

},

164+

} as never);

165+

expect(normalizedGptModel?.baseUrl).toBe("https://openrouter.ai/api/v1");

172166173-

expect(

174-

provider.normalizeResolvedModel?.({

167+

const normalizedHunterModel = provider.normalizeResolvedModel?.({

168+

provider: "openrouter",

169+

model: {

175170

provider: "openrouter",

176-

model: {

177-

provider: "openrouter",

178-

id: "openrouter/hunter-alpha",

179-

name: "Hunter Alpha",

180-

api: "openai-completions",

181-

baseUrl: "https://openrouter.ai/api/v1",

182-

reasoning: true,

183-

input: ["text"],

184-

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

185-

contextWindow: 1_048_576,

186-

maxTokens: 65_536,

187-

},

188-

} as never),

189-

).toMatchObject({

190-

reasoning: false,

191-

});

171+

id: "openrouter/hunter-alpha",

172+

name: "Hunter Alpha",

173+

api: "openai-completions",

174+

baseUrl: "https://openrouter.ai/api/v1",

175+

reasoning: true,

176+

input: ["text"],

177+

cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

178+

contextWindow: 1_048_576,

179+

maxTokens: 65_536,

180+

},

181+

} as never);

182+

expect(normalizedHunterModel?.reasoning).toBe(false);

192183193184

expect(

194185

provider.normalizeTransport?.({

@@ -235,13 +226,8 @@ describe("openrouter provider hooks", () => {

235226

expect(baseStreamFn).toHaveBeenCalledOnce();

236227

const firstCall = baseStreamFn.mock.calls[0];

237228

const firstModel = firstCall?.[0];

238-

expect(firstModel).toMatchObject({

239-

compat: {

240-

openRouterRouting: {

241-

order: ["moonshot"],

242-

},

243-

},

244-

});

229+

const compat = (firstModel as { compat?: { openRouterRouting?: { order?: unknown } } }).compat;

230+

expect(compat?.openRouterRouting?.order).toEqual(["moonshot"]);

245231

});

246232247233

it("does not inject OpenRouter reasoning for Hunter Alpha", async () => {

@@ -323,20 +309,18 @@ describe("openrouter provider hooks", () => {

323309

{},

324310

);

325311326-

expect(capturedPayload).toMatchObject({

327-

thinking: { type: "enabled" },

328-

reasoning_effort: "xhigh",

329-

messages: [

330-

{ role: "user", content: "read file" },

331-

{

332-

role: "assistant",

333-

tool_calls: [{ id: "call_1", type: "function" }],

334-

reasoning_content: "",

335-

},

336-

{ role: "tool", content: "ok" },

337-

{ role: "assistant", content: "done", reasoning_content: "" },

338-

],

339-

});

312+

expect(capturedPayload?.thinking).toEqual({ type: "enabled" });

313+

expect(capturedPayload?.reasoning_effort).toBe("xhigh");

314+

expect(capturedPayload?.messages).toEqual([

315+

{ role: "user", content: "read file" },

316+

{

317+

role: "assistant",

318+

tool_calls: [{ id: "call_1", type: "function" }],

319+

reasoning_content: "",

320+

},

321+

{ role: "tool", content: "ok" },

322+

{ role: "assistant", content: "done", reasoning_content: "" },

323+

]);

340324

expect(baseStreamFn).toHaveBeenCalledOnce();

341325

});

342326

@@ -486,10 +470,8 @@ describe("openrouter provider hooks", () => {

486470

{},

487471

);

488472489-

expect(capturedPayload).toMatchObject({

490-

messages: [{ role: "user", content: "Return JSON." }],

491-

reasoning: { effort: "high" },

492-

});

473+

expect(capturedPayload?.messages).toEqual([{ role: "user", content: "Return JSON." }]);

474+

expect(capturedPayload?.reasoning).toEqual({ effort: "high" });

493475

expect(baseStreamFn).toHaveBeenCalledOnce();

494476

});

495477

@@ -552,6 +534,6 @@ describe("openrouter provider hooks", () => {

552534

expect(payloads[0]?.messages).toHaveLength(2);

553535

expect(payloads[0]).not.toHaveProperty("reasoning");

554536

expect(payloads[1]?.messages).toHaveLength(2);

555-

expect(payloads[1]).toMatchObject({ reasoning: { effort: "high" } });

537+

expect(payloads[1]?.reasoning).toEqual({ effort: "high" });

556538

});

557539

});