


























@@ -35,6 +35,7 @@ const DEFAULT_CACHE_TTL_MS = 15_000;
3535const DEFAULT_MAX_CACHE_ENTRIES = 1000;
3636const CACHE_SWEEP_INTERVAL_MS = 1000;
3737const DEFAULT_MIN_TIMEOUT_MS = 250;
38+const DEFAULT_SETUP_GRACE_TIMEOUT_MS = 30_000;
3839const DEFAULT_QUERY_MODE = "recent" as const;
3940const DEFAULT_QMD_SEARCH_MODE = "search" as const;
4041const DEFAULT_TRANSCRIPT_DIR = "active-memory";
@@ -216,6 +217,7 @@ type AsyncLock = <T>(task: () => Promise<T>) => Promise<T>;
216217const toggleStoreLocks = new Map<string, AsyncLock>();
217218let lastActiveRecallCacheSweepAt = 0;
218219let minimumTimeoutMs = DEFAULT_MIN_TIMEOUT_MS;
220+let setupGraceTimeoutMs = DEFAULT_SETUP_GRACE_TIMEOUT_MS;
219221220222function createAsyncLock(): AsyncLock {
221223let lock: Promise<void> = Promise.resolve();
@@ -2188,9 +2190,10 @@ async function maybeResolveActiveRecall(params: {
21882190const controller = new AbortController();
21892191const TIMEOUT_SENTINEL = Symbol("timeout");
21902192let sessionFile: string | undefined;
2193+const watchdogTimeoutMs = params.config.timeoutMs + setupGraceTimeoutMs;
21912194const timeoutId = setTimeout(() => {
2192-controller.abort(new Error(`active-memory timeout after ${params.config.timeoutMs}ms`));
2193-}, params.config.timeoutMs);
2195+controller.abort(new Error(`active-memory timeout after ${watchdogTimeoutMs}ms`));
2196+}, watchdogTimeoutMs);
21942197timeoutId.unref?.();
2195219821962199const timeoutPromise = new Promise<typeof TIMEOUT_SENTINEL>((resolve) => {
@@ -2428,109 +2431,114 @@ export default definePluginEntry({
24282431},
24292432});
243024332431-api.on("before_prompt_build", async (event, ctx) => {
2432-try {
2433-refreshLiveConfigFromRuntime();
2434-const resolvedAgentId = resolveStatusUpdateAgentId(ctx);
2435-const resolvedSessionKey =
2436-ctx.sessionKey?.trim() ||
2437-(resolvedAgentId
2438- ? resolveCanonicalSessionKeyFromSessionId({
2439- api,
2440-agentId: resolvedAgentId,
2441-sessionId: ctx.sessionId,
2442-})
2443- : undefined);
2444-const effectiveAgentId =
2445-resolvedAgentId || resolveStatusUpdateAgentId({ sessionKey: resolvedSessionKey });
2446-if (await isSessionActiveMemoryDisabled({ api, sessionKey: resolvedSessionKey })) {
2447-await persistPluginStatusLines({
2448- api,
2449-agentId: effectiveAgentId,
2450-sessionKey: resolvedSessionKey,
2451-});
2452-return undefined;
2453-}
2454-if (!isEnabledForAgent(config, effectiveAgentId)) {
2455-await persistPluginStatusLines({
2456- api,
2457-agentId: effectiveAgentId,
2458-sessionKey: resolvedSessionKey,
2459-});
2460-return undefined;
2461-}
2462-if (!isEligibleInteractiveSession(ctx)) {
2463-await persistPluginStatusLines({
2464- api,
2465-agentId: effectiveAgentId,
2466-sessionKey: resolvedSessionKey,
2434+const beforePromptBuildTimeoutMs = 120_000 + setupGraceTimeoutMs;
2435+api.on(
2436+"before_prompt_build",
2437+async (event, ctx) => {
2438+try {
2439+refreshLiveConfigFromRuntime();
2440+const resolvedAgentId = resolveStatusUpdateAgentId(ctx);
2441+const resolvedSessionKey =
2442+ctx.sessionKey?.trim() ||
2443+(resolvedAgentId
2444+ ? resolveCanonicalSessionKeyFromSessionId({
2445+ api,
2446+agentId: resolvedAgentId,
2447+sessionId: ctx.sessionId,
2448+})
2449+ : undefined);
2450+const effectiveAgentId =
2451+resolvedAgentId || resolveStatusUpdateAgentId({ sessionKey: resolvedSessionKey });
2452+if (await isSessionActiveMemoryDisabled({ api, sessionKey: resolvedSessionKey })) {
2453+await persistPluginStatusLines({
2454+ api,
2455+agentId: effectiveAgentId,
2456+sessionKey: resolvedSessionKey,
2457+});
2458+return undefined;
2459+}
2460+if (!isEnabledForAgent(config, effectiveAgentId)) {
2461+await persistPluginStatusLines({
2462+ api,
2463+agentId: effectiveAgentId,
2464+sessionKey: resolvedSessionKey,
2465+});
2466+return undefined;
2467+}
2468+if (!isEligibleInteractiveSession(ctx)) {
2469+await persistPluginStatusLines({
2470+ api,
2471+agentId: effectiveAgentId,
2472+sessionKey: resolvedSessionKey,
2473+});
2474+return undefined;
2475+}
2476+if (
2477+!isAllowedChatType(config, {
2478+ ...ctx,
2479+sessionKey: resolvedSessionKey ?? ctx.sessionKey,
2480+mainKey: api.config.session?.mainKey,
2481+})
2482+) {
2483+await persistPluginStatusLines({
2484+ api,
2485+agentId: effectiveAgentId,
2486+sessionKey: resolvedSessionKey,
2487+});
2488+return undefined;
2489+}
2490+if (
2491+!isAllowedChatId(config, {
2492+sessionKey: resolvedSessionKey ?? ctx.sessionKey,
2493+messageProvider: ctx.messageProvider,
2494+})
2495+) {
2496+await persistPluginStatusLines({
2497+ api,
2498+agentId: effectiveAgentId,
2499+sessionKey: resolvedSessionKey,
2500+});
2501+return undefined;
2502+}
2503+const query = buildQuery({
2504+latestUserMessage: event.prompt,
2505+recentTurns: extractRecentTurns(event.messages),
2506+ config,
24672507});
2468-return undefined;
2469-}
2470-if (
2471-!isAllowedChatType(config, {
2472- ...ctx,
2473-sessionKey: resolvedSessionKey ?? ctx.sessionKey,
2474-mainKey: api.config.session?.mainKey,
2475-})
2476-) {
2477-await persistPluginStatusLines({
2508+const result = await maybeResolveActiveRecall({
24782509 api,
2510+ config,
24792511agentId: effectiveAgentId,
24802512sessionKey: resolvedSessionKey,
2481-});
2482-return undefined;
2483-}
2484-if (
2485-!isAllowedChatId(config, {
2486-sessionKey: resolvedSessionKey ?? ctx.sessionKey,
2513+sessionId: ctx.sessionId,
24872514messageProvider: ctx.messageProvider,
2488-})
2489-) {
2490-await persistPluginStatusLines({
2491- api,
2492-agentId: effectiveAgentId,
2493-sessionKey: resolvedSessionKey,
2515+channelId: ctx.channelId,
2516+ query,
2517+currentModelProviderId: ctx.modelProviderId,
2518+currentModelId: ctx.modelId,
24942519});
2520+if (!result.summary) {
2521+return undefined;
2522+}
2523+const promptPrefix = buildPromptPrefix(result.summary);
2524+if (!promptPrefix) {
2525+return undefined;
2526+}
2527+return {
2528+prependContext: promptPrefix,
2529+};
2530+} catch (error) {
2531+const message = toSingleLineLogValue(
2532+error instanceof Error ? error.message : String(error),
2533+);
2534+api.logger.warn?.(
2535+`active-memory: before_prompt_build failed, skipping memory lookup: ${message}`,
2536+);
24952537return undefined;
24962538}
2497-const query = buildQuery({
2498-latestUserMessage: event.prompt,
2499-recentTurns: extractRecentTurns(event.messages),
2500- config,
2501-});
2502-const result = await maybeResolveActiveRecall({
2503- api,
2504- config,
2505-agentId: effectiveAgentId,
2506-sessionKey: resolvedSessionKey,
2507-sessionId: ctx.sessionId,
2508-messageProvider: ctx.messageProvider,
2509-channelId: ctx.channelId,
2510- query,
2511-currentModelProviderId: ctx.modelProviderId,
2512-currentModelId: ctx.modelId,
2513-});
2514-if (!result.summary) {
2515-return undefined;
2516-}
2517-const promptPrefix = buildPromptPrefix(result.summary);
2518-if (!promptPrefix) {
2519-return undefined;
2520-}
2521-return {
2522-prependContext: promptPrefix,
2523-};
2524-} catch (error) {
2525-const message = toSingleLineLogValue(
2526-error instanceof Error ? error.message : String(error),
2527-);
2528-api.logger.warn?.(
2529-`active-memory: before_prompt_build failed, skipping memory lookup: ${message}`,
2530-);
2531-return undefined;
2532-}
2533-});
2539+},
2540+{ timeoutMs: beforePromptBuildTimeoutMs },
2541+);
25342542},
25352543});
25362544@@ -2548,9 +2556,13 @@ export const __testing = {
25482556activeRecallCache.clear();
25492557lastActiveRecallCacheSweepAt = 0;
25502558minimumTimeoutMs = DEFAULT_MIN_TIMEOUT_MS;
2559+setupGraceTimeoutMs = DEFAULT_SETUP_GRACE_TIMEOUT_MS;
25512560},
25522561setMinimumTimeoutMsForTests(value: number) {
25532562minimumTimeoutMs = value;
25542563},
2564+setSetupGraceTimeoutMsForTests(value: number) {
2565+setupGraceTimeoutMs = Math.max(0, Math.floor(value));
2566+},
25552567 setCachedResult,
25562568};
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。