feat(world/analyst): ground the AI in live cloud metrics so it can answer anything

The analyst's context fed panel names + visibility but NOT the live values, so it
couldn't answer "what's my spend / how many DO nodes / is Enso saving money". On the
cloud board it now also folds a real-data snapshot — live traffic (rps/req), platform
24h (requests/tokens/nodes/GPUs/regions/uptime), the Enso router (cost saved, reward
rate, engine share, models routed), the flywheel ledger, and the caller's billing
(spend/balance/events). Best-effort + parallel with the news feeds; real data only,
mirroring the panels. Pairs with the 26-command control surface — the analyst can now
both control the dashboard AND answer questions about what it shows.

Claude-Session: https://claude.ai/code/session_01SpMZ69ur3tjAXCiwaa7Wv2
This commit is contained in:
hanzo-dev
2026-07-18 16:27:04 -07:00
parent 8c0e928789
commit 3d892d9633
+51 -1
View File
@@ -16,6 +16,10 @@
import { analystTransport, type AnalystLiveHandlers, type AnalystResponse } from './analyst-transport';
import { commandManifest, type AppHost } from './app-commands';
import { fetchWithTimeout } from '@/utils';
import { getTrafficGlobe } from './cloud-map';
import { getCloudPulse, getMyBilling } from './cloud-pulse';
import { getRouterStats } from './router-stats';
import { getEnsoTraining } from './enso-training';
// The grounding snapshot is best-effort garnish. Cap each read so a cold server
// (gdelt-doc can take ~10s cold) never delays the user's chat send.
@@ -71,7 +75,17 @@ export async function collectContext(host: AppHost): Promise<string> {
parts.push('ORGS (id = name): ' + orgs.map((o) => `${o.id}=${o.name}`).join(', '));
}
const [headlines, crypto, macro] = await Promise.all([topHeadlines(), cryptoSnapshot(), macroSnapshot()]);
// On the cloud board, ground the model in the LIVE platform metrics too, so it can
// answer "what's my spend / how many nodes / is Enso saving money" from real data —
// not just describe which panels exist. Best-effort + parallel with the news feeds.
const wantCloud = st.variant === 'cloud';
const [headlines, crypto, macro, cloud] = await Promise.all([
topHeadlines(),
cryptoSnapshot(),
macroSnapshot(),
wantCloud ? cloudSnapshot() : Promise.resolve(''),
]);
if (cloud) parts.push(cloud);
if (headlines) parts.push('TOP HEADLINES:\n' + headlines);
if (crypto) parts.push('CRYPTO: ' + crypto);
if (macro) parts.push('MACRO SIGNALS: ' + macro);
@@ -79,6 +93,42 @@ export async function collectContext(host: AppHost): Promise<string> {
return parts.join('\n\n');
}
// Live Hanzo-cloud metrics for the analyst's grounding: traffic, platform 24h, the
// Enso router (cost saved / reward / engine share / models routed), the flywheel
// ledger, and the caller's billing. Each read is best-effort (null on failure) so a
// slow feed never blocks the answer. REAL data only — mirrors the panels verbatim.
async function cloudSnapshot(): Promise<string> {
const n = (v: number, d = 0): string => (Number.isFinite(v) ? v.toFixed(d) : '0');
const [traffic, pulse, stats, enso, bill] = await Promise.all([
getTrafficGlobe().catch(() => null),
getCloudPulse().catch(() => null),
getRouterStats(24).catch(() => null),
getEnsoTraining().catch(() => null),
getMyBilling().catch(() => null),
]);
const lines: string[] = [];
if (traffic?.totals) {
lines.push(`Live traffic: ${n(traffic.totals.rps_1m, 2)} req/s (1m), ${n(traffic.totals.rpm_60m, 1)} req/min (60m avg), ${traffic.points?.length ?? 0} active regions.`);
}
if (pulse?.overview) {
const o = pulse.overview;
lines.push(`Platform 24h: ${n(o.requests24h)} requests, ${n(o.tokens24h)} tokens, ${n(o.modelsServed)} models served, ${n(o.nodesOnline)} nodes online, ${n(o.gpusOnline)} GPUs, ${n(o.regions)} regions, ${n(o.uptimePct, 2)}% uptime.`);
}
if (stats && !stats.unavailable) {
const models = Object.keys(stats.by_model || {});
lines.push(`Enso router (24h): cost saved ${n(stats.cost.saved_pct, 1)}% vs premium (baseline ${stats.cost.baseline_model || '—'}), reward rate ${n(stats.quality.reward_rate * 100)}%, engine share ${n(stats.quality.engine_share * 100)}%, avg confidence ${n(stats.quality.avg_confidence * 100)}%${models.length ? `. Models routed: ${models.join(', ')}` : ''}.`);
}
if (enso?.ledger?.available) {
const l = enso.ledger;
lines.push(`Enso flywheel: ${n(l.total)} routing decisions, ${n(l.enginePct)}% engine-routed (${n(l.heuristic)} heuristic), ${n(l.rewarded)} rewarded, avg confidence ${n(l.avgConfidence, 2)}${l.models?.length ? `. Top models: ${l.models.slice(0, 4).map((m) => `${m.name} ${m.count}`).join(', ')}` : ''}.`);
}
if (bill) {
const bal = bill.balance ? `, $${n(bill.balance.balance / 100, 2)} balance` : '';
lines.push(`Your billing: $${n(bill.spend30dCents / 100, 2)} spend/30d${bal}, ${bill.usage?.length ?? 0} billable events.`);
}
return lines.length ? 'HANZO CLOUD (live):\n' + lines.join('\n') : '';
}
async function topHeadlines(): Promise<string> {
try {
const r = await fetchWithTimeout('/v1/world/gdelt-doc?query=world&maxrecords=8', {}, SNAPSHOT_TIMEOUT_MS);