fix(active-memory): skip colon-containing channels from session store (#77396)

QQ c2c agent IDs such as `c2c:10D4F7C2...` were stored as the session
channel. When the recall subagent resolved this as a runnable channel the
colon reached `normalizeBundledPluginDirName` which rejects names containing
`:`, crashing the recall run. Apply the same guard already used for explicit
`channelId` params (#76704) to store-derived channels.
This commit is contained in:
HCL
2026-05-05 00:13:20 +08:00
committed by clawsweeper
parent fc7e2a10c8
commit c8e58583c0
2 changed files with 10 additions and 1 deletions

View File

@@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai
### Changes
- Plugins/active-memory: skip session-store channel entries that contain `:` when resolving the recall subagent's channel, so QQ c2c agent IDs (e.g. `c2c:10D4F7C2…`) and other scoped conversation IDs do not reach bundled-plugin `dirName` validation and crash the recall run. The same guard already applied to explicit `channelId` params (#76704); this extends it to store-derived channels. (#77396)
- Models/auth: add `openclaw models auth list [--provider <id>] [--json]` so users can inspect saved per-agent auth profiles without dumping secrets or hitting the old “too many arguments” path. Thanks @vincentkoc.
- Control UI/header: show the active agent name in dashboard breadcrumbs without adding the current session key, keeping non-chat views oriented without crowding the topbar.
- Control UI/cron: make the New Job sidebar collapsible so the jobs list can reclaim space while keeping the form one click away. Thanks @BunsDev.

View File

@@ -560,9 +560,17 @@ function resolveRecallRunChannelContext(params: {
store,
sessionKey: resolvedSessionKey,
}).existing;
const strongEntryChannel =
const rawStrongEntryChannel =
normalizeOptionalString(sessionEntry?.lastChannel) ??
normalizeOptionalString(sessionEntry?.channel);
// Channel IDs containing ":" are scoped conversation IDs (e.g. QQ c2c
// "c2c:10D4F7C2..."), not runnable channel names. The same guard that
// applies to explicit channelId (#76704) must also apply to channels
// read from the session store (#77396).
const strongEntryChannel =
rawStrongEntryChannel && !rawStrongEntryChannel.includes(":")
? rawStrongEntryChannel
: undefined;
const weakEntryChannel = normalizeOptionalString(sessionEntry?.origin?.provider);
return resolveReturnValue({
resolvedChannel: strongEntryChannel ?? weakEntryChannel,