mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-20 21:23:23 +00:00
refactor: dedupe finite number coercion helper
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { asFiniteNumber } from "../shared/number-coercion.js";
|
||||
|
||||
export type UsageLike = {
|
||||
input?: number;
|
||||
output?: number;
|
||||
@@ -68,16 +70,6 @@ export function makeZeroUsageSnapshot(): AssistantUsageSnapshot {
|
||||
};
|
||||
}
|
||||
|
||||
const asFiniteNumber = (value: unknown): number | undefined => {
|
||||
if (typeof value !== "number") {
|
||||
return undefined;
|
||||
}
|
||||
if (!Number.isFinite(value)) {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
export function hasNonzeroUsage(usage?: NormalizedUsage | null): usage is NormalizedUsage {
|
||||
if (!usage) {
|
||||
return false;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asFiniteNumber } from "../shared/number-coercion.js";
|
||||
import { sleep } from "../utils.js";
|
||||
import { generateSecureFraction } from "./secure-random.js";
|
||||
|
||||
@@ -30,9 +31,6 @@ const DEFAULT_RETRY_CONFIG = {
|
||||
jitter: 0,
|
||||
};
|
||||
|
||||
const asFiniteNumber = (value: unknown): number | undefined =>
|
||||
typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
|
||||
const clampNumber = (value: unknown, fallback: number, min?: number, max?: number) => {
|
||||
const next = asFiniteNumber(value);
|
||||
if (next === undefined) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
} from "../config/sessions/paths.js";
|
||||
import type { SessionEntry } from "../config/sessions/types.js";
|
||||
import { stripEnvelope, stripMessageIdHints } from "../shared/chat-envelope.js";
|
||||
import { asFiniteNumber } from "../shared/number-coercion.js";
|
||||
import { countToolResults, extractToolCallNames } from "../utils/transcript-tools.js";
|
||||
import { estimateUsageCost, resolveModelCostConfig } from "../utils/usage-format.js";
|
||||
import type {
|
||||
@@ -74,16 +75,6 @@ const emptyTotals = (): CostUsageTotals => ({
|
||||
missingCostEntries: 0,
|
||||
});
|
||||
|
||||
const toFiniteNumber = (value: unknown): number | undefined => {
|
||||
if (typeof value !== "number") {
|
||||
return undefined;
|
||||
}
|
||||
if (!Number.isFinite(value)) {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const extractCostBreakdown = (usageRaw?: UsageLike | null): CostBreakdown | undefined => {
|
||||
if (!usageRaw || typeof usageRaw !== "object") {
|
||||
return undefined;
|
||||
@@ -94,17 +85,17 @@ const extractCostBreakdown = (usageRaw?: UsageLike | null): CostBreakdown | unde
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const total = toFiniteNumber(cost.total);
|
||||
const total = asFiniteNumber(cost.total);
|
||||
if (total === undefined || total < 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
total,
|
||||
input: toFiniteNumber(cost.input),
|
||||
output: toFiniteNumber(cost.output),
|
||||
cacheRead: toFiniteNumber(cost.cacheRead),
|
||||
cacheWrite: toFiniteNumber(cost.cacheWrite),
|
||||
input: asFiniteNumber(cost.input),
|
||||
output: asFiniteNumber(cost.output),
|
||||
cacheRead: asFiniteNumber(cost.cacheRead),
|
||||
cacheWrite: asFiniteNumber(cost.cacheWrite),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -117,7 +108,7 @@ const parseTimestamp = (entry: Record<string, unknown>): Date | undefined => {
|
||||
}
|
||||
}
|
||||
const message = entry.message as Record<string, unknown> | undefined;
|
||||
const messageTimestamp = toFiniteNumber(message?.timestamp);
|
||||
const messageTimestamp = asFiniteNumber(message?.timestamp);
|
||||
if (messageTimestamp !== undefined) {
|
||||
const parsed = new Date(messageTimestamp);
|
||||
if (!Number.isNaN(parsed.valueOf())) {
|
||||
@@ -152,7 +143,7 @@ const parseTranscriptEntry = (entry: Record<string, unknown>): ParsedTranscriptE
|
||||
|
||||
const costBreakdown = extractCostBreakdown(usageRaw);
|
||||
const stopReason = typeof message.stopReason === "string" ? message.stopReason : undefined;
|
||||
const durationMs = toFiniteNumber(message.durationMs ?? entry.durationMs);
|
||||
const durationMs = asFiniteNumber(message.durationMs ?? entry.durationMs);
|
||||
|
||||
return {
|
||||
message,
|
||||
|
||||
3
src/shared/number-coercion.ts
Normal file
3
src/shared/number-coercion.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function asFiniteNumber(value: unknown): number | undefined {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
export { asFiniteNumber } from "../shared/number-coercion.js";
|
||||
|
||||
export function trimToUndefined(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
||||
}
|
||||
@@ -6,10 +8,6 @@ export function asBoolean(value: unknown): boolean | undefined {
|
||||
return typeof value === "boolean" ? value : undefined;
|
||||
}
|
||||
|
||||
export function asFiniteNumber(value: unknown): number | undefined {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
|
||||
export function asObject(value: unknown): Record<string, unknown> | undefined {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
|
||||
Reference in New Issue
Block a user