fix: cover per-peer LINE cron recovery (#81704) · openclaw/openclaw@8338412
steipete
·
2026-05-16
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -15,6 +15,7 @@ Docs: https://docs.openclaw.ai
|
15 | 15 | - Agents: strip Gemini/Gemma `<final>` tags with attributes or self-closing syntax from delivered replies, including strict final-tag streaming enforcement. Fixes #65867. |
16 | 16 | - macOS/update: disarm legacy `ai.openclaw.update.*` LaunchAgents when `openclaw update` starts from one, preventing KeepAlive relaunch loops that repeatedly restart the Gateway and replay update continuations. Fixes #82167. |
17 | 17 | - LINE: acknowledge signed webhook events before agent processing so slow model replies do not cause LINE `request_timeout` delivery failures. Fixes #65375. Thanks @myericho. |
| 18 | +- LINE: stop cron recovery from inferring lowercased LINE recipients from canonical session keys, so long-running task replies do not silently retry undeliverable push targets. Fixes #81628. (#81704) Thanks @edenfunf. |
18 | 19 | - TTS: preserve channel-derived voice-note delivery for `/tts audio` replies even when the provider output is not natively voice-compatible. (#82174) Thanks @xuruiray. |
19 | 20 | - Codex/Lossless: keep Codex explicit compaction on native app-server threads while allowing Lossless through the context-engine slot; `openclaw doctor --fix` now migrates legacy `compaction.provider: "lossless-claw"` config to `plugins.slots.contextEngine`. |
20 | 21 | - Cron/doctor: report scheduled jobs with explicit `payload.model` overrides, including provider namespace counts and default-model mismatches, so stale cron model pins are visible during auth or billing investigations. Fixes #82151. Thanks @mgonto. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -859,9 +859,7 @@ describe("cron tool", () => {
|
859 | 859 | dmScope: "per-account-channel-peer", |
860 | 860 | peerId: "Uabcdef0123456789abcdef0123456789", |
861 | 861 | }); |
862 | | -expect(sessionKey).toBe( |
863 | | -"agent:main:line:primary:direct:uabcdef0123456789abcdef0123456789", |
864 | | -); |
| 862 | +expect(sessionKey).toBe("agent:main:line:primary:direct:uabcdef0123456789abcdef0123456789"); |
865 | 863 | |
866 | 864 | const delivery = await executeAddAndReadDelivery({ |
867 | 865 | callId: "call-line-direct-no-context-81628", |
@@ -871,6 +869,24 @@ describe("cron tool", () => {
|
871 | 869 | expect(delivery?.to).toBeUndefined(); |
872 | 870 | }); |
873 | 871 | |
| 872 | +it("does not surface lowercased LINE DM recipients with per-peer scope (#81628)", async () => { |
| 873 | +const sessionKey = buildAgentPeerSessionKey({ |
| 874 | +agentId: "main", |
| 875 | +channel: "line", |
| 876 | +peerKind: "direct", |
| 877 | +dmScope: "per-peer", |
| 878 | +peerId: "Uabcdef0123456789abcdef0123456789", |
| 879 | +}); |
| 880 | +expect(sessionKey).toBe("agent:main:direct:uabcdef0123456789abcdef0123456789"); |
| 881 | + |
| 882 | +const delivery = await executeAddAndReadDelivery({ |
| 883 | +callId: "call-line-per-peer-no-context-81628", |
| 884 | +agentSessionKey: sessionKey, |
| 885 | +}); |
| 886 | + |
| 887 | +expect(delivery?.to).toBeUndefined(); |
| 888 | +}); |
| 889 | + |
874 | 890 | it("does not let current delivery context override explicit delivery targets", async () => { |
875 | 891 | expect( |
876 | 892 | await executeAddAndReadDelivery({ |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -575,6 +575,7 @@ function inferDeliveryFromSessionKey(agentSessionKey?: string): CronDelivery | n
|
575 | 575 | if (!peerId) { |
576 | 576 | return null; |
577 | 577 | } |
| 578 | +const marker = parts[markerIndex]; |
578 | 579 | |
579 | 580 | let channel: CronMessageChannel | undefined; |
580 | 581 | if (markerIndex >= 1) { |
@@ -587,11 +588,12 @@ function inferDeliveryFromSessionKey(agentSessionKey?: string): CronDelivery | n
|
587 | 588 | // HTTP 400, so refuse the fallback for LINE and let the caller surface the |
588 | 589 | // missing target instead of silently scheduling an undeliverable job. |
589 | 590 | // openclaw/openclaw#81628 |
590 | | -if (channel === "line") { |
| 591 | +const isChannellessLineDirectId = |
| 592 | +!channel && (marker === "direct" || marker === "dm") && /^[ucr][a-f0-9]{32}$/.test(peerId); |
| 593 | +if (channel === "line" || isChannellessLineDirectId) { |
591 | 594 | return null; |
592 | 595 | } |
593 | 596 | |
594 | | -const marker = parts[markerIndex]; |
595 | 597 | const delivery: CronDelivery = { mode: "announce", to: peerId }; |
596 | 598 | if (channel) { |
597 | 599 | delivery.channel = channel; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。