@@ -86,10 +86,30 @@ async function configureSelfHostedTestProvider(params: {
|
86 | 86 | }); |
87 | 87 | } |
88 | 88 | |
| 89 | +function cancelTrackedResponse(init?: ResponseInit): { |
| 90 | +response: Response; |
| 91 | +wasCanceled: () => boolean; |
| 92 | +} { |
| 93 | +let canceled = false; |
| 94 | +const stream = new ReadableStream<Uint8Array>({ |
| 95 | +start(controller) { |
| 96 | +controller.enqueue(new TextEncoder().encode("ignored")); |
| 97 | +}, |
| 98 | +cancel() { |
| 99 | +canceled = true; |
| 100 | +}, |
| 101 | +}); |
| 102 | +return { |
| 103 | +response: new Response(stream, init), |
| 104 | +wasCanceled: () => canceled, |
| 105 | +}; |
| 106 | +} |
| 107 | + |
89 | 108 | describe("discoverOpenAICompatibleLocalModels", () => { |
90 | 109 | it("uses guarded fetch pinned to the configured self-hosted provider", async () => { |
91 | 110 | const release = vi.fn(async () => undefined); |
92 | 111 | const propsRelease = vi.fn(async () => undefined); |
| 112 | +const propsResponse = cancelTrackedResponse({ status: 404 }); |
93 | 113 | fetchWithSsrFGuardMock.mockResolvedValueOnce({ |
94 | 114 | response: new Response(JSON.stringify({ data: [{ id: "Qwen/Qwen3-32B" }] }), { |
95 | 115 | status: 200, |
@@ -98,7 +118,7 @@ describe("discoverOpenAICompatibleLocalModels", () => {
|
98 | 118 | release, |
99 | 119 | }); |
100 | 120 | fetchWithSsrFGuardMock.mockResolvedValueOnce({ |
101 | | -response: new Response("{}", { status: 404 }), |
| 121 | +response: propsResponse.response, |
102 | 122 | finalUrl: "http://127.0.0.1:8000/props", |
103 | 123 | release: propsRelease, |
104 | 124 | }); |
@@ -141,6 +161,28 @@ describe("discoverOpenAICompatibleLocalModels", () => {
|
141 | 161 | }); |
142 | 162 | expect(release).toHaveBeenCalledOnce(); |
143 | 163 | expect(propsRelease).toHaveBeenCalledOnce(); |
| 164 | +expect(propsResponse.wasCanceled()).toBe(true); |
| 165 | +}); |
| 166 | + |
| 167 | +it("cancels model discovery error bodies before falling back", async () => { |
| 168 | +const release = vi.fn(async () => undefined); |
| 169 | +const response = cancelTrackedResponse({ status: 503, statusText: "Service Unavailable" }); |
| 170 | +fetchWithSsrFGuardMock.mockResolvedValueOnce({ |
| 171 | +response: response.response, |
| 172 | +finalUrl: "http://127.0.0.1:8000/v1/models", |
| 173 | + release, |
| 174 | +}); |
| 175 | + |
| 176 | +const models = await discoverOpenAICompatibleLocalModels({ |
| 177 | +baseUrl: "http://127.0.0.1:8000/v1/", |
| 178 | +apiKey: "self-hosted-test-key", |
| 179 | +label: "vLLM", |
| 180 | +env: {}, |
| 181 | +}); |
| 182 | + |
| 183 | +expect(models).toEqual([]); |
| 184 | +expect(release).toHaveBeenCalledOnce(); |
| 185 | +expect(response.wasCanceled()).toBe(true); |
144 | 186 | }); |
145 | 187 | |
146 | 188 | it("uses llama.cpp nested /props n_ctx as the runtime context cap", async () => { |
|