mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-20 13:13:06 +00:00
perf: skip bundled session fallback on hot paths
This commit is contained in:
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { clearSessionStoreCacheForTest } from "../../../src/config/sessions.js";
|
||||
import { clearSessionStoreCacheForTest } from "../../../src/config/sessions/store.js";
|
||||
import {
|
||||
createDiscordNativeApprovalAdapter,
|
||||
getDiscordApprovalCapability,
|
||||
|
||||
@@ -90,6 +90,7 @@ function createDiscordOriginTargetResolver(configOverride?: DiscordExecApprovalC
|
||||
const sessionConversation = resolveApprovalRequestSessionConversation({
|
||||
request,
|
||||
channel: "discord",
|
||||
bundledFallback: false,
|
||||
});
|
||||
const sessionKind = extractDiscordSessionKind(
|
||||
normalizeOptionalString(request.request.sessionKey) ?? null,
|
||||
@@ -113,6 +114,7 @@ function createDiscordOriginTargetResolver(configOverride?: DiscordExecApprovalC
|
||||
const sessionConversation = resolveApprovalRequestSessionConversation({
|
||||
request,
|
||||
channel: "discord",
|
||||
bundledFallback: false,
|
||||
});
|
||||
const sessionKind = extractDiscordSessionKind(request.request.sessionKey?.trim() || null);
|
||||
if (sessionKind === "dm") {
|
||||
@@ -134,6 +136,7 @@ function createDiscordOriginTargetResolver(configOverride?: DiscordExecApprovalC
|
||||
const sessionConversation = resolveApprovalRequestSessionConversation({
|
||||
request,
|
||||
channel: "discord",
|
||||
bundledFallback: false,
|
||||
});
|
||||
const sessionKind = extractDiscordSessionKind(request.request.sessionKey?.trim() || null);
|
||||
if (sessionKind === "dm") {
|
||||
|
||||
@@ -3,7 +3,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { clearSessionStoreCacheForTest } from "../../../src/config/sessions.js";
|
||||
import { clearSessionStoreCacheForTest } from "../../../src/config/sessions/store.js";
|
||||
import { slackApprovalCapability, slackNativeApprovalAdapter } from "./approval-native.js";
|
||||
|
||||
function buildConfig(
|
||||
|
||||
@@ -96,6 +96,7 @@ function resolveSlackFallbackOriginTarget(request: ApprovalRequest): SlackOrigin
|
||||
const sessionTarget = resolveApprovalRequestSessionConversation({
|
||||
request,
|
||||
channel: "slack",
|
||||
bundledFallback: false,
|
||||
});
|
||||
if (!sessionTarget) {
|
||||
return null;
|
||||
|
||||
@@ -3,7 +3,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { clearSessionStoreCacheForTest } from "../../../src/config/sessions.js";
|
||||
import { clearSessionStoreCacheForTest } from "../../../src/config/sessions/store.js";
|
||||
import { telegramApprovalCapability, telegramNativeApprovalAdapter } from "./approval-native.js";
|
||||
|
||||
function buildConfig(
|
||||
|
||||
@@ -125,7 +125,7 @@ function buildGenericParentOverrideCandidates(sessionKey: string | null | undefi
|
||||
return [];
|
||||
}
|
||||
const { baseSessionKey, threadId } = parseThreadSessionSuffix(raw.rawId);
|
||||
return buildChannelKeyCandidates(threadId ? baseSessionKey : undefined);
|
||||
return buildChannelKeyCandidates(threadId ? baseSessionKey : raw.rawId);
|
||||
}
|
||||
|
||||
function buildFeishuParentOverrideCandidates(rawId: string | undefined): string[] {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { clearRuntimeConfigSnapshot, setRuntimeConfigSnapshot } from "../../config/config.js";
|
||||
import { clearRuntimeConfigSnapshot, setRuntimeConfigSnapshot } from "../../config/io.js";
|
||||
import { resetPluginRuntimeStateForTest } from "../../plugins/runtime.js";
|
||||
|
||||
const fallbackState = vi.hoisted(() => ({
|
||||
@@ -27,7 +27,7 @@ vi.mock("../../plugin-sdk/facade-runtime.js", async () => {
|
||||
};
|
||||
});
|
||||
|
||||
import { resolveSessionConversationRef } from "./session-conversation.js";
|
||||
import { resolveSessionConversationRef, resolveSessionThreadInfo } from "./session-conversation.js";
|
||||
|
||||
describe("session conversation bundled fallback", () => {
|
||||
beforeEach(() => {
|
||||
@@ -73,6 +73,51 @@ describe("session conversation bundled fallback", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("can skip bundled fallback probing for hot generic-only callers", () => {
|
||||
fallbackState.activeDirName = "mock-threaded";
|
||||
fallbackState.resolveSessionConversation = ({ rawId }) => {
|
||||
const [conversationId, threadId] = rawId.split(":topic:");
|
||||
return {
|
||||
id: conversationId,
|
||||
threadId,
|
||||
baseConversationId: conversationId,
|
||||
parentConversationCandidates: [conversationId],
|
||||
};
|
||||
};
|
||||
setRuntimeConfigSnapshot({
|
||||
plugins: {
|
||||
entries: {
|
||||
"mock-threaded": {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
resolveSessionConversationRef("agent:main:mock-threaded:group:room:topic:42", {
|
||||
bundledFallback: false,
|
||||
}),
|
||||
).toEqual({
|
||||
channel: "mock-threaded",
|
||||
kind: "group",
|
||||
rawId: "room:topic:42",
|
||||
id: "room:topic:42",
|
||||
threadId: undefined,
|
||||
baseSessionKey: "agent:main:mock-threaded:group:room:topic:42",
|
||||
baseConversationId: "room:topic:42",
|
||||
parentConversationCandidates: [],
|
||||
});
|
||||
expect(
|
||||
resolveSessionThreadInfo("agent:main:mock-threaded:group:room:topic:42", {
|
||||
bundledFallback: false,
|
||||
}),
|
||||
).toEqual({
|
||||
baseSessionKey: "agent:main:mock-threaded:group:room:topic:42",
|
||||
threadId: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("uses explicit bundled parent candidates before registry bootstrap", () => {
|
||||
fallbackState.activeDirName = "mock-parent";
|
||||
fallbackState.resolveSessionConversation = ({ rawId }) => ({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { clearRuntimeConfigSnapshot } from "../../config/config.js";
|
||||
import { clearRuntimeConfigSnapshot, setRuntimeConfigSnapshot } from "../../config/io.js";
|
||||
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../../plugins/runtime.js";
|
||||
import { createTestRegistry } from "../../test-utils/channel-plugins.js";
|
||||
import { createSessionConversationTestRegistry } from "../../test-utils/session-conversation-registry.js";
|
||||
@@ -56,6 +56,15 @@ describe("session conversation routing", () => {
|
||||
|
||||
it("does not load bundled session-key fallbacks for inactive channel plugins", () => {
|
||||
resetPluginRuntimeStateForTest();
|
||||
setRuntimeConfigSnapshot({
|
||||
plugins: {
|
||||
entries: {
|
||||
telegram: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(resolveSessionConversationRef("agent:main:telegram:group:-100123:topic:77")).toEqual({
|
||||
channel: "telegram",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getRuntimeConfigSnapshot } from "../../config/runtime-snapshot.js";
|
||||
import { tryLoadActivatedBundledPluginPublicSurfaceModuleSync } from "../../plugin-sdk/facade-runtime.js";
|
||||
import {
|
||||
parseRawSessionConversationRef,
|
||||
@@ -49,6 +50,9 @@ type BundledSessionKeyModule = {
|
||||
};
|
||||
|
||||
const SESSION_KEY_API_ARTIFACT_BASENAME = "session-key-api.js";
|
||||
type SessionConversationResolutionOptions = {
|
||||
bundledFallback?: boolean;
|
||||
};
|
||||
|
||||
type NormalizedSessionConversationResolution = ResolvedSessionConversation & {
|
||||
hasExplicitParentConversationCandidates: boolean;
|
||||
@@ -140,6 +144,9 @@ function resolveBundledSessionConversationFallback(params: {
|
||||
kind: "group" | "channel";
|
||||
rawId: string;
|
||||
}): NormalizedSessionConversationResolution | null {
|
||||
if (isBundledSessionConversationFallbackDisabled(params.channel)) {
|
||||
return null;
|
||||
}
|
||||
const dirName = normalizeResolvedChannel(params.channel);
|
||||
let resolveSessionConversation: BundledSessionKeyModule["resolveSessionConversation"];
|
||||
try {
|
||||
@@ -163,10 +170,23 @@ function resolveBundledSessionConversationFallback(params: {
|
||||
);
|
||||
}
|
||||
|
||||
function isBundledSessionConversationFallbackDisabled(channel: string): boolean {
|
||||
const snapshot = getRuntimeConfigSnapshot();
|
||||
if (!snapshot?.plugins) {
|
||||
return false;
|
||||
}
|
||||
if (snapshot.plugins.enabled === false) {
|
||||
return true;
|
||||
}
|
||||
const entry = snapshot.plugins.entries?.[normalizeResolvedChannel(channel)];
|
||||
return !!entry && typeof entry === "object" && entry.enabled === false;
|
||||
}
|
||||
|
||||
function resolveSessionConversationResolution(params: {
|
||||
channel: string;
|
||||
kind: "group" | "channel";
|
||||
rawId: string;
|
||||
bundledFallback?: boolean;
|
||||
}): ResolvedSessionConversation | null {
|
||||
const rawId = params.rawId.trim();
|
||||
if (!rawId) {
|
||||
@@ -180,13 +200,16 @@ function resolveSessionConversationResolution(params: {
|
||||
rawId,
|
||||
}),
|
||||
);
|
||||
const shouldTryBundledFallback = params.bundledFallback !== false && !messaging;
|
||||
const resolved =
|
||||
pluginResolved ??
|
||||
resolveBundledSessionConversationFallback({
|
||||
channel: params.channel,
|
||||
kind: params.kind,
|
||||
rawId,
|
||||
}) ??
|
||||
(shouldTryBundledFallback
|
||||
? resolveBundledSessionConversationFallback({
|
||||
channel: params.channel,
|
||||
kind: params.kind,
|
||||
rawId,
|
||||
})
|
||||
: null) ??
|
||||
buildGenericConversationResolution(rawId);
|
||||
if (!resolved) {
|
||||
return null;
|
||||
@@ -214,6 +237,7 @@ export function resolveSessionConversation(params: {
|
||||
channel: string;
|
||||
kind: "group" | "channel";
|
||||
rawId: string;
|
||||
bundledFallback?: boolean;
|
||||
}): ResolvedSessionConversation | null {
|
||||
return resolveSessionConversationResolution(params);
|
||||
}
|
||||
@@ -224,13 +248,17 @@ function buildBaseSessionKey(raw: RawSessionConversationRef, id: string): string
|
||||
|
||||
export function resolveSessionConversationRef(
|
||||
sessionKey: string | undefined | null,
|
||||
opts: SessionConversationResolutionOptions = {},
|
||||
): ResolvedSessionConversationRef | null {
|
||||
const raw = parseRawSessionConversationRef(sessionKey);
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const resolved = resolveSessionConversation(raw);
|
||||
const resolved = resolveSessionConversation({
|
||||
...raw,
|
||||
bundledFallback: opts.bundledFallback,
|
||||
});
|
||||
if (!resolved) {
|
||||
return null;
|
||||
}
|
||||
@@ -249,8 +277,9 @@ export function resolveSessionConversationRef(
|
||||
|
||||
export function resolveSessionThreadInfo(
|
||||
sessionKey: string | undefined | null,
|
||||
opts: SessionConversationResolutionOptions = {},
|
||||
): ParsedThreadSessionSuffix {
|
||||
const resolved = resolveSessionConversationRef(sessionKey);
|
||||
const resolved = resolveSessionConversationRef(sessionKey, opts);
|
||||
if (!resolved) {
|
||||
return parseThreadSessionSuffix(sessionKey);
|
||||
}
|
||||
|
||||
@@ -10,3 +10,10 @@ export function parseSessionThreadInfo(sessionKey: string | undefined): {
|
||||
} {
|
||||
return resolveSessionThreadInfo(sessionKey);
|
||||
}
|
||||
|
||||
export function parseSessionThreadInfoFast(sessionKey: string | undefined): {
|
||||
baseSessionKey: string | undefined;
|
||||
threadId: string | undefined;
|
||||
} {
|
||||
return resolveSessionThreadInfo(sessionKey, { bundledFallback: false });
|
||||
}
|
||||
|
||||
@@ -87,12 +87,15 @@ function normalizeOptionalChannel(value?: string | null): string | undefined {
|
||||
export function resolveApprovalRequestSessionConversation(params: {
|
||||
request: ApprovalRequestLike;
|
||||
channel?: string | null;
|
||||
bundledFallback?: boolean;
|
||||
}): ApprovalRequestSessionConversation | null {
|
||||
const sessionKey = normalizeOptionalString(params.request.request.sessionKey);
|
||||
if (!sessionKey) {
|
||||
return null;
|
||||
}
|
||||
const resolved = resolveSessionConversationRef(sessionKey);
|
||||
const resolved = resolveSessionConversationRef(sessionKey, {
|
||||
bundledFallback: params.bundledFallback,
|
||||
});
|
||||
if (!resolved) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user