fix(webchat): preserve session labels across /new resets (#23755)

Co-authored-by: ThunderStormer <16649514+ThunderStormer@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-02-22 21:05:36 +01:00
parent 8a83ca54a1
commit 19046e0cfc
3 changed files with 41 additions and 0 deletions

View File

@@ -40,6 +40,7 @@ Docs: https://docs.openclaw.ai
- Exec approvals/Forwarding: restore Discord text forwarding when component approvals are not configured, and carry request snapshots through resolve events so resolved notices still forward after cache misses/restarts. (#22988) Thanks @bubmiller.
- Security/Elevated: match `tools.elevated.allowFrom` against sender identities only (not recipient `ctx.To`), closing a recipient-token bypass for `/elevated` authorization. (#11022) Thanks @coygeek.
- Webchat/Sessions: preserve external session routing metadata when internal `chat.send` turns run under `webchat`, so explicit channel-keyed sessions (for example Telegram) no longer get rewritten to `webchat` and misroute follow-up delivery. (#23258) Thanks @binary64.
- Webchat/Sessions: preserve existing session `label` across `/new` and `/reset` rollovers so reset sessions remain discoverable in session history lists. (#23755) Thanks @ThunderStormer.
- Config/Memory: allow `"mistral"` in `agents.defaults.memorySearch.provider` and `agents.defaults.memorySearch.fallback` schema validation. (#14934) Thanks @ThomsenDrake.
- Security/Feishu: enforce ID-only allowlist matching for DM/group sender authorization, normalize Feishu ID prefixes during checks, and ignore mutable display names so display-name collisions cannot satisfy allowlist entries. This ships in the next npm release. Thanks @jiseoung for reporting.
- Security/Group policy: harden `channels.*.groups.*.toolsBySender` matching by requiring explicit sender-key types (`id:`, `e164:`, `username:`, `name:`), preventing cross-identifier collisions across mutable/display-name fields while keeping legacy untyped keys on a deprecated ID-only path. This ships in the next npm release. Thanks @jiseoung for reporting.

View File

@@ -996,6 +996,42 @@ describe("initSessionState preserves behavior overrides across /new and /reset",
expect(result.sessionEntry.reasoningLevel).toBe("low");
});
it("/new preserves session label from previous session", async () => {
const storePath = await createStorePath("openclaw-reset-label-");
const sessionKey = "agent:main:telegram:dm:user-label";
const existingSessionId = "existing-session-label";
await seedSessionStoreWithOverrides({
storePath,
sessionKey,
sessionId: existingSessionId,
overrides: { label: "telegram-priority" },
});
const cfg = {
session: { store: storePath, idleMinutes: 999 },
} as OpenClawConfig;
const result = await initSessionState({
ctx: {
Body: "/new",
RawBody: "/new",
CommandBody: "/new",
From: "user-label",
To: "bot",
ChatType: "direct",
SessionKey: sessionKey,
Provider: "telegram",
Surface: "telegram",
},
cfg,
commandAuthorized: true,
});
expect(result.isNewSession).toBe(true);
expect(result.resetTriggered).toBe(true);
expect(result.sessionEntry.label).toBe("telegram-priority");
});
it("/new in a new session does not preserve overrides", async () => {
const storePath = await createStorePath("openclaw-new-no-preserve-");
const sessionKey = "agent:main:telegram:dm:user3";

View File

@@ -168,6 +168,7 @@ export async function initSessionState(params: {
let persistedTtsAuto: TtsAutoMode | undefined;
let persistedModelOverride: string | undefined;
let persistedProviderOverride: string | undefined;
let persistedLabel: string | undefined;
const normalizedChatType = normalizeChatType(ctx.ChatType);
const isGroup =
@@ -265,6 +266,7 @@ export async function initSessionState(params: {
persistedTtsAuto = entry.ttsAuto;
persistedModelOverride = entry.modelOverride;
persistedProviderOverride = entry.providerOverride;
persistedLabel = entry.label;
} else {
sessionId = crypto.randomUUID();
isNewSession = true;
@@ -280,6 +282,7 @@ export async function initSessionState(params: {
persistedTtsAuto = entry.ttsAuto;
persistedModelOverride = entry.modelOverride;
persistedProviderOverride = entry.providerOverride;
persistedLabel = entry.label;
}
}
@@ -339,6 +342,7 @@ export async function initSessionState(params: {
responseUsage: baseEntry?.responseUsage,
modelOverride: persistedModelOverride ?? baseEntry?.modelOverride,
providerOverride: persistedProviderOverride ?? baseEntry?.providerOverride,
label: persistedLabel ?? baseEntry?.label,
sendPolicy: baseEntry?.sendPolicy,
queueMode: baseEntry?.queueMode,
queueDebounceMs: baseEntry?.queueDebounceMs,