Files
openclaw/src/gateway/session-utils.types.ts
Peter Lindsey 6add1cc969 feat(messages): config-level default for the persistent /usage footer
Adds `messages.responseUsage` (precedence session -> channel -> config default
-> off) so the persistent /usage footer can default-on, with three distinct
states: explicit on (tokens/full), explicit off (persisted), and unset (inherit
the configured default).

Unifies effective-value resolution behind a single channel-aware resolver
`resolveEffectiveResponseUsage` used by reply rendering, the no-arg /usage
toggle, the ACP control, and the gateway session-row builder; the row builder's
`effectiveResponseUsage` is carried through sessions.changed events, chat
snapshots, and the UI row so live consumers never go stale. `/usage reset`
(aliases inherit/clear/default) clears the override to inherit; only explicit
off persists; a full session reset preserves the preference. ACP "Usage detail"
gains an "inherit" option for unset sessions. Docs/help/completions updated; "on"
documented as a legacy alias; config-doc baseline regenerated.
2026-06-24 07:12:33 -07:00

140 lines
4.4 KiB
TypeScript

// Shared Gateway session projection types.
// Keeps server methods and Control UI payloads aligned.
import type { FastMode } from "@openclaw/normalization-core/string-coerce";
import type { ChatType } from "../channels/chat-type.js";
import type {
SessionCompactionCheckpoint,
SessionEntry,
SessionGoal,
} from "../config/sessions/types.js";
import type { PluginSessionExtensionProjection } from "../plugins/host-hooks.js";
import type { FastModeSource } from "../shared/fast-mode.js";
import type {
GatewayAgentRuntime,
GatewayAgentRow as SharedGatewayAgentRow,
GatewayThinkingLevelOption,
SessionsListResultBase,
SessionsPatchResultBase,
} from "../shared/session-types.js";
import type { DeliveryContext } from "../utils/delivery-context.types.js";
// Shared Gateway session response contracts. Server methods, UI adapters, and
// tests import these types so list/patch/preview payloads evolve together.
export type GatewaySessionsDefaults = {
modelProvider: string | null;
model: string | null;
contextTokens: number | null;
thinkingLevels?: GatewayThinkingLevelOption[];
thinkingOptions?: string[];
thinkingDefault?: string;
};
/** Runtime status surfaced for the latest session run. */
export type SessionRunStatus = "running" | "done" | "failed" | "killed" | "timeout";
type SubagentRunState = "active" | "interrupted" | "historical";
export type SessionCompactionCheckpointPreview = Pick<
SessionCompactionCheckpoint,
"checkpointId" | "createdAt" | "reason"
>;
export type GatewaySessionRow = {
key: string;
spawnedBy?: string;
spawnedWorkspaceDir?: string;
spawnedCwd?: string;
forkedFromParent?: boolean;
spawnDepth?: number;
subagentRole?: SessionEntry["subagentRole"];
subagentControlScope?: SessionEntry["subagentControlScope"];
kind: "direct" | "group" | "global" | "unknown";
label?: string;
displayName?: string;
derivedTitle?: string;
lastMessagePreview?: string;
channel?: string;
subject?: string;
groupChannel?: string;
space?: string;
chatType?: ChatType;
origin?: SessionEntry["origin"];
updatedAt: number | null;
sessionId?: string;
systemSent?: boolean;
abortedLastRun?: boolean;
thinkingLevel?: string;
thinkingLevels?: GatewayThinkingLevelOption[];
thinkingOptions?: string[];
thinkingDefault?: string;
fastMode?: FastMode;
effectiveFastMode?: FastMode;
effectiveFastModeSource?: FastModeSource;
fastAutoOnSeconds?: number;
verboseLevel?: string;
traceLevel?: string;
reasoningLevel?: string;
elevatedLevel?: string;
sendPolicy?: "allow" | "deny";
inputTokens?: number;
outputTokens?: number;
totalTokens?: number;
totalTokensFresh?: boolean;
goal?: SessionGoal;
estimatedCostUsd?: number;
status?: SessionRunStatus;
hasActiveRun?: boolean;
subagentRunState?: SubagentRunState;
hasActiveSubagentRun?: boolean;
startedAt?: number;
endedAt?: number;
runtimeMs?: number;
parentSessionKey?: string;
childSessions?: string[];
responseUsage?: "on" | "off" | "tokens" | "full";
/** Resolved effective usage mode (session override → channel config → default → off). Populated by surfaces that have config access; absent from the raw session store row. */
effectiveResponseUsage?: "on" | "off" | "tokens" | "full";
modelProvider?: string;
model?: string;
agentRuntime?: GatewayAgentRuntime;
contextTokens?: number;
contextBudgetStatus?: SessionEntry["contextBudgetStatus"];
deliveryContext?: DeliveryContext;
lastChannel?: SessionEntry["lastChannel"];
lastTo?: string;
lastAccountId?: string;
lastThreadId?: SessionEntry["lastThreadId"];
compactionCheckpointCount?: number;
latestCompactionCheckpoint?: SessionCompactionCheckpointPreview;
pluginExtensions?: PluginSessionExtensionProjection[];
};
export type GatewayAgentRow = SharedGatewayAgentRow;
export type SessionPreviewItem = {
role: "user" | "assistant" | "tool" | "system" | "other";
text: string;
};
export type SessionsPreviewEntry = {
key: string;
status: "ok" | "empty" | "missing" | "error";
items: SessionPreviewItem[];
};
export type SessionsPreviewResult = {
ts: number;
previews: SessionsPreviewEntry[];
};
export type SessionsListResult = SessionsListResultBase<GatewaySessionsDefaults, GatewaySessionRow>;
export type SessionsPatchResult = SessionsPatchResultBase<SessionEntry> & {
entry: SessionEntry;
resolved?: {
modelProvider?: string;
model?: string;
agentRuntime?: GatewayAgentRuntime;
};
};