export interface AssistantInsightMetric { label: string; value: string; tone?: "neutral" | "good" | "warn" | "danger" | "info"; } export interface AssistantInsightSection { title: string; metrics: AssistantInsightMetric[]; } export interface AssistantInsight { kind: "chargeability" | "resource_match" | "holiday_region" | "resource_holidays"; title: string; subtitle?: string; metrics: AssistantInsightMetric[]; sections?: AssistantInsightSection[]; } function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function asString(value: unknown): string | null { return typeof value === "string" && value.trim() ? value : null; } function asNumber(value: unknown): number | null { return typeof value === "number" && Number.isFinite(value) ? value : null; } function formatHours(value: unknown): string | null { const num = asNumber(value); return num == null ? null : `${num.toFixed(num % 1 === 0 ? 0 : 1)} h`; } function formatDays(value: unknown): string | null { const num = asNumber(value); return num == null ? null : `${num.toFixed(num % 1 === 0 ? 0 : 1)} d`; } function pushMetric( metrics: AssistantInsightMetric[], label: string, value: string | null, tone?: AssistantInsightMetric["tone"], ) { if (!value) return; metrics.push({ label, value, ...(tone ? { tone } : {}) }); } function createLocationLabel(locationContext: Record | undefined): string | null { if (!locationContext) return null; const parts = [ asString(locationContext.metroCity), asString(locationContext.federalState), asString(locationContext.country), asString(locationContext.countryCode), ].filter(Boolean); return parts.length > 0 ? parts.join(", ") : null; } function buildChargeabilityInsight(data: Record): AssistantInsight | null { const resource = asString(data.resource); const month = asString(data.month); if (!resource || !month) return null; const holidaySummary = isRecord(data.holidaySummary) ? data.holidaySummary : undefined; const absenceSummary = isRecord(data.absenceSummary) ? data.absenceSummary : undefined; const capacityBreakdown = isRecord(data.capacityBreakdown) ? data.capacityBreakdown : undefined; const locationContext = isRecord(data.locationContext) ? data.locationContext : undefined; const chargeabilityPct = asNumber(data.chargeabilityPct); const targetPct = asNumber(data.targetPct); const metrics: AssistantInsightMetric[] = []; pushMetric(metrics, "Chargeability", asString(data.chargeability), chargeabilityPct == null || targetPct == null ? "info" : chargeabilityPct >= targetPct ? "good" : "warn"); pushMetric(metrics, "Available", formatHours(data.availableHours)); pushMetric(metrics, "Booked", formatHours(data.bookedHours)); pushMetric(metrics, "Unassigned", formatHours(data.unassignedHours)); pushMetric(metrics, "Target", formatHours(data.targetHours)); pushMetric(metrics, "Holidays", formatDays(holidaySummary?.workdayCount ?? holidaySummary?.count)); const sections: AssistantInsightSection[] = []; const basisMetrics: AssistantInsightMetric[] = []; pushMetric(basisMetrics, "Location", createLocationLabel(locationContext), "info"); pushMetric(basisMetrics, "Base working days", formatDays(data.baseWorkingDays)); pushMetric(basisMetrics, "Effective working days", formatDays(data.workingDays)); pushMetric(basisMetrics, "Base capacity", formatHours(data.baseAvailableHours)); if (basisMetrics.length > 0) { sections.push({ title: "Basis", metrics: basisMetrics }); } const deductionMetrics: AssistantInsightMetric[] = []; pushMetric(deductionMetrics, "Holiday deduction", formatHours(holidaySummary?.hoursDeduction ?? capacityBreakdown?.holidayHoursDeduction), "warn"); pushMetric(deductionMetrics, "Absence deduction", formatHours(absenceSummary?.hoursDeduction ?? capacityBreakdown?.absenceHoursDeduction), "warn"); pushMetric(deductionMetrics, "Absence days", formatDays(absenceSummary?.dayEquivalent)); if (deductionMetrics.length > 0) { sections.push({ title: "Deductions", metrics: deductionMetrics }); } return { kind: "chargeability", title: `${resource} ยท ${month}`, subtitle: "Holiday-aware monthly capacity", metrics, ...(sections.length > 0 ? { sections } : {}), }; } function buildHolidayRegionInsight(data: Record): AssistantInsight | null { const locationContext = isRecord(data.locationContext) ? data.locationContext : undefined; const periodStart = asString(data.periodStart); const periodEnd = asString(data.periodEnd); const metrics: AssistantInsightMetric[] = []; pushMetric(metrics, "Region", createLocationLabel(locationContext), "info"); pushMetric(metrics, "Resolved holidays", asNumber(data.count)?.toString() ?? null); pushMetric(metrics, "Period", periodStart && periodEnd ? `${periodStart} to ${periodEnd}` : null); const summary = isRecord(data.summary) ? data.summary : undefined; const scopeItems = Array.isArray(summary?.byScope) ? summary.byScope : []; const scopeMetrics = scopeItems .map((item) => { if (!isRecord(item)) return null; const scope = asString(item.scope); const count = asNumber(item.count); if (!scope || count == null) return null; return { label: scope, value: String(count) } satisfies AssistantInsightMetric; }) .filter((item): item is AssistantInsightMetric => item !== null); return { kind: "holiday_region", title: createLocationLabel(locationContext) ?? "Regional holidays", subtitle: "Resolved public holiday set", metrics, ...(scopeMetrics.length > 0 ? { sections: [{ title: "Scopes", metrics: scopeMetrics }] } : {}), }; } function buildResourceHolidayInsight(data: Record): AssistantInsight | null { const resource = isRecord(data.resource) ? data.resource : undefined; const summary = isRecord(data.summary) ? data.summary : undefined; const periodStart = asString(data.periodStart); const periodEnd = asString(data.periodEnd); const metrics: AssistantInsightMetric[] = []; pushMetric(metrics, "Employee", asString(resource?.name) ?? asString(resource?.eid)); pushMetric(metrics, "Location", createLocationLabel(resource), "info"); pushMetric(metrics, "Resolved holidays", asNumber(data.count)?.toString() ?? null); pushMetric(metrics, "Period", periodStart && periodEnd ? `${periodStart} to ${periodEnd}` : null); const scopeItems = Array.isArray(summary?.byScope) ? summary.byScope : []; const scopeMetrics = scopeItems .map((item) => { if (!isRecord(item)) return null; const scope = asString(item.scope); const count = asNumber(item.count); if (!scope || count == null) return null; return { label: scope, value: String(count) } satisfies AssistantInsightMetric; }) .filter((item): item is AssistantInsightMetric => item !== null); return { kind: "resource_holidays", title: `${asString(resource?.name) ?? "Resource"} holidays`, subtitle: "Location-specific holiday resolution", metrics, ...(scopeMetrics.length > 0 ? { sections: [{ title: "Scopes", metrics: scopeMetrics }] } : {}), }; } function buildResourceMatchInsight(data: Record): AssistantInsight | null { const project = isRecord(data.project) ? data.project : undefined; const period = isRecord(data.period) ? data.period : undefined; const bestMatch = isRecord(data.bestMatch) ? data.bestMatch : undefined; if (!project || !period || !bestMatch) return null; const remainingHours = asNumber(bestMatch.remainingHours); const remainingHoursPerDay = asNumber(bestMatch.remainingHoursPerDay); const lcr = asString(bestMatch.lcr); const holidaySummary = isRecord(bestMatch.holidaySummary) ? bestMatch.holidaySummary : undefined; const absenceSummary = isRecord(bestMatch.absenceSummary) ? bestMatch.absenceSummary : undefined; const capacityBreakdown = isRecord(bestMatch.capacityBreakdown) ? bestMatch.capacityBreakdown : undefined; const metrics: AssistantInsightMetric[] = []; pushMetric(metrics, "Best match", asString(bestMatch.name) ?? asString(bestMatch.eid), "good"); pushMetric(metrics, "Project", asString(project.name) ?? asString(project.shortCode)); pushMetric(metrics, "Remaining", formatHours(remainingHours), remainingHours != null && remainingHours > 0 ? "good" : "warn"); pushMetric(metrics, "Per workday", formatHours(remainingHoursPerDay)); pushMetric(metrics, "LCR", lcr); pushMetric(metrics, "Holiday deduction", formatHours(holidaySummary?.hoursDeduction), "warn"); const sections: AssistantInsightSection[] = []; const profileMetrics: AssistantInsightMetric[] = []; pushMetric(profileMetrics, "Role", asString(bestMatch.role)); pushMetric(profileMetrics, "Chapter", asString(bestMatch.chapter)); pushMetric(profileMetrics, "Location", createLocationLabel(bestMatch), "info"); pushMetric(profileMetrics, "Candidate pool", asNumber(data.candidateCount)?.toString() ?? null); if (profileMetrics.length > 0) { sections.push({ title: "Selection", metrics: profileMetrics }); } const basisMetrics: AssistantInsightMetric[] = []; pushMetric(basisMetrics, "Window", asString(period.startDate) && asString(period.endDate) ? `${asString(period.startDate)} to ${asString(period.endDate)}` : null); pushMetric(basisMetrics, "Ranking", asString(period.rankingMode)); pushMetric(basisMetrics, "Min/day", formatHours(period.minHoursPerDay)); pushMetric(basisMetrics, "Base capacity", formatHours(capacityBreakdown?.baseAvailableHours ?? bestMatch.baseAvailableHours)); pushMetric(basisMetrics, "Effective capacity", formatHours(bestMatch.availableHours)); pushMetric(basisMetrics, "Absence deduction", formatHours(absenceSummary?.hoursDeduction ?? capacityBreakdown?.absenceHoursDeduction), "warn"); if (basisMetrics.length > 0) { sections.push({ title: "Capacity basis", metrics: basisMetrics }); } return { kind: "resource_match", title: `${asString(project.shortCode) ?? asString(project.name) ?? "Project"} staffing`, subtitle: "Holiday-aware best-fit resource", metrics, ...(sections.length > 0 ? { sections } : {}), }; } export function buildAssistantInsight(toolName: string, data: unknown): AssistantInsight | null { if (!isRecord(data)) return null; switch (toolName) { case "get_chargeability": return buildChargeabilityInsight(data); case "find_best_project_resource": return buildResourceMatchInsight(data); case "list_holidays_by_region": return buildHolidayRegionInsight(data); case "get_resource_holidays": return buildResourceHolidayInsight(data); default: return null; } }