import * as Cause from "effect/Cause";import * as Exit from "effect/Exit"; export type MetricAttributeValue = string;export type MetricAttributes = Readonly<Record<string, MetricAttributeValue>>;export type ObservabilityOutcome = "success" | "failure" | "interrupt"; export function compactMetricAttributes( attributes: Readonly<Record<string, unknown>>,): MetricAttributes { return Object.fromEntries( Object.entries(attributes).flatMap(([key, value]) => { if (value === undefined || value === null) { return []; } if (typeof value === "string") { return [[key, value]]; } if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") { return [[key, String(value)]]; } return []; }), );} export function outcomeFromExit(exit: Exit.Exit<unknown, unknown>): ObservabilityOutcome { if (Exit.isSuccess(exit)) { return "success"; } return Cause.hasInterruptsOnly(exit.cause) ? "interrupt" : "failure";} export function normalizeModelMetricLabel(model: string | null | undefined): string | undefined { const normalized = model?.trim().toLowerCase(); if (!normalized) { return undefined; } if (normalized.includes("gpt")) { return "gpt"; } if (normalized.includes("claude")) { return "claude"; } if (normalized.includes("gemini")) { return "gemini"; } return "other";}
import * as Cause from "effect/Cause";
import * as Exit from "effect/Exit";
export type MetricAttributeValue = string;
export type MetricAttributes = Readonly<Record<string, MetricAttributeValue>>;
export type ObservabilityOutcome = "success" | "failure" | "interrupt";
export function compactMetricAttributes(
attributes: Readonly<Record<string, unknown>>,
): MetricAttributes {
return Object.fromEntries(
Object.entries(attributes).flatMap(([key, value]) => {
if (value === undefined || value === null) {
return [];
}
if (typeof value === "string") {
return [[key, value]];
}
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
return [[key, String(value)]];
}
return [];
}),
);
}
export function outcomeFromExit(exit: Exit.Exit<unknown, unknown>): ObservabilityOutcome {
if (Exit.isSuccess(exit)) {
return "success";
}
return Cause.hasInterruptsOnly(exit.cause) ? "interrupt" : "failure";
}
export function normalizeModelMetricLabel(model: string | null | undefined): string | undefined {
const normalized = model?.trim().toLowerCase();
if (!normalized) {
return undefined;
}
if (normalized.includes("gpt")) {
return "gpt";
}
if (normalized.includes("claude")) {
return "claude";
}
if (normalized.includes("gemini")) {
return "gemini";
}
return "other";
}