diff --git a/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts b/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts index 95eac33e6ba..350df8eef0e 100644 --- a/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts +++ b/extensions/telegram/src/bot.create-telegram-bot.test-harness.ts @@ -12,6 +12,9 @@ type AnyMock = ReturnType; type AnyAsyncMock = ReturnType Promise>>; type GetRuntimeConfigFn = typeof import("openclaw/plugin-sdk/runtime-config-snapshot").getRuntimeConfig; +type GetSessionEntryFn = typeof import("openclaw/plugin-sdk/session-store-runtime").getSessionEntry; +type ListSessionEntriesFn = + typeof import("openclaw/plugin-sdk/session-store-runtime").listSessionEntries; type LoadSessionStoreFn = typeof import("openclaw/plugin-sdk/session-store-runtime").loadSessionStore; type ResolveStorePathFn = @@ -61,7 +64,9 @@ vi.mock("openclaw/plugin-sdk/web-media", () => ({ })); const { + getSessionEntryMock, getRuntimeConfig, + listSessionEntriesMock, loadSessionStoreMock, readSessionUpdatedAtMock, recordInboundSessionMock, @@ -69,7 +74,9 @@ const { sessionStoreEntries, } = vi.hoisted( (): { + getSessionEntryMock: MockFn; getRuntimeConfig: MockFn; + listSessionEntriesMock: MockFn; loadSessionStoreMock: MockFn; readSessionUpdatedAtMock: MockFn; recordInboundSessionMock: MockFn>; @@ -77,12 +84,23 @@ const { sessionStoreEntries: { value: SessionStore }; } => ({ getRuntimeConfig: vi.fn(() => ({})), - loadSessionStoreMock: vi.fn( - (_storePath, _opts) => sessionStoreEntries.value, - ), resolveStorePathMock: vi.fn( (storePath?: string) => storePath ?? sessionStorePath, ), + loadSessionStoreMock: vi.fn( + (_storePath, _opts) => sessionStoreEntries.value, + ), + getSessionEntryMock: vi.fn(({ storePath, sessionKey, agentId }) => { + const resolvedStorePath = storePath ?? resolveStorePathMock(undefined, { agentId }); + return loadSessionStoreMock(resolvedStorePath)[sessionKey]; + }), + listSessionEntriesMock: vi.fn(({ storePath, agentId } = {}) => { + const resolvedStorePath = storePath ?? resolveStorePathMock(undefined, { agentId }); + return Object.entries(loadSessionStoreMock(resolvedStorePath)).map(([sessionKey, entry]) => ({ + sessionKey, + entry, + })); + }), readSessionUpdatedAtMock: vi.fn(() => undefined), recordInboundSessionMock: vi.fn(async () => undefined), sessionStoreEntries: { value: {} as SessionStore }, @@ -444,6 +462,8 @@ export const telegramBotRuntimeForTest: TelegramBotRuntimeForTest = { }; export const telegramBotDepsForTest: TelegramBotDeps = { getRuntimeConfig, + getSessionEntry: getSessionEntryMock, + listSessionEntries: listSessionEntriesMock, loadSessionStore: loadSessionStoreMock as TelegramBotDeps["loadSessionStore"], resolveStorePath: resolveStorePathMock, readSessionUpdatedAt: readSessionUpdatedAtMock, @@ -564,6 +584,19 @@ beforeEach(() => { loadSessionStoreMock.mockImplementation(() => sessionStoreEntries.value); resolveStorePathMock.mockReset(); resolveStorePathMock.mockImplementation((storePath?: string) => storePath ?? sessionStorePath); + getSessionEntryMock.mockReset(); + getSessionEntryMock.mockImplementation(({ storePath, sessionKey, agentId }) => { + const resolvedStorePath = storePath ?? resolveStorePathMock(undefined, { agentId }); + return loadSessionStoreMock(resolvedStorePath)[sessionKey]; + }); + listSessionEntriesMock.mockReset(); + listSessionEntriesMock.mockImplementation(({ storePath, agentId } = {}) => { + const resolvedStorePath = storePath ?? resolveStorePathMock(undefined, { agentId }); + return Object.entries(loadSessionStoreMock(resolvedStorePath)).map(([sessionKey, entry]) => ({ + sessionKey, + entry, + })); + }); readSessionUpdatedAtMock.mockReset(); readSessionUpdatedAtMock.mockReturnValue(undefined); recordInboundSessionMock.mockReset(); diff --git a/extensions/telegram/src/bot.ts b/extensions/telegram/src/bot.ts index d2c570d69ba..db50e00848b 100644 --- a/extensions/telegram/src/bot.ts +++ b/extensions/telegram/src/bot.ts @@ -1,11 +1,10 @@ // Telegram plugin module implements bot behavior. -import { getSessionEntry, listSessionEntries } from "openclaw/plugin-sdk/session-store-runtime"; import { createTelegramBotCore, getTelegramSequentialKey, setTelegramBotRuntimeForTest, } from "./bot-core.js"; -import { defaultTelegramBotDeps, type TelegramBotDeps } from "./bot-deps.js"; +import { defaultTelegramBotDeps } from "./bot-deps.js"; import type { TelegramBotOptions } from "./bot.types.js"; export type { TelegramBotOptions } from "./bot.types.js"; @@ -17,39 +16,6 @@ export function createTelegramBot( ): ReturnType { return createTelegramBotCore({ ...opts, - telegramDeps: withTelegramSessionAccessorDeps(opts.telegramDeps ?? defaultTelegramBotDeps), + telegramDeps: opts.telegramDeps ?? defaultTelegramBotDeps, }); } - -function withTelegramSessionAccessorDeps(deps: TelegramBotDeps): TelegramBotDeps { - if (!deps.loadSessionStore) { - return { - ...deps, - getSessionEntry: deps.getSessionEntry ?? getSessionEntry, - listSessionEntries: deps.listSessionEntries ?? listSessionEntries, - }; - } - - const listInjectedEntries = ( - scope: Parameters>[0] = {}, - ) => { - const storePath = - scope.storePath ?? deps.resolveStorePath(undefined, { agentId: scope.agentId }); - return Object.entries(deps.loadSessionStore?.(storePath) ?? {}).map(([sessionKey, entry]) => ({ - sessionKey, - entry, - })); - }; - - return { - ...deps, - // Existing Telegram tests and custom deps inject loadSessionStore; expose - // the same data through the accessor seam consumed by migrated handlers. - getSessionEntry: - deps.getSessionEntry ?? - ((scope) => - listInjectedEntries(scope).find(({ sessionKey }) => sessionKey === scope.sessionKey) - ?.entry), - listSessionEntries: deps.listSessionEntries ?? listInjectedEntries, - }; -} diff --git a/scripts/check-session-accessor-boundary.mjs b/scripts/check-session-accessor-boundary.mjs index a034ce2de98..f81db2f2ff9 100644 --- a/scripts/check-session-accessor-boundary.mjs +++ b/scripts/check-session-accessor-boundary.mjs @@ -132,6 +132,7 @@ export const migratedBundledPluginSessionAccessorFiles = new Set([ "extensions/memory-core/src/dreaming-narrative.ts", "extensions/mattermost/src/mattermost/model-picker.ts", "extensions/telegram/src/bot-handlers.runtime.ts", + "extensions/telegram/src/bot.ts", ]); export const migratedSessionAccessorWriteFiles = new Set([ diff --git a/test/scripts/check-session-accessor-boundary.test.ts b/test/scripts/check-session-accessor-boundary.test.ts index 6b217b0079c..3442734c96e 100644 --- a/test/scripts/check-session-accessor-boundary.test.ts +++ b/test/scripts/check-session-accessor-boundary.test.ts @@ -86,6 +86,7 @@ describe("session accessor boundary guard", () => { "extensions/memory-core/src/dreaming-narrative.ts", "extensions/mattermost/src/mattermost/model-picker.ts", "extensions/telegram/src/bot-handlers.runtime.ts", + "extensions/telegram/src/bot.ts", ]), ); });