diff --git a/src/agents/openclaw-tools.session-status.test.ts b/src/agents/openclaw-tools.session-status.test.ts index aeca01ee603..2a6e5c08526 100644 --- a/src/agents/openclaw-tools.session-status.test.ts +++ b/src/agents/openclaw-tools.session-status.test.ts @@ -577,6 +577,29 @@ describe("session_status tool", () => { expect(details.sessionKey).toBe("agent:main:current"); }); + it("resolves sessionKey=current for a channel-plugin requester via implicit fallback", async () => { + resetSessionStore({}); + + const tool = getSessionStatusTool("agent:main:scope:scopy:direct:scopy"); + + const result = await tool.execute("call-current-channel-plugin", { sessionKey: "current" }); + const details = result.details as { ok?: boolean; sessionKey?: string; statusText?: string }; + expect(details.ok).toBe(true); + expect(details.sessionKey).toBe("agent:main:scope:scopy:direct:scopy"); + expect(details.statusText).toContain("OpenClaw"); + expect(details.statusText).toContain("🧠 Model:"); + }); + + it("does not synthesize a current fallback for unknown non-literal session keys", async () => { + resetSessionStore({}); + + const tool = getSessionStatusTool("agent:main:scope:scopy:direct:scopy"); + + await expect( + tool.execute("call-current-non-literal", { sessionKey: "definitely-not-current" }), + ).rejects.toThrow("Unknown sessionId: definitely-not-current"); + }); + it("includes background task context in session_status output", async () => { resetSessionStore({ "agent:main:main": { diff --git a/src/agents/tools/session-status-tool.ts b/src/agents/tools/session-status-tool.ts index d335750182e..0163b17a130 100644 --- a/src/agents/tools/session-status-tool.ts +++ b/src/agents/tools/session-status-tool.ts @@ -137,6 +137,27 @@ function resolveStoreScopedRequesterKey(params: { return parsed.rest === params.mainKey ? params.mainKey : params.requesterKey; } +function synthesizeImplicitCurrentSessionEntry(): SessionEntry { + return { + sessionId: "", + updatedAt: Date.now(), + }; +} + +function resolveImplicitCurrentSessionFallback(params: { + requestedKeyRaw: string; + storeScopedRequesterKey: string; +}): { key: string; entry: SessionEntry } | null { + const requesterKey = params.storeScopedRequesterKey.trim(); + if (params.requestedKeyRaw !== "current" || !requesterKey) { + return null; + } + return { + key: requesterKey, + entry: synthesizeImplicitCurrentSessionEntry(), + }; +} + function listImplicitDefaultDirectFallbackKeys(params: { keyRaw: string; mainKey: string; @@ -461,6 +482,17 @@ export function createSessionStatusTool(opts?: { } } + if (!resolved) { + const fallback = resolveImplicitCurrentSessionFallback({ + requestedKeyRaw, + storeScopedRequesterKey, + }); + if (fallback) { + resolved = fallback; + resolvedViaImplicitCurrentFallback = true; + } + } + if (!resolved) { const kind = shouldResolveSessionIdInput(requestedKeyRaw) ? "sessionId" : "sessionKey"; throw new Error(`Unknown ${kind}: ${requestedKeyRaw}`);