docs: document session helper APIs

This commit is contained in:
Peter Steinberger
2026-06-03 21:37:49 -04:00
parent 604597d825
commit d0bf656a3f
8 changed files with 28 additions and 0 deletions

View File

@@ -7,10 +7,12 @@ import type { SessionScope } from "./types.js";
const FALLBACK_DEFAULT_AGENT_ID = "main";
/** Builds the canonical main session key for an agent. */
function buildMainSessionKey(agentId: string, mainKey?: string): string {
return `agent:${normalizeAgentId(agentId)}:${normalizeMainKey(mainKey)}`;
}
/** Resolves the configured main session key, honoring global session scope. */
export function resolveMainSessionKey(cfg?: {
session?: { scope?: SessionScope; mainKey?: string };
agents?: { list?: Array<{ id?: string; default?: boolean }> };
@@ -26,6 +28,7 @@ export function resolveMainSessionKey(cfg?: {
export { resolveAgentIdFromSessionKey };
/** Resolves the main session key for one explicit agent. */
export function resolveAgentMainSessionKey(params: {
cfg?: { session?: { mainKey?: string } };
agentId: string;
@@ -33,6 +36,7 @@ export function resolveAgentMainSessionKey(params: {
return buildMainSessionKey(params.agentId, params.cfg?.session?.mainKey);
}
/** Resolves an explicit agent id to its canonical main session key. */
export function resolveExplicitAgentSessionKey(params: {
cfg?: { session?: { scope?: SessionScope; mainKey?: string } };
agentId?: string | null;
@@ -44,6 +48,7 @@ export function resolveExplicitAgentSessionKey(params: {
return resolveAgentMainSessionKey({ cfg: params.cfg, agentId });
}
/** Canonicalizes main-session aliases to the current scoped session key. */
export function canonicalizeMainSessionAlias(params: {
cfg?: { session?: { scope?: SessionScope; mainKey?: string } };
agentId: string;

View File

@@ -1,9 +1,11 @@
import { normalizeStoreSessionKey } from "./store-entry.js";
/** Provider hook for session keys that maintenance/pruning should preserve. */
export type SessionMaintenancePreserveKeysProvider = () => Iterable<string> | undefined;
const preserveKeysProviders = new Set<SessionMaintenancePreserveKeysProvider>();
/** Registers a provider for session maintenance preserve keys. */
export function registerSessionMaintenancePreserveKeysProvider(
provider: SessionMaintenancePreserveKeysProvider,
): () => void {
@@ -32,6 +34,7 @@ function addSessionMaintenancePreserveKeys(
}
}
/** Collects normalized session keys that maintenance/pruning must preserve. */
export function collectSessionMaintenancePreserveKeys(
baseKeys?: Iterable<string | undefined>,
): Set<string> | undefined {

View File

@@ -1,5 +1,6 @@
import type { SessionEntry } from "./types.js";
/** Applies best-effort in-place migrations for legacy session store entry fields. */
export function applySessionStoreMigrations(store: Record<string, SessionEntry>): boolean {
let changed = false;
// Best-effort migration: message provider → channel naming.

View File

@@ -12,12 +12,14 @@ import { resolveStateDir } from "../paths.js";
import type { OpenClawConfig } from "../types.openclaw.js";
import { resolveAgentsDirFromSessionStorePath, resolveStorePath } from "./paths.js";
/** CLI/session-store target selection options. */
export type SessionStoreSelectionOptions = {
store?: string;
agent?: string;
allAgents?: boolean;
};
/** One session store path paired with its owning agent id. */
export type SessionStoreTarget = {
agentId: string;
storePath: string;
@@ -60,6 +62,7 @@ function shouldSkipDiscoveredAgentDirName(dirName: string, agentId: string): boo
);
}
/** Lists agent ids whose session stores should be considered configured. */
export function listConfiguredSessionStoreAgentIds(cfg: OpenClawConfig): string[] {
const ids = new Set(listAgentIds(cfg).map((agentId) => normalizeAgentId(agentId)));
const addAcpAgentId = (agentId: string | undefined) => {
@@ -167,6 +170,7 @@ function toDiscoveredSessionStoreTarget(
};
}
/** Resolves all configured and discoverable agent session stores synchronously. */
export function resolveAllAgentSessionStoreTargetsSync(
cfg: OpenClawConfig,
params: { env?: NodeJS.ProcessEnv } = {},
@@ -233,6 +237,7 @@ export function resolveAllAgentSessionStoreTargetsSync(
return dedupeTargetsByStorePath([...validatedConfiguredTargets, ...discoveredTargets]);
}
/** Resolves session store targets for one agent, including retired/manual stores. */
export function resolveAgentSessionStoreTargetsSync(
cfg: OpenClawConfig,
agentId: string,
@@ -318,6 +323,7 @@ export function resolveAgentSessionStoreTargetsSync(
return dedupeTargetsByStorePath(targets);
}
/** Resolves all configured and discoverable agent session stores asynchronously. */
export async function resolveAllAgentSessionStoreTargets(
cfg: OpenClawConfig,
params: { env?: NodeJS.ProcessEnv } = {},
@@ -401,6 +407,7 @@ export async function resolveAllAgentSessionStoreTargets(
return dedupeTargetsByStorePath([...validatedConfiguredTargets, ...discoveredTargets]);
}
/** Resolves session store targets from explicit CLI-style selection options. */
export function resolveSessionStoreTargets(
cfg: OpenClawConfig,
opts: SessionStoreSelectionOptions,

View File

@@ -1,6 +1,7 @@
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import type { SessionEntry } from "../config/sessions.js";
/** User or automatic model/provider override selection for a session entry. */
export type ModelOverrideSelection = {
provider: string;
model: string;
@@ -20,6 +21,7 @@ function clearFallbackOrigin(entry: SessionEntry): boolean {
return updated;
}
/** Applies a model/auth-profile override to a session entry and clears stale runtime fields. */
export function applyModelOverrideToSessionEntry(params: {
entry: SessionEntry;
selection: ModelOverrideSelection;
@@ -158,6 +160,7 @@ function wrappedOverrideModel(provider: string, model: string): string {
return `${provider}/${model}`;
}
/** Repairs overrides where legacy provider/model fields were stored as provider/model strings. */
export function repairProviderWrappedModelOverride(params: {
entry: SessionEntry;
defaultProvider: string;

View File

@@ -7,8 +7,10 @@ import type { SessionChatType, SessionEntry } from "../config/sessions.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { deriveSessionChatType } from "./session-chat-type.js";
/** Session send-policy decision after config and per-session overrides are evaluated. */
export type SessionSendPolicyDecision = "allow" | "deny";
/** Normalizes raw send-policy text into a decision. */
export function normalizeSendPolicy(raw?: string | null): SessionSendPolicyDecision | undefined {
const value = normalizeOptionalLowercaseString(raw);
if (value === "allow") {
@@ -71,6 +73,7 @@ function deriveChatTypeFromKey(key?: string): SessionChatType | undefined {
return undefined;
}
/** Resolves whether a session send is allowed by entry override and config rules. */
export function resolveSendPolicy(params: {
cfg: OpenClawConfig;
entry?: SessionEntry;

View File

@@ -1,3 +1,4 @@
/** Session lifecycle event broadcast to observers when a session is created or linked. */
export type SessionLifecycleEvent = {
sessionKey: string;
reason: string;
@@ -10,6 +11,7 @@ type SessionLifecycleListener = (event: SessionLifecycleEvent) => void;
const SESSION_LIFECYCLE_LISTENERS = new Set<SessionLifecycleListener>();
/** Registers a session lifecycle listener. */
export function onSessionLifecycleEvent(listener: SessionLifecycleListener): () => void {
SESSION_LIFECYCLE_LISTENERS.add(listener);
return () => {
@@ -17,6 +19,7 @@ export function onSessionLifecycleEvent(listener: SessionLifecycleListener): ()
};
}
/** Emits a best-effort session lifecycle event to all listeners. */
export function emitSessionLifecycleEvent(event: SessionLifecycleEvent): void {
for (const listener of SESSION_LIFECYCLE_LISTENERS) {
try {

View File

@@ -1,6 +1,7 @@
import { asPositiveSafeInteger } from "@openclaw/normalization-core/number-coercion";
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
/** Normalized transcript update emitted after a session transcript changes. */
export type SessionTranscriptUpdate = {
sessionFile: string;
sessionKey?: string;
@@ -14,6 +15,7 @@ type SessionTranscriptListener = (update: SessionTranscriptUpdate) => void;
const SESSION_TRANSCRIPT_LISTENERS = new Set<SessionTranscriptListener>();
/** Registers a listener for normalized session transcript updates. */
export function onSessionTranscriptUpdate(listener: SessionTranscriptListener): () => void {
SESSION_TRANSCRIPT_LISTENERS.add(listener);
return () => {
@@ -21,6 +23,7 @@ export function onSessionTranscriptUpdate(listener: SessionTranscriptListener):
};
}
/** Emits a normalized transcript update to all registered listeners. */
export function emitSessionTranscriptUpdate(update: string | SessionTranscriptUpdate): void {
const normalized =
typeof update === "string"