refactor(src): split oversized modules
This commit is contained in:
103
src/commands/agent/session.ts
Normal file
103
src/commands/agent/session.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import crypto from "node:crypto";
|
||||
|
||||
import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import {
|
||||
normalizeThinkLevel,
|
||||
normalizeVerboseLevel,
|
||||
type ThinkLevel,
|
||||
type VerboseLevel,
|
||||
} from "../../auto-reply/thinking.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import {
|
||||
DEFAULT_IDLE_MINUTES,
|
||||
loadSessionStore,
|
||||
resolveAgentIdFromSessionKey,
|
||||
resolveSessionKey,
|
||||
resolveStorePath,
|
||||
type SessionEntry,
|
||||
} from "../../config/sessions.js";
|
||||
import { normalizeMainKey } from "../../routing/session-key.js";
|
||||
|
||||
export type SessionResolution = {
|
||||
sessionId: string;
|
||||
sessionKey?: string;
|
||||
sessionEntry?: SessionEntry;
|
||||
sessionStore?: Record<string, SessionEntry>;
|
||||
storePath: string;
|
||||
isNewSession: boolean;
|
||||
persistedThinking?: ThinkLevel;
|
||||
persistedVerbose?: VerboseLevel;
|
||||
};
|
||||
|
||||
export function resolveSession(opts: {
|
||||
cfg: ClawdbotConfig;
|
||||
to?: string;
|
||||
sessionId?: string;
|
||||
sessionKey?: string;
|
||||
}): SessionResolution {
|
||||
const sessionCfg = opts.cfg.session;
|
||||
const scope = sessionCfg?.scope ?? "per-sender";
|
||||
const mainKey = normalizeMainKey(sessionCfg?.mainKey);
|
||||
const idleMinutes = Math.max(
|
||||
sessionCfg?.idleMinutes ?? DEFAULT_IDLE_MINUTES,
|
||||
1,
|
||||
);
|
||||
const idleMs = idleMinutes * 60_000;
|
||||
const explicitSessionKey = opts.sessionKey?.trim();
|
||||
const storeAgentId = resolveAgentIdFromSessionKey(explicitSessionKey);
|
||||
const storePath = resolveStorePath(sessionCfg?.store, {
|
||||
agentId: storeAgentId,
|
||||
});
|
||||
const sessionStore = loadSessionStore(storePath);
|
||||
const now = Date.now();
|
||||
|
||||
const ctx: MsgContext | undefined = opts.to?.trim()
|
||||
? { From: opts.to }
|
||||
: undefined;
|
||||
let sessionKey: string | undefined =
|
||||
explicitSessionKey ??
|
||||
(ctx ? resolveSessionKey(scope, ctx, mainKey) : undefined);
|
||||
let sessionEntry = sessionKey ? sessionStore[sessionKey] : undefined;
|
||||
|
||||
// If a session id was provided, prefer to re-use its entry (by id) even when no key was derived.
|
||||
if (
|
||||
!explicitSessionKey &&
|
||||
opts.sessionId &&
|
||||
(!sessionEntry || sessionEntry.sessionId !== opts.sessionId)
|
||||
) {
|
||||
const foundKey = Object.keys(sessionStore).find(
|
||||
(key) => sessionStore[key]?.sessionId === opts.sessionId,
|
||||
);
|
||||
if (foundKey) {
|
||||
sessionKey = sessionKey ?? foundKey;
|
||||
sessionEntry = sessionStore[foundKey];
|
||||
}
|
||||
}
|
||||
|
||||
const fresh = sessionEntry && sessionEntry.updatedAt >= now - idleMs;
|
||||
const sessionId =
|
||||
opts.sessionId?.trim() ||
|
||||
(fresh ? sessionEntry?.sessionId : undefined) ||
|
||||
crypto.randomUUID();
|
||||
const isNewSession = !fresh && !opts.sessionId;
|
||||
|
||||
const persistedThinking =
|
||||
fresh && sessionEntry?.thinkingLevel
|
||||
? normalizeThinkLevel(sessionEntry.thinkingLevel)
|
||||
: undefined;
|
||||
const persistedVerbose =
|
||||
fresh && sessionEntry?.verboseLevel
|
||||
? normalizeVerboseLevel(sessionEntry.verboseLevel)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
sessionId,
|
||||
sessionKey,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
storePath,
|
||||
isNewSession,
|
||||
persistedThinking,
|
||||
persistedVerbose,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user