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

推荐订阅源

GbyAI
GbyAI
WordPress大学
WordPress大学
D
DataBreaches.Net
腾讯CDC
小众软件
小众软件
B
Blog RSS Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
The Blog of Author Tim Ferriss
MongoDB | Blog
MongoDB | Blog
U
Unit 42
Y
Y Combinator Blog
V
V2EX
I
InfoQ
D
Docker
量子位
N
Netflix TechBlog - Medium
Recent Announcements
Recent Announcements
A
About on SuperTechFans
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog
阮一峰的网络日志
阮一峰的网络日志
MyScale Blog
MyScale 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
fix(outbound): keep direct-only targets out of group sess...
scotthuang · 2026-06-19 · via Recent Commits to openclaw:main
Original file line numberDiff line numberDiff line change

@@ -467,6 +467,7 @@ describe("resolveDeliveryTarget", () => {

467467

id: "alpha",

468468

outbound: createStubOutbound("Alpha"),

469469

messaging: { targetPrefixes: ["alpha"] },

470+

capabilities: { chatTypes: ["group"] },

470471

}),

471472

directory: {

472473

listGroups: async () => [

@@ -503,6 +504,7 @@ describe("resolveDeliveryTarget", () => {

503504

id: "alpha",

504505

outbound: createStubOutbound("Alpha"),

505506

messaging: { targetPrefixes: ["alpha"] },

507+

capabilities: { chatTypes: ["group"] },

506508

}),

507509

directory: {

508510

listGroups: async () => {

Original file line numberDiff line numberDiff line change

@@ -498,6 +498,23 @@ describe("resolveOutboundSessionRoute", () => {

498498

chatType: "direct",

499499

},

500500

},

501+

{

502+

name: "uses resolved direct-only channel user targets to avoid phantom group sessions",

503+

target: "wxid_abc123@im.wechat",

504+

channel: "openclaw-weixin",

505+

resolvedTarget: {

506+

to: "wxid_abc123@im.wechat",

507+

kind: "user" as const,

508+

source: "normalized" as const,

509+

resolutionSource: "normalized" as const,

510+

},

511+

expected: {

512+

sessionKey: "agent:main:openclaw-weixin:direct:wxid_abc123@im.wechat",

513+

from: "openclaw-weixin:wxid_abc123@im.wechat",

514+

to: "user:wxid_abc123@im.wechat",

515+

chatType: "direct",

516+

},

517+

},

501518

])("$name", async ({ channel = "guildchat", target, threadId, resolvedTarget, expected }) => {

502519

const route = await resolveOutboundSessionRoute({

503520

cfg: perChannelPeerSessionCfg,

Original file line numberDiff line numberDiff line change

@@ -142,12 +142,18 @@ describe("resolveMessagingTarget (directory fallback)", () => {

142142

{ kind: "group", id: "replacement-id", name: "support" } satisfies ChannelDirectoryEntry,

143143

]);

144144

const firstPlugin = {

145-

...createChannelTestPluginBase({ id: "richchat" }),

145+

...createChannelTestPluginBase({

146+

id: "richchat",

147+

capabilities: { chatTypes: ["group"] },

148+

}),

146149

directory: { listGroups: firstListGroups },

147150

messaging: { targetResolver: {} },

148151

} satisfies ChannelPlugin;

149152

const replacementPlugin = {

150-

...createChannelTestPluginBase({ id: "richchat" }),

153+

...createChannelTestPluginBase({

154+

id: "richchat",

155+

capabilities: { chatTypes: ["group"] },

156+

}),

151157

directory: { listGroups: replacementListGroups },

152158

messaging: { targetResolver: {} },

153159

} satisfies ChannelPlugin;

@@ -218,6 +224,37 @@ describe("resolveMessagingTarget (directory fallback)", () => {

218224

expect(mocks.listGroupsLive).not.toHaveBeenCalled();

219225

});

220226
227+

it("defaults bare id-like targets to user for direct-only channel plugins", async () => {

228+

const directOnlyPlugin = {

229+

...createChannelTestPluginBase({

230+

id: "openclaw-weixin",

231+

capabilities: { chatTypes: ["direct"] },

232+

}),

233+

messaging: {

234+

targetResolver: {

235+

looksLikeId: (raw: string) => raw.endsWith("@im.wechat"),

236+

},

237+

},

238+

} satisfies ChannelPlugin;

239+
240+

const result = await expectOkResolution({

241+

cfg,

242+

channel: "openclaw-weixin",

243+

input: "wxid_abc123@im.wechat",

244+

plugin: directOnlyPlugin,

245+

});

246+
247+

expect(result.target).toEqual({

248+

to: "wxid_abc123@im.wechat",

249+

kind: "user",

250+

display: "wxid_abc123@im.wechat",

251+

source: "normalized",

252+

resolutionSource: "normalized",

253+

});

254+

expect(mocks.listGroups).not.toHaveBeenCalled();

255+

expect(mocks.listGroupsLive).not.toHaveBeenCalled();

256+

});

257+
221258

it("uses catalog plugin target grammar for unloaded numeric topic ids", async () => {

222259

mocks.getLoadedChannelPlugin.mockReturnValue(undefined);

223260

mocks.getChannelPlugin.mockReturnValue({

Original file line numberDiff line numberDiff line change

@@ -188,6 +188,11 @@ function detectTargetKind(

188188

return "group";

189189

}

190190
191+

const chatTypes = plugin?.capabilities?.chatTypes ?? [];

192+

if (chatTypes.length > 0 && chatTypes.every((chatType) => chatType === "direct")) {

193+

return "user";

194+

}

195+
191196

return "group";

192197

}

193198