fix(provider): treat a scheme-less loopback base URL as local - #837
Open
ANIRUDDHA ADAK (aniruddhaadak80) wants to merge 1 commit into
Open
ANIRUDDHA ADAK (aniruddhaadak80) wants to merge 1 commit into
ANIRUDDHA ADAK (aniruddhaadak80) wants to merge 1 commit into
Conversation
ANIRUDDHA ADAK (aniruddhaadak80)
requested review from
Aayam Bansal (aayambansal) and
Ishaan Gangwani (ishaan1124)
as code owners
September 29, 2026 17:55
|
ANIRUDDHA ADAK (@aniruddhaadak80) is attempting to deploy a commit to the InkVell Team on Vercel. A member of the Team first needs to authorize it. |
ANIRUDDHA ADAK (aniruddhaadak80)
force-pushed
the
fix/inference-schemeless-local
branch
2 times, most recently
from
September 30, 2026 09:46
d212b35 to
e4d4f3f
Compare
localhost:11434/v1 parses with the scheme localhost:, so the hostname never read as localhost and the route fell through to byok. LocalProvider.normalizeBaseURL accepts that form, so the same endpoint was local there and a cloud key here.
ANIRUDDHA ADAK (aniruddhaadak80)
force-pushed
the
fix/inference-schemeless-local
branch
from
September 30, 2026 10:18
e4d4f3f to
e695baa
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Inference.localreads the host of a base URL withnew URL(value).hostname, but a scheme-less base URL does not throw here — it parses successfully with the host absorbed as the scheme.new URL("localhost:11434/v1")is valid per the URL spec:localhost:becomes the scheme, sohostnameis the empty string and every comparison fails.Why it matters
This form is legal here and accepted everywhere else.
LocalProvider.normalizeBaseURL(src/provider/local.ts:125) explicitly prependshttp://when the scheme is missing, so the two helpers disagree on the same string:classifyis the route authority and its result is whatusage-loggingrecords, so a user's own Ollama configured the ordinary way is attributed as billable remote spend rather than local. Thehttp://localhost:11434/v1spelling of the same endpoint classifies correctly, which is why this reads as intermittent rather than systematic.Verification
The existing test only covered the
http://spelling. One new case fails before, passes after:The second new test is the guard against over-correcting:
api.openai.com/v1(also scheme-less) must staybyok, so the fix is not "treat everything schemeless as local". The local cases coverlocalhost:, a bare127.0.0.1:with a port, and an uppercaseLOCALHOST:.local-availabilityandlocal-runtimeare unaffected: 9 pass / 0 fail across the three files.The change
function local(value: unknown) { if (typeof value !== "string" || !value) return false try { - const host = new URL(value).hostname.toLowerCase().replace(/^\[|\]$/g, "") + // "localhost:11434/v1" parses with the scheme "localhost:", so the + // hostname never came out as "localhost". LocalProvider.normalizeBaseURL + // accepts a missing scheme, so this has to agree or the same endpoint + // reads as local there and as a cloud key here. + const absolute = /^https?:\/\//i.test(value) ? value : `http://${value}` + const host = new URL(absolute).hostname.toLowerCase().replace(/^\[|\]$/g, "") return host === "localhost" || host === "127.0.0.1" || host === "0.0.0.0" || host === "::1" } catch { return false } }The
try/catchstays, so a genuinely unparseable value still returnsfalserather than throwing.Touched files are Prettier-clean (verified on LF-normalized copies; this Windows checkout's
core.autocrlf=truemakes Prettier flag every file repo-wide).Fixes #836