mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-26 02:04:37 +08:00
fix(semantic-index): return global Response from proxied model downloads
When a model download proxy is configured, createProxyFetch() returned the Response from undici's own fetch, which is not the global Response. Transformers.js only writes `instanceof Response` results to its file cache, so the ONNX weights were never cached and preload failed with "Unable to get model file path or buffer." Keep undici's fetch and ProxyAgent, and re-wrap the response body stream in a global Response. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
1 parent
eadadda071
commit
79117ebf0c
2 files changed
+47
-2
No files matched your search
@@ -52,9 +52,16 @@ export async function createProxyFetch(proxyUrl: string): Promise<typeof fetch>
|
||||
}
|
||||
const { fetch: undiciFetch, ProxyAgent } = await import('undici')
|
||||
const dispatcher = new ProxyAgent(proxyUrl)
|
||||
return ((input, init) => {
|
||||
return (async (input, init) => {
|
||||
const nextInit: UndiciRequestInit = { ...(init as UndiciRequestInit | undefined), dispatcher }
|
||||
return undiciFetch(input as Parameters<UndiciFetch>[0], nextInit) as unknown as ReturnType<typeof fetch>
|
||||
const response = await undiciFetch(input as Parameters<UndiciFetch>[0], nextInit)
|
||||
// Transformers.js only caches model files for `instanceof Response`; undici's own Response
|
||||
// class fails that check, so re-wrap the stream in a global Response.
|
||||
return new Response(response.body as ReadableStream<Uint8Array> | null, {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: response.headers as unknown as HeadersInit,
|
||||
})
|
||||
}) as typeof fetch
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import http from 'node:http'
|
||||
import net, { type AddressInfo } from 'node:net'
|
||||
import test from 'node:test'
|
||||
import {
|
||||
createProxyFetch,
|
||||
@@ -100,6 +102,42 @@ test('local model download proxy rejects SOCKS URLs explicitly', async () => {
|
||||
await assert.rejects(() => createProxyFetch('socks5://127.0.0.1:1080'), /SOCKS proxy is not supported/)
|
||||
})
|
||||
|
||||
test('local model download proxy returns a global Response through the proxy', async (t) => {
|
||||
const target = http.createServer((_req, res) => res.end('model-bytes'))
|
||||
let proxied = 0
|
||||
const proxy = http.createServer()
|
||||
proxy.on('connect', (req, socket, head) => {
|
||||
proxied += 1
|
||||
const [host, port] = (req.url ?? '').split(':')
|
||||
const upstream = net.connect(Number(port), host, () => {
|
||||
socket.write('HTTP/1.1 200 Connection Established\r\n\r\n')
|
||||
upstream.write(head)
|
||||
upstream.pipe(socket)
|
||||
socket.pipe(upstream)
|
||||
})
|
||||
})
|
||||
const listen = (server: http.Server) =>
|
||||
new Promise<number>((resolve) =>
|
||||
server.listen(0, '127.0.0.1', () => resolve((server.address() as AddressInfo).port))
|
||||
)
|
||||
const targetPort = await listen(target)
|
||||
const proxyPort = await listen(proxy)
|
||||
t.after(() => {
|
||||
target.closeAllConnections()
|
||||
proxy.closeAllConnections()
|
||||
target.close()
|
||||
proxy.close()
|
||||
})
|
||||
|
||||
const proxyFetch = await createProxyFetch(`http://127.0.0.1:${proxyPort}`)
|
||||
const response = await proxyFetch(`http://127.0.0.1:${targetPort}/model.onnx`)
|
||||
|
||||
// Transformers.js caches model files only for `instanceof Response`; anything else fails to load
|
||||
assert.ok(response instanceof globalThis.Response)
|
||||
assert.equal(await response.text(), 'model-bytes')
|
||||
assert.equal(proxied, 1)
|
||||
})
|
||||
|
||||
test('local model download source resolves to the selected remote host', () => {
|
||||
assert.equal(resolveModelDownloadRemoteHost('huggingface'), 'https://huggingface.co/')
|
||||
assert.equal(resolveModelDownloadRemoteHost('hf-mirror'), 'https://hf-mirror.com/')
|
||||
|
||||
Reference in new issue
Block a user