Declare the AI owner, and let every node borrow its model over the mesh
vv_is_ai_host() was `=== 'host1'`, which made a physical fact — that is where the GPU is — look like a rule. AI_OWNER_HOST declares it, so the card can move to a rebuilt host3 or a friend's spare. The gate was also doing two jobs. Assistant docks and findings strips now ask whether a model is reachable, so a node without a GPU gets them by borrowing; the AI tab asks whether this is the owner, because that page carries the bug reports, the index and the model configuration — the surface where the vocabulary assumes you built the mesh. Resolution is local, then owner, then anyone else declaring a model, pinned once it answers. Pinned rather than re-derived per call: a mesh that re-decides every request eventually decides differently mid-conversation, and a chat whose second turn lands on another machine has no history there. Cleared only on a transport failure, and only when there is somewhere else to go — a single-node mesh whose model is down should say so, not report AI as unconfigured.
This commit is contained in:
@@ -214,11 +214,33 @@ function vv_ai_config(): array {
|
||||
if ($cfg !== null) return $cfg;
|
||||
|
||||
$vars = vv_conf_vars();
|
||||
$host = strtoupper(vv_detect_host());
|
||||
// The node whose model this one uses — itself if it has one, the owner's otherwise. Was
|
||||
// vv_detect_host(), which meant a node without a GPU had no AI rather than borrowing one.
|
||||
$modelHost = vv_ai_model_host();
|
||||
$host = strtoupper($modelHost);
|
||||
|
||||
// Borrowed models are reached by hostname, not by the owner's own loopback. HOST1_OLLAMA_URL
|
||||
// is http://localhost:11434, which is true on host1 and points at nothing anywhere else, so a
|
||||
// remote borrower substitutes the owner's Tailscale name — the mesh resolves those and there
|
||||
// are no hardcoded IPs anywhere in this project.
|
||||
//
|
||||
// The owner keeps loopback for its own calls. Rewriting it for everyone would push host1's own
|
||||
// traffic onto the tailnet interface and make local AI depend on Tailscale being up, which is
|
||||
// a real dependency to add for no gain.
|
||||
$rawUrl = rtrim(trim($vars["{$host}_OLLAMA_URL"] ?? ''), '/');
|
||||
if ($modelHost !== vv_detect_host() && $rawUrl !== '') {
|
||||
$ownerName = trim((string)($vars[strtoupper($modelHost)] ?? ''));
|
||||
if ($ownerName !== '') {
|
||||
$rawUrl = preg_replace('#://(localhost|127\.0\.0\.1)([:/]|$)#i',
|
||||
'://' . $ownerName . '$2', $rawUrl);
|
||||
}
|
||||
}
|
||||
|
||||
$cfg = [
|
||||
'enabled' => strtolower(trim($vars['AI_ENABLED'] ?? 'false')) === 'true',
|
||||
'url' => rtrim(trim($vars["{$host}_OLLAMA_URL"] ?? ''), '/'),
|
||||
'url' => $rawUrl,
|
||||
'model_host' => $modelHost,
|
||||
'borrowed' => $modelHost !== vv_detect_host(),
|
||||
'model' => trim($vars["{$host}_OLLAMA_MODEL"] ?? ''),
|
||||
'embed_model' => trim($vars["{$host}_OLLAMA_EMBED_MODEL"] ?? 'nomic-embed-text'),
|
||||
'db' => trim($vars['AI_INDEX_DB'] ?? '') ?: AI_DATA_DIR . '/ai_index.db',
|
||||
|
||||
Reference in New Issue
Block a user