Report the owner's model and index on a mirror's Monitor card
A mirror was probing an Ollama it does not have and an index it never builds, so the card read "unreachable / not built" about the wrong machine while the model it actually uses was up. The card now names whose figures it is showing.
This commit is contained in:
@@ -547,7 +547,64 @@ function vv_ai_recent_logs(int $max = 40): array {
|
||||
return $out;
|
||||
}
|
||||
|
||||
// The figures every AI surface draws: the banner, the Scheduler dock and the Monitor card.
|
||||
//
|
||||
// On a mirror these describe the owner, because on a mirror there is nothing local to describe.
|
||||
// Collected locally it probed an Ollama that is not installed and an index that is never built,
|
||||
// and the Monitor card said "Ollama unreachable / Index not built" — both true of that box and
|
||||
// both the wrong question, since the model it actually uses was up the whole time.
|
||||
//
|
||||
// Routed here rather than in the cache writer so that every consumer follows. api/ai.php already
|
||||
// sends the stats *action* to the owner, so the tab was right while the card was wrong; this is
|
||||
// what makes the two agree.
|
||||
function vv_ai_stats(): array {
|
||||
return vv_ai_is_owner() ? vv_ai_stats_local() : vv_ai_stats_shared();
|
||||
}
|
||||
|
||||
// What the owner reports about itself, fetched once and cached by the caller. A transport failure
|
||||
// is reported as a failed health check rather than as absent hardware: "cannot reach the owner"
|
||||
// and "the owner has no model" are different faults with different fixes, and the local-collection
|
||||
// version could only ever express the second one.
|
||||
function vv_ai_stats_shared(): array {
|
||||
require_once __DIR__ . '/ai_rpc.php';
|
||||
|
||||
$status = 200;
|
||||
$owner = vv_ai_owner_host();
|
||||
$name = trim((string)(vv_conf_vars()[strtoupper($owner)] ?? $owner));
|
||||
$r = vv_ai_rpc('stats', [], false, $status);
|
||||
|
||||
if (($r['ok'] ?? false) && is_array($r['stats'] ?? null)) {
|
||||
$stats = $r['stats'];
|
||||
$stats['served_by'] = $name; // so a surface can say whose numbers these are
|
||||
return $stats;
|
||||
}
|
||||
|
||||
$why = (string)($r['error'] ?? 'no response from the AI owner');
|
||||
return [
|
||||
'enabled' => vv_ai_enabled(),
|
||||
'model' => '',
|
||||
'embed_model' => '',
|
||||
'url' => '',
|
||||
'k' => 0,
|
||||
'served_by' => $name,
|
||||
// Shapes kept identical to the local collection. The Monitor card reads runtime.reachable
|
||||
// and index.exists directly, and a missing key there renders as a broken card rather than
|
||||
// as the outage it is.
|
||||
'index' => ['exists' => false, 'chunks' => 0, 'stale' => false],
|
||||
'runtime' => ['reachable' => false, 'loaded' => false, 'offload_pct' => null],
|
||||
'loaded' => null,
|
||||
'health' => [[
|
||||
'id' => 'owner',
|
||||
'label' => 'AI owner',
|
||||
'state' => 'bad',
|
||||
'detail' => $why,
|
||||
'fix' => "Check that $name is up and that this node's SSH key still reaches it",
|
||||
]],
|
||||
'ts' => time(),
|
||||
];
|
||||
}
|
||||
|
||||
function vv_ai_stats_local(): array {
|
||||
$cfg = vv_ai_config();
|
||||
return [
|
||||
'enabled' => $cfg['enabled'],
|
||||
@@ -596,6 +653,10 @@ function vv_ai_stats_cached(bool $live = false): array {
|
||||
function vv_ai_monitor_block(array $stats): array {
|
||||
return [
|
||||
'model' => $stats['model'] ?? '',
|
||||
// Empty on the owner, the owner's hostname on a mirror. The card draws a model and an
|
||||
// index that live on another machine, and a dashboard that shows one node's figures under
|
||||
// another node's heading is the kind of quiet wrongness this project keeps finding.
|
||||
'served_by' => $stats['served_by'] ?? '',
|
||||
'runtime' => $stats['runtime'] ?? [],
|
||||
'index' => $stats['index'] ?? [],
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user