From 66db6c749dd8b28145191869e998e702686bb5ae Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 10 Jan 2026 05:23:29 +0100 Subject: [PATCH] fix: persist elevated off override --- src/auto-reply/reply.directive.test.ts | 11 ++++++++++- src/auto-reply/reply/directive-handling.ts | 12 +++++------- src/gateway/sessions-patch.ts | 4 ++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/auto-reply/reply.directive.test.ts b/src/auto-reply/reply.directive.test.ts index 28ff47486..4cbcd2b32 100644 --- a/src/auto-reply/reply.directive.test.ts +++ b/src/auto-reply/reply.directive.test.ts @@ -811,6 +811,7 @@ describe("directive behavior", () => { it("returns status alongside directive-only acks", async () => { await withTempHome(async (home) => { vi.mocked(runEmbeddedPiAgent).mockReset(); + const storePath = path.join(home, "sessions.json"); const res = await getReplyFromConfig( { @@ -834,13 +835,21 @@ describe("directive behavior", () => { }, }, whatsapp: { allowFrom: ["+1222"] }, - session: { store: path.join(home, "sessions.json") }, + session: { store: storePath }, }, ); const text = Array.isArray(res) ? res[0]?.text : res?.text; expect(text).toContain("Elevated mode disabled."); expect(text).toContain("Session: agent:main:main"); + const optionsLine = text + ?.split("\n") + .find((line) => line.trim().startsWith("⚙️")); + expect(optionsLine).toBeTruthy(); + expect(optionsLine).not.toContain("elevated"); + + const store = loadSessionStore(storePath); + expect(store["agent:main:main"]?.elevatedLevel).toBe("off"); expect(runEmbeddedPiAgent).not.toHaveBeenCalled(); }); }); diff --git a/src/auto-reply/reply/directive-handling.ts b/src/auto-reply/reply/directive-handling.ts index 37f7e6698..bbc8a4f2d 100644 --- a/src/auto-reply/reply/directive-handling.ts +++ b/src/auto-reply/reply/directive-handling.ts @@ -866,8 +866,9 @@ export async function handleDirectiveOnly(params: { else sessionEntry.reasoningLevel = directives.reasoningLevel; } if (directives.hasElevatedDirective && directives.elevatedLevel) { - if (directives.elevatedLevel === "off") delete sessionEntry.elevatedLevel; - else sessionEntry.elevatedLevel = directives.elevatedLevel; + // Unlike other toggles, elevated defaults can be "on". + // Persist "off" explicitly so `/elevated off` actually overrides defaults. + sessionEntry.elevatedLevel = directives.elevatedLevel; } if (modelSelection) { if (modelSelection.isDefault) { @@ -1049,11 +1050,8 @@ export async function persistInlineDirectives(params: { elevatedEnabled && elevatedAllowed ) { - if (directives.elevatedLevel === "off") { - delete sessionEntry.elevatedLevel; - } else { - sessionEntry.elevatedLevel = directives.elevatedLevel; - } + // Persist "off" explicitly so inline `/elevated off` overrides defaults. + sessionEntry.elevatedLevel = directives.elevatedLevel; updated = true; } const modelDirective = diff --git a/src/gateway/sessions-patch.ts b/src/gateway/sessions-patch.ts index 31421800a..397464c6a 100644 --- a/src/gateway/sessions-patch.ts +++ b/src/gateway/sessions-patch.ts @@ -144,8 +144,8 @@ export async function applySessionsPatchToStore(params: { } else if (raw !== undefined) { const normalized = normalizeElevatedLevel(String(raw)); if (!normalized) return invalid('invalid elevatedLevel (use "on"|"off")'); - if (normalized === "off") delete next.elevatedLevel; - else next.elevatedLevel = normalized; + // Persist "off" explicitly so patches can override defaults. + next.elevatedLevel = normalized; } }