From 693f61404ddc88d9479a1524bb4b43fbc418d5d9 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 2 Mar 2026 14:35:34 +0000 Subject: [PATCH] refactor(shared): centralize assistant identity and usage timeseries types --- src/gateway/assistant-identity.ts | 15 +------------- src/infra/session-cost-usage.types.ts | 21 ++++++-------------- src/shared/assistant-identity-values.ts | 16 +++++++++++++++ src/shared/session-usage-timeseries-types.ts | 16 +++++++++++++++ ui/src/ui/assistant-identity.ts | 16 ++------------- ui/src/ui/usage-types.ts | 21 ++++++-------------- 6 files changed, 47 insertions(+), 58 deletions(-) create mode 100644 src/shared/assistant-identity-values.ts create mode 100644 src/shared/session-usage-timeseries-types.ts diff --git a/src/gateway/assistant-identity.ts b/src/gateway/assistant-identity.ts index d1a103e9260..1ebc583e547 100644 --- a/src/gateway/assistant-identity.ts +++ b/src/gateway/assistant-identity.ts @@ -3,6 +3,7 @@ import { resolveAgentIdentity } from "../agents/identity.js"; import { loadAgentIdentity } from "../commands/agents.config.js"; import type { OpenClawConfig } from "../config/config.js"; import { normalizeAgentId } from "../routing/session-key.js"; +import { coerceIdentityValue } from "../shared/assistant-identity-values.js"; import { isAvatarHttpUrl, isAvatarImageDataUrl, @@ -26,20 +27,6 @@ export type AssistantIdentity = { emoji?: string; }; -function coerceIdentityValue(value: string | undefined, maxLength: number): string | undefined { - if (typeof value !== "string") { - return undefined; - } - const trimmed = value.trim(); - if (!trimmed) { - return undefined; - } - if (trimmed.length <= maxLength) { - return trimmed; - } - return trimmed.slice(0, maxLength); -} - function isAvatarUrl(value: string): boolean { return isAvatarHttpUrl(value) || isAvatarImageDataUrl(value); } diff --git a/src/infra/session-cost-usage.types.ts b/src/infra/session-cost-usage.types.ts index 56c33721192..70de453bcd9 100644 --- a/src/infra/session-cost-usage.types.ts +++ b/src/infra/session-cost-usage.types.ts @@ -1,4 +1,8 @@ import type { NormalizedUsage } from "../agents/usage.js"; +import type { + SessionUsageTimePoint as SharedSessionUsageTimePoint, + SessionUsageTimeSeries as SharedSessionUsageTimeSeries, +} from "../shared/session-usage-timeseries-types.js"; export type CostBreakdown = { total?: number; @@ -141,22 +145,9 @@ export type DiscoveredSession = { firstUserMessage?: string; }; -export type SessionUsageTimePoint = { - timestamp: number; - input: number; - output: number; - cacheRead: number; - cacheWrite: number; - totalTokens: number; - cost: number; - cumulativeTokens: number; - cumulativeCost: number; -}; +export type SessionUsageTimePoint = SharedSessionUsageTimePoint; -export type SessionUsageTimeSeries = { - sessionId?: string; - points: SessionUsageTimePoint[]; -}; +export type SessionUsageTimeSeries = SharedSessionUsageTimeSeries; export type SessionLogEntry = { timestamp: number; diff --git a/src/shared/assistant-identity-values.ts b/src/shared/assistant-identity-values.ts new file mode 100644 index 00000000000..8894ee129d3 --- /dev/null +++ b/src/shared/assistant-identity-values.ts @@ -0,0 +1,16 @@ +export function coerceIdentityValue( + value: string | undefined, + maxLength: number, +): string | undefined { + if (typeof value !== "string") { + return undefined; + } + const trimmed = value.trim(); + if (!trimmed) { + return undefined; + } + if (trimmed.length <= maxLength) { + return trimmed; + } + return trimmed.slice(0, maxLength); +} diff --git a/src/shared/session-usage-timeseries-types.ts b/src/shared/session-usage-timeseries-types.ts new file mode 100644 index 00000000000..97c9324b3f6 --- /dev/null +++ b/src/shared/session-usage-timeseries-types.ts @@ -0,0 +1,16 @@ +export type SessionUsageTimePoint = { + timestamp: number; + input: number; + output: number; + cacheRead: number; + cacheWrite: number; + totalTokens: number; + cost: number; + cumulativeTokens: number; + cumulativeCost: number; +}; + +export type SessionUsageTimeSeries = { + sessionId?: string; + points: SessionUsageTimePoint[]; +}; diff --git a/ui/src/ui/assistant-identity.ts b/ui/src/ui/assistant-identity.ts index 3f6e14fa925..83543bf3a2f 100644 --- a/ui/src/ui/assistant-identity.ts +++ b/ui/src/ui/assistant-identity.ts @@ -1,3 +1,5 @@ +import { coerceIdentityValue } from "../../../src/shared/assistant-identity-values.js"; + const MAX_ASSISTANT_NAME = 50; const MAX_ASSISTANT_AVATAR = 200; @@ -10,20 +12,6 @@ export type AssistantIdentity = { avatar: string | null; }; -function coerceIdentityValue(value: string | undefined, maxLength: number): string | undefined { - if (typeof value !== "string") { - return undefined; - } - const trimmed = value.trim(); - if (!trimmed) { - return undefined; - } - if (trimmed.length <= maxLength) { - return trimmed; - } - return trimmed.slice(0, maxLength); -} - export function normalizeAssistantIdentity( input?: Partial | null, ): AssistantIdentity { diff --git a/ui/src/ui/usage-types.ts b/ui/src/ui/usage-types.ts index 7e03f1c3346..e79ecd41939 100644 --- a/ui/src/ui/usage-types.ts +++ b/ui/src/ui/usage-types.ts @@ -1,3 +1,7 @@ +import type { + SessionUsageTimePoint as SharedSessionUsageTimePoint, + SessionUsageTimeSeries as SharedSessionUsageTimeSeries, +} from "../../../src/shared/session-usage-timeseries-types.js"; import type { SessionsUsageResult as SharedSessionsUsageResult } from "../../../src/shared/usage-types.js"; export type SessionsUsageEntry = SharedSessionsUsageResult["sessions"][number]; @@ -13,19 +17,6 @@ export type CostUsageSummary = { totals: SessionsUsageTotals; }; -export type SessionUsageTimePoint = { - timestamp: number; - input: number; - output: number; - cacheRead: number; - cacheWrite: number; - totalTokens: number; - cost: number; - cumulativeTokens: number; - cumulativeCost: number; -}; +export type SessionUsageTimePoint = SharedSessionUsageTimePoint; -export type SessionUsageTimeSeries = { - sessionId?: string; - points: SessionUsageTimePoint[]; -}; +export type SessionUsageTimeSeries = SharedSessionUsageTimeSeries;