mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-08-29 10:21:34 +00:00
fix: use matching Undici fetch for private AI providers (#1309)
Co-authored-by: Angad Singh <angad@singhangad.in>
This commit is contained in:
co-authored by
Angad Singh
parent
fa0fa7f836
commit
26757813c8
@@ -1,4 +1,4 @@
|
||||
import { getFetchDispatcher } from "../../utils/proxy-agent.js";
|
||||
import { fetchWithProxy } from "../../utils/proxy-agent.js";
|
||||
import { safeOutboundFetch } from "../../utils/safe-outbound-fetch.js";
|
||||
import { evaluateEgress, readPrivateAllowlist } from "../egress.js";
|
||||
import { AiProviderError } from "./types.js";
|
||||
@@ -9,8 +9,8 @@ import { AiProviderError } from "./types.js";
|
||||
*
|
||||
* Public hosts use safeOutboundFetch, which re-checks the resolved address at
|
||||
* connect time. Allowlisted private hosts cannot use it (its whole job is to
|
||||
* refuse them), so they fall back to plain fetch with the proxy dispatcher --
|
||||
* still respecting corporate proxy configuration.
|
||||
* refuse them), so they use the installed Undici fetch implementation with
|
||||
* its matching proxy dispatcher -- still respecting proxy configuration.
|
||||
*/
|
||||
export async function providerFetch(
|
||||
url: string,
|
||||
@@ -24,10 +24,7 @@ export async function providerFetch(
|
||||
}
|
||||
|
||||
if (decision.isPrivate) {
|
||||
return fetch(url, {
|
||||
...init,
|
||||
dispatcher: getFetchDispatcher(url),
|
||||
} as RequestInit);
|
||||
return fetchWithProxy(url, init);
|
||||
}
|
||||
|
||||
return safeOutboundFetch(url, init) as unknown as Promise<Response>;
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const fetchWithProxy = vi.fn();
|
||||
const getFetchDispatcher = vi.fn();
|
||||
const safeOutboundFetch = vi.fn();
|
||||
const readPrivateAllowlist = vi.fn();
|
||||
const evaluateEgress = vi.fn();
|
||||
const globalFetch = vi.fn();
|
||||
|
||||
vi.mock("../../utils/proxy-agent.js", () => ({
|
||||
fetchWithProxy,
|
||||
getFetchDispatcher,
|
||||
}));
|
||||
vi.mock("../../utils/safe-outbound-fetch.js", () => ({ safeOutboundFetch }));
|
||||
vi.mock("../../ai/egress.js", () => ({
|
||||
readPrivateAllowlist,
|
||||
evaluateEgress,
|
||||
}));
|
||||
|
||||
const { providerFetch } = await import("../../ai/providers/http.js");
|
||||
|
||||
describe("providerFetch", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
vi.stubGlobal("fetch", globalFetch);
|
||||
readPrivateAllowlist.mockResolvedValue(["192.168.1.50"]);
|
||||
});
|
||||
|
||||
it("uses the matching Undici fetch implementation for private providers", async () => {
|
||||
const response = { ok: true, status: 200 } as Response;
|
||||
const init = { method: "GET" };
|
||||
evaluateEgress.mockReturnValue({ allowed: true, isPrivate: true });
|
||||
fetchWithProxy.mockResolvedValue(response);
|
||||
|
||||
await expect(
|
||||
providerFetch("http://192.168.1.50:11434/api/tags", init),
|
||||
).resolves.toBe(response);
|
||||
|
||||
expect(fetchWithProxy).toHaveBeenCalledWith(
|
||||
"http://192.168.1.50:11434/api/tags",
|
||||
init,
|
||||
);
|
||||
expect(globalFetch).not.toHaveBeenCalled();
|
||||
expect(safeOutboundFetch).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user