mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-21 16:41:56 +00:00
* feat(ui): Token Usage dashboard with session analytics Adds a comprehensive Token Usage view to the dashboard: Backend: - Extended session-cost-usage.ts with per-session daily breakdown - Added date range filtering (startMs/endMs) to API endpoints - New sessions.usage, sessions.usage.timeseries, sessions.usage.logs endpoints - Cost breakdown by token type (input/output/cache read/write) Frontend: - Two-column layout: Daily chart + breakdown | Sessions list - Interactive daily bar chart with click-to-filter and shift-click range select - Session detail panel with usage timeline, conversation logs, context weight - Filter chips for active day/session selections - Toggle between tokens/cost view modes (default: cost) - Responsive design for smaller screens UX improvements: - 21-day default date range - Debounced date input (400ms) - Session list shows filtered totals when days selected - Context weight breakdown shows skills, tools, files contribution * fix(ui): restore gatewayUrl validation and syncUrlWithSessionKey signature - Restore normalizeGatewayUrl() to validate ws:/wss: protocol - Restore isTopLevelWindow() guard for iframe security - Revert syncUrlWithSessionKey signature (host param was unused) * feat(ui): Token Usage dashboard with session analytics Adds a comprehensive Token Usage view to the dashboard: Backend: - Extended session-cost-usage.ts with per-session daily breakdown - Added date range filtering (startMs/endMs) to API endpoints - New sessions.usage, sessions.usage.timeseries, sessions.usage.logs endpoints - Cost breakdown by token type (input/output/cache read/write) Frontend: - Two-column layout: Daily chart + breakdown | Sessions list - Interactive daily bar chart with click-to-filter and shift-click range select - Session detail panel with usage timeline, conversation logs, context weight - Filter chips for active day/session selections - Toggle between tokens/cost view modes (default: cost) - Responsive design for smaller screens UX improvements: - 21-day default date range - Debounced date input (400ms) - Session list shows filtered totals when days selected - Context weight breakdown shows skills, tools, files contribution * fix: usage dashboard data + cost handling (#8462) (thanks @mcinteerj) * Usage: enrich metrics dashboard * Usage: add latency + model trends * Gateway: improve usage log parsing * UI: add usage query helpers * UI: client-side usage filter + debounce * Build: harden write-cli-compat timing * UI: add conversation log filters * UI: fix usage dashboard lint + state * Web UI: default usage dates to local day * Protocol: sync session usage params (#8462) (thanks @mcinteerj, @TakHoffman) --------- Co-authored-by: Jake McInteer <mcinteerj@gmail.com>
120 lines
4.4 KiB
TypeScript
120 lines
4.4 KiB
TypeScript
import { Type } from "@sinclair/typebox";
|
|
import { NonEmptyString, SessionLabelString } from "./primitives.js";
|
|
|
|
export const SessionsListParamsSchema = Type.Object(
|
|
{
|
|
limit: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
activeMinutes: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
includeGlobal: Type.Optional(Type.Boolean()),
|
|
includeUnknown: Type.Optional(Type.Boolean()),
|
|
/**
|
|
* Read first 8KB of each session transcript to derive title from first user message.
|
|
* Performs a file read per session - use `limit` to bound result set on large stores.
|
|
*/
|
|
includeDerivedTitles: Type.Optional(Type.Boolean()),
|
|
/**
|
|
* Read last 16KB of each session transcript to extract most recent message preview.
|
|
* Performs a file read per session - use `limit` to bound result set on large stores.
|
|
*/
|
|
includeLastMessage: Type.Optional(Type.Boolean()),
|
|
label: Type.Optional(SessionLabelString),
|
|
spawnedBy: Type.Optional(NonEmptyString),
|
|
agentId: Type.Optional(NonEmptyString),
|
|
search: Type.Optional(Type.String()),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const SessionsPreviewParamsSchema = Type.Object(
|
|
{
|
|
keys: Type.Array(NonEmptyString, { minItems: 1 }),
|
|
limit: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
maxChars: Type.Optional(Type.Integer({ minimum: 20 })),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const SessionsResolveParamsSchema = Type.Object(
|
|
{
|
|
key: Type.Optional(NonEmptyString),
|
|
sessionId: Type.Optional(NonEmptyString),
|
|
label: Type.Optional(SessionLabelString),
|
|
agentId: Type.Optional(NonEmptyString),
|
|
spawnedBy: Type.Optional(NonEmptyString),
|
|
includeGlobal: Type.Optional(Type.Boolean()),
|
|
includeUnknown: Type.Optional(Type.Boolean()),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const SessionsPatchParamsSchema = Type.Object(
|
|
{
|
|
key: NonEmptyString,
|
|
label: Type.Optional(Type.Union([SessionLabelString, Type.Null()])),
|
|
thinkingLevel: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
verboseLevel: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
reasoningLevel: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
responseUsage: Type.Optional(
|
|
Type.Union([
|
|
Type.Literal("off"),
|
|
Type.Literal("tokens"),
|
|
Type.Literal("full"),
|
|
// Backward compat with older clients/stores.
|
|
Type.Literal("on"),
|
|
Type.Null(),
|
|
]),
|
|
),
|
|
elevatedLevel: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
execHost: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
execSecurity: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
execAsk: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
execNode: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
model: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
spawnedBy: Type.Optional(Type.Union([NonEmptyString, Type.Null()])),
|
|
sendPolicy: Type.Optional(
|
|
Type.Union([Type.Literal("allow"), Type.Literal("deny"), Type.Null()]),
|
|
),
|
|
groupActivation: Type.Optional(
|
|
Type.Union([Type.Literal("mention"), Type.Literal("always"), Type.Null()]),
|
|
),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const SessionsResetParamsSchema = Type.Object(
|
|
{ key: NonEmptyString },
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const SessionsDeleteParamsSchema = Type.Object(
|
|
{
|
|
key: NonEmptyString,
|
|
deleteTranscript: Type.Optional(Type.Boolean()),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const SessionsCompactParamsSchema = Type.Object(
|
|
{
|
|
key: NonEmptyString,
|
|
maxLines: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|
|
|
|
export const SessionsUsageParamsSchema = Type.Object(
|
|
{
|
|
/** Specific session key to analyze; if omitted returns all sessions. */
|
|
key: Type.Optional(NonEmptyString),
|
|
/** Start date for range filter (YYYY-MM-DD). */
|
|
startDate: Type.Optional(Type.String({ pattern: "^\\d{4}-\\d{2}-\\d{2}$" })),
|
|
/** End date for range filter (YYYY-MM-DD). */
|
|
endDate: Type.Optional(Type.String({ pattern: "^\\d{4}-\\d{2}-\\d{2}$" })),
|
|
/** Maximum sessions to return (default 50). */
|
|
limit: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
/** Include context weight breakdown (systemPromptReport). */
|
|
includeContextWeight: Type.Optional(Type.Boolean()),
|
|
},
|
|
{ additionalProperties: false },
|
|
);
|