From a646d9fc5c97a50f1ac534f7b32b16b55eb4870e Mon Sep 17 00:00:00 2001 From: "[._.]/ Adam Eivy" Date: Sun, 6 Sep 2026 04:42:24 +0000 Subject: [PATCH] fix: keep remote GPU providers selectable across host platforms --- server/lib/systemCapabilities.js | 12 ++++++++++-- server/lib/systemCapabilities.test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/server/lib/systemCapabilities.js b/server/lib/systemCapabilities.js index 9c405ebf2e..7534330736 100644 --- a/server/lib/systemCapabilities.js +++ b/server/lib/systemCapabilities.js @@ -9,6 +9,7 @@ */ import os from 'os'; +import { isLocalInstanceEndpoint } from './localEndpoint.js'; import { isAppleSilicon } from './platform.js'; import { getCudaCapability, getCudaComputeCapability } from './cudaCapability.js'; @@ -385,6 +386,13 @@ export function withHardwareCompatibility(item, capabilities, requirements) { } export function withProviderHardwareCompatibility(provider, capabilities) { + // These probes describe this PortOS host, not the machine serving a remote + // API (including a local CLI harness backed by a fleet GPU endpoint). + // Preserve requirements, but leave remote hardware unverified and selectable. + const endpoint = provider?.endpoint; + const remoteEndpoint = typeof endpoint === 'string' && URL.canParse(endpoint) + && !isLocalInstanceEndpoint(endpoint); + const runtimeCapabilities = remoteEndpoint ? null : capabilities; const hardwareRequirements = hardwareRequirementsForProvider(provider); const modelRequirementLayers = provider?.modelHardwareRequirements || {}; const modelIds = [...new Set([ @@ -398,7 +406,7 @@ export function withProviderHardwareCompatibility(provider, capabilities) { ].filter((model) => typeof model === 'string' && model))]; const modelHardwareCompatibility = Object.fromEntries(modelIds.map((model) => { const requirements = hardwareRequirementsForProviderModel(provider, model); - return [model, evaluateHardwareRequirements(requirements, capabilities)]; + return [model, evaluateHardwareRequirements(requirements, runtimeCapabilities)]; })); const hasModelRequirements = Object.values(modelHardwareCompatibility).some( (compatibility) => Object.keys(compatibility.requirements).length > 0, @@ -407,7 +415,7 @@ export function withProviderHardwareCompatibility(provider, capabilities) { return { ...provider, hardwareRequirements, - hardwareCompatibility: evaluateHardwareRequirements(hardwareRequirements, capabilities), + hardwareCompatibility: evaluateHardwareRequirements(hardwareRequirements, runtimeCapabilities), modelHardwareCompatibility, }; } diff --git a/server/lib/systemCapabilities.test.js b/server/lib/systemCapabilities.test.js index 0f885ccfc2..fc6f1c4a00 100644 --- a/server/lib/systemCapabilities.test.js +++ b/server/lib/systemCapabilities.test.js @@ -179,6 +179,32 @@ describe('systemCapabilities', () => { expect(provider.modelHardwareCompatibility.large.state).toBe('unavailable'); }); + it('keeps fleet API and TUI models selectable without applying the caller hardware', () => { + for (const type of ['api', 'tui']) { + const provider = { + id: 'fleet-gpu', + type, + command: type === 'tui' ? 'opencode' : undefined, + endpoint: 'http://gpu.example.com:18022/v1', + vllmBacked: true, + models: ['qwen3.8-27b'], + hardwareRequirements: { platforms: ['win32'] }, + modelHardwareRequirements: { 'qwen3.8-27b': { minMemoryGb: 256 } }, + }; + const remote = withProviderHardwareCompatibility(provider, APPLE_32GB); + expect(remote.hardwareCompatibility.state).toBe('unknown'); + expect(remote.modelHardwareCompatibility['qwen3.8-27b']).toMatchObject({ + state: 'unknown', + requirements: { minMemoryGb: 256, platforms: ['win32'] }, + }); + for (const endpoint of ['http://localhost:18022/v1', 'http://[::1]:18022/v1', '', undefined]) { + const local = withProviderHardwareCompatibility({ ...provider, endpoint }, APPLE_32GB); + expect(local.hardwareCompatibility.state).toBe('unavailable'); + expect(local.modelHardwareCompatibility['qwen3.8-27b'].state).toBe('unavailable'); + } + } + }); + it('retains inferred local model compatibility without provider overrides', () => { const provider = withProviderHardwareCompatibility({ id: 'ollama',