Files
openclaw/src/config/types.base.ts
Peter Steinberger 694ca50e97 Revert "refactor: move runtime state to SQLite"
This reverts commit f91de52f0d.
2026-05-13 13:33:38 +01:00

353 lines
12 KiB
TypeScript

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" | "batched";
export type GroupPolicy = "open" | "disabled" | "allowlist";
export type DmPolicy = "pairing" | "allowlist" | "open" | "disabled";
export type ContextVisibilityMode = "all" | "allowlist" | "allowlist_quote";
export type TextChunkMode = "length" | "newline";
export type StreamingMode = "off" | "partial" | "block" | "progress";
export type ChannelStreamingCommandTextMode = "raw" | "status";
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 ChannelStreamingProgressConfig = {
/** Initial progress title. "auto" picks from labels; false hides the title. Default: "auto". */
label?: string | false;
/** Candidate labels for label="auto". Defaults to OpenClaw's built-in progress labels. */
labels?: string[];
/** Maximum number of progress lines to keep below the label. Default: 8. */
maxLines?: number;
/** Progress draft renderer. "text" is the portable fallback; "rich" lets supported channels use structured UI. */
render?: "text" | "rich";
/** Include compact tool/task progress in the draft. Default: true. */
toolProgress?: boolean;
/** Command/exec progress detail in the draft. "raw" preserves released behavior; "status" shows only the tool label. Default: "raw". */
commandText?: ChannelStreamingCommandTextMode;
};
export type ChannelStreamingPreviewConfig = {
/** Chunking thresholds for preview-draft updates while streaming. */
chunk?: BlockStreamingChunkConfig;
/**
* Render live tool/activity updates into the preview draft for channels that
* edit a single preview message in place.
* Default: true.
*/
toolProgress?: boolean;
/** Command/exec progress detail in the preview. "raw" preserves released behavior; "status" shows only the tool label. Default: "raw". */
commandText?: ChannelStreamingCommandTextMode;
};
export type ChannelStreamingBlockConfig = {
/** Enable chunked block-reply delivery for channels that support it. */
enabled?: boolean;
/** Merge streamed block replies before sending. */
coalesce?: BlockStreamingCoalesceConfig;
};
export type ChannelStreamingConfig = {
/**
* Preview streaming mode:
* - "off": disable preview updates
* - "partial": update one preview in place
* - "block": emit larger chunked preview updates
* - "progress": progress/status preview mode for channels that support it
*/
mode?: StreamingMode;
/** Chunking mode for outbound text delivery. */
chunkMode?: TextChunkMode;
/**
* Channel-specific native transport streaming toggle.
* Used today by Slack's native stream API.
*/
nativeTransport?: boolean;
preview?: ChannelStreamingPreviewConfig;
progress?: ChannelStreamingProgressConfig;
block?: ChannelStreamingBlockConfig;
};
export type ChannelDeliveryStreamingConfig = Pick<ChannelStreamingConfig, "chunkMode" | "block">;
export type ChannelPreviewStreamingConfig = Pick<
ChannelStreamingConfig,
"mode" | "chunkMode" | "preview" | "progress" | "block"
>;
export type SlackChannelStreamingConfig = Pick<
ChannelStreamingConfig,
"mode" | "chunkMode" | "preview" | "progress" | "block" | "nativeTransport"
>;
export type MarkdownTableMode = "off" | "bullets" | "code" | "block";
export type MarkdownConfig = {
/** Table rendering mode (off|bullets|code|block). */
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;
/**
* Inactivity window for thread-bound sessions (hours).
* Session auto-unfocuses after this amount of idle time. Set to 0 to disable. Default: 24.
*/
idleHours?: number;
/**
* Optional hard max age for thread-bound sessions (hours).
* Session auto-unfocuses once this age is reached even if active. Set to 0 to disable. Default: 0.
*/
maxAgeHours?: number;
/**
* Allow channel integrations to create thread-bound work sessions from
* sessions_spawn or native ACP spawn flows. Channel/account keys can override.
* Default: true when thread bindings are enabled.
*/
spawnSessions?: boolean;
/**
* Default context mode for native subagents spawned into a bound thread.
* Default: "fork" so the child starts from the requester transcript.
*/
defaultSpawnContext?: "isolated" | "fork";
};
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;
mainKey?: string;
sendPolicy?: SessionSendPolicyConfig;
/** Session transcript write-lock acquisition policy. */
writeLock?: SessionWriteLockConfig;
agentToAgent?: {
/** Max ping-pong turns between requester/target (0-20). Default: 5. */
maxPingPongTurns?: number;
};
/** Shared defaults for thread-bound session routing across channels/providers. */
threadBindings?: SessionThreadBindingsConfig;
/** Automatic session store maintenance (pruning, capping, archive retention, disk budget). */
maintenance?: SessionMaintenanceConfig;
};
export type SessionWriteLockConfig = {
/** How long to wait while acquiring a session transcript write lock. Default: 60000. */
acquireTimeoutMs?: number;
};
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;
/** @deprecated Ignored. Run `openclaw doctor --fix` to remove. */
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 rotation. Default: 100 MB. */
maxFileBytes?: number;
consoleLevel?: "silent" | "fatal" | "error" | "warn" | "info" | "debug" | "trace";
consoleStyle?: "pretty" | "compact" | "json";
/** Redact sensitive tokens in log sinks and persisted transcript text. Default: "tools". Safety-boundary UI/tool/diagnostic payloads may still redact when this is "off". */
redactSensitive?: "off" | "tools";
/** Regex patterns used to redact sensitive tokens from logs and transcripts. */
redactPatterns?: string[];
};
export type DiagnosticsOtelConfig = {
enabled?: boolean;
endpoint?: string;
tracesEndpoint?: string;
metricsEndpoint?: string;
logsEndpoint?: 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;
/**
* Opt-in raw content capture for OTEL span attributes.
* Boolean `true` captures non-system message/tool content; the object form
* can enable each content class explicitly.
*/
captureContent?:
| boolean
| {
enabled?: boolean;
inputMessages?: boolean;
outputMessages?: boolean;
toolInputs?: boolean;
toolOutputs?: boolean;
systemPrompt?: boolean;
};
};
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[];
/** Threshold in ms before a processing session with no observed progress logs diagnostics. */
stuckSessionWarnMs?: number;
/** Threshold in ms before eligible stalled active work may be aborted for recovery. */
stuckSessionAbortMs?: number;
otel?: DiagnosticsOtelConfig;
cacheTrace?: DiagnosticsCacheTraceConfig;
};
export type WebReconnectConfig = {
initialMs?: number;
maxMs?: number;
factor?: number;
jitter?: number;
maxAttempts?: number; // 0 = unlimited
};
export type WebWhatsAppConfig = {
/** Baileys application ping interval in milliseconds. Default: 25000. */
keepAliveIntervalMs?: number;
/** WebSocket opening handshake timeout in milliseconds. Default: 60000. */
connectTimeoutMs?: number;
/** Baileys query timeout in milliseconds. Default: 60000. */
defaultQueryTimeoutMs?: number;
};
export type WebConfig = {
/** If false, do not start the WhatsApp web provider. Default: true. */
enabled?: boolean;
heartbeatSeconds?: number;
reconnect?: WebReconnectConfig;
whatsapp?: WebWhatsAppConfig;
};
// 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;
};