Files
moltbot/src/config/types.base.ts
Peter Steinberger eb73e87f18 fix(session): prevent silent overflow on parent thread forks (#26912)
Lands #26912 from @markshields-tl with configurable session.parentForkMaxTokens and docs/tests/changelog updates.

Co-authored-by: Mark Shields <239231357+markshields-tl@users.noreply.github.com>
2026-02-25 23:54:02 +00:00

232 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { ChatType } from "../channels/chat-type.js";
export type ReplyMode = "text" | "command";
export type TypingMode = "never" | "instant" | "thinking" | "message";
export type SessionScope = "per-sender" | "global";
export type DmScope = "main" | "per-peer" | "per-channel-peer" | "per-account-channel-peer";
export type ReplyToMode = "off" | "first" | "all";
export type GroupPolicy = "open" | "disabled" | "allowlist";
export type DmPolicy = "pairing" | "allowlist" | "open" | "disabled";
export type OutboundRetryConfig = {
/** Max retry attempts for outbound requests (default: 3). */
attempts?: number;
/** Minimum retry delay in ms (default: 300-500ms depending on provider). */
minDelayMs?: number;
/** Maximum retry delay cap in ms (default: 30000). */
maxDelayMs?: number;
/** Jitter factor (0-1) applied to delays (default: 0.1). */
jitter?: number;
};
export type BlockStreamingCoalesceConfig = {
minChars?: number;
maxChars?: number;
idleMs?: number;
};
export type BlockStreamingChunkConfig = {
minChars?: number;
maxChars?: number;
breakPreference?: "paragraph" | "newline" | "sentence";
};
export type MarkdownTableMode = "off" | "bullets" | "code";
export type MarkdownConfig = {
/** Table rendering mode (off|bullets|code). */
tables?: MarkdownTableMode;
};
export type HumanDelayConfig = {
/** Delay style for block replies (off|natural|custom). */
mode?: "off" | "natural" | "custom";
/** Minimum delay in milliseconds (default: 800). */
minMs?: number;
/** Maximum delay in milliseconds (default: 2500). */
maxMs?: number;
};
export type SessionSendPolicyAction = "allow" | "deny";
export type SessionSendPolicyMatch = {
channel?: string;
chatType?: ChatType;
/**
* Session key prefix match.
* Note: some consumers match against a normalized key (for example, stripping `agent:<id>:`).
*/
keyPrefix?: string;
/** Optional raw session-key prefix match for consumers that normalize session keys. */
rawKeyPrefix?: string;
};
export type SessionSendPolicyRule = {
action: SessionSendPolicyAction;
match?: SessionSendPolicyMatch;
};
export type SessionSendPolicyConfig = {
default?: SessionSendPolicyAction;
rules?: SessionSendPolicyRule[];
};
export type SessionResetMode = "daily" | "idle";
export type SessionResetConfig = {
mode?: SessionResetMode;
/** Local hour (0-23) for the daily reset boundary. */
atHour?: number;
/** Sliding idle window (minutes). When set with daily mode, whichever expires first wins. */
idleMinutes?: number;
};
export type SessionResetByTypeConfig = {
direct?: SessionResetConfig;
/** @deprecated Use `direct` instead. Kept for backward compatibility. */
dm?: SessionResetConfig;
group?: SessionResetConfig;
thread?: SessionResetConfig;
};
export type SessionThreadBindingsConfig = {
/**
* Master switch for thread-bound session routing features.
* Channel/provider keys can override this default.
*/
enabled?: boolean;
/**
* Auto-unfocus TTL for thread-bound sessions (hours).
* Set to 0 to disable. Default: 24.
*/
ttlHours?: number;
};
export type SessionConfig = {
scope?: SessionScope;
/** DM session scoping (default: "main"). */
dmScope?: DmScope;
/** Map platform-prefixed identities (e.g. "telegram:123") to canonical DM peers. */
identityLinks?: Record<string, string[]>;
resetTriggers?: string[];
idleMinutes?: number;
reset?: SessionResetConfig;
resetByType?: SessionResetByTypeConfig;
/** Channel-specific reset overrides (e.g. { discord: { mode: "idle", idleMinutes: 10080 } }). */
resetByChannel?: Record<string, SessionResetConfig>;
store?: string;
typingIntervalSeconds?: number;
typingMode?: TypingMode;
/**
* Max parent transcript token count allowed for thread/session forking.
* If parent totalTokens is above this value, OpenClaw skips parent fork and
* starts a fresh thread session instead. Set to 0 to disable this guard.
*/
parentForkMaxTokens?: number;
mainKey?: string;
sendPolicy?: SessionSendPolicyConfig;
agentToAgent?: {
/** Max ping-pong turns between requester/target (05). Default: 5. */
maxPingPongTurns?: number;
};
/** Shared defaults for thread-bound session routing across channels/providers. */
threadBindings?: SessionThreadBindingsConfig;
/** Automatic session store maintenance (pruning, capping, file rotation). */
maintenance?: SessionMaintenanceConfig;
};
export type SessionMaintenanceMode = "enforce" | "warn";
export type SessionMaintenanceConfig = {
/** Whether to enforce maintenance or warn only. Default: "warn". */
mode?: SessionMaintenanceMode;
/** Remove session entries older than this duration (e.g. "30d", "12h"). Default: "30d". */
pruneAfter?: string | number;
/** Deprecated. Use pruneAfter instead. */
pruneDays?: number;
/** Maximum number of session entries to keep. Default: 500. */
maxEntries?: number;
/** Rotate sessions.json when it exceeds this size (e.g. "10mb"). Default: 10mb. */
rotateBytes?: number | string;
/**
* Retention for archived reset transcripts (`*.reset.<timestamp>`).
* Set `false` to disable reset-archive cleanup. Default: same as `pruneAfter` (30d).
*/
resetArchiveRetention?: string | number | false;
/**
* Optional per-agent sessions-directory disk budget (e.g. "500mb").
* When exceeded, warn (mode=warn) or enforce oldest-first cleanup (mode=enforce).
*/
maxDiskBytes?: number | string;
/**
* Target size after disk-budget cleanup (high-water mark), e.g. "400mb".
* Default: 80% of maxDiskBytes.
*/
highWaterBytes?: number | string;
};
export type LoggingConfig = {
level?: "silent" | "fatal" | "error" | "warn" | "info" | "debug" | "trace";
file?: string;
/** Maximum size of a single log file in bytes before writes are suppressed. Default: 500 MB. */
maxFileBytes?: number;
consoleLevel?: "silent" | "fatal" | "error" | "warn" | "info" | "debug" | "trace";
consoleStyle?: "pretty" | "compact" | "json";
/** Redact sensitive tokens in tool summaries. Default: "tools". */
redactSensitive?: "off" | "tools";
/** Regex patterns used to redact sensitive tokens (defaults apply when unset). */
redactPatterns?: string[];
};
export type DiagnosticsOtelConfig = {
enabled?: boolean;
endpoint?: string;
protocol?: "http/protobuf" | "grpc";
headers?: Record<string, string>;
serviceName?: string;
traces?: boolean;
metrics?: boolean;
logs?: boolean;
/** Trace sample rate (0.0 - 1.0). */
sampleRate?: number;
/** Metric export interval (ms). */
flushIntervalMs?: number;
};
export type DiagnosticsCacheTraceConfig = {
enabled?: boolean;
filePath?: string;
includeMessages?: boolean;
includePrompt?: boolean;
includeSystem?: boolean;
};
export type DiagnosticsConfig = {
enabled?: boolean;
/** Optional ad-hoc diagnostics flags (e.g. "telegram.http"). */
flags?: string[];
otel?: DiagnosticsOtelConfig;
cacheTrace?: DiagnosticsCacheTraceConfig;
};
export type WebReconnectConfig = {
initialMs?: number;
maxMs?: number;
factor?: number;
jitter?: number;
maxAttempts?: number; // 0 = unlimited
};
export type WebConfig = {
/** If false, do not start the WhatsApp web provider. Default: true. */
enabled?: boolean;
heartbeatSeconds?: number;
reconnect?: WebReconnectConfig;
};
// Provider docking: allowlists keyed by provider id (and internal "webchat").
export type AgentElevatedAllowFromConfig = Partial<Record<string, Array<string | number>>>;
export type IdentityConfig = {
name?: string;
theme?: string;
emoji?: string;
/** Avatar image: workspace-relative path, http(s) URL, or data URI. */
avatar?: string;
};