@infersec/conduit 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{start-BS3RcUet.js → start-CQayYNYZ.js} +170 -32
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ const __dirname = __pathDirname(__filename);
|
|
|
6
6
|
|
|
7
7
|
import { parseArgs } from 'node:util';
|
|
8
8
|
import 'node:crypto';
|
|
9
|
-
import { a as asError, s as startInferenceAgent } from './start-
|
|
9
|
+
import { a as asError, s as startInferenceAgent } from './start-CQayYNYZ.js';
|
|
10
10
|
import 'argon2';
|
|
11
11
|
import 'node:child_process';
|
|
12
12
|
import 'node:stream';
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const __filename = __fileURLToPath(import.meta.url);
|
|
|
5
5
|
const __dirname = __pathDirname(__filename);
|
|
6
6
|
|
|
7
7
|
import 'node:crypto';
|
|
8
|
-
import { s as startInferenceAgent, a as asError } from './start-
|
|
8
|
+
import { s as startInferenceAgent, a as asError } from './start-CQayYNYZ.js';
|
|
9
9
|
import 'argon2';
|
|
10
10
|
import 'node:child_process';
|
|
11
11
|
import 'node:stream';
|
|
@@ -31,7 +31,7 @@ import require$$1$5, { fileURLToPath } from 'node:url';
|
|
|
31
31
|
import require$$1$6 from 'node:async_hooks';
|
|
32
32
|
import require$$1$7 from 'node:console';
|
|
33
33
|
import require$$0$b, { mkdir, readFile, writeFile, stat, unlink, rename, realpath, readlink, readdir, lstat } from 'node:fs/promises';
|
|
34
|
-
import path$1, {
|
|
34
|
+
import path$1, { join, dirname, win32, posix } from 'node:path';
|
|
35
35
|
import require$$1$8 from 'node:dns';
|
|
36
36
|
import require$$2$4 from 'node:sqlite';
|
|
37
37
|
import require$$0$c from 'path';
|
|
@@ -96521,7 +96521,9 @@ async function downloadModelViaHuggingFace({ format, huggingFaceToken, modelSlug
|
|
|
96521
96521
|
modelSlug,
|
|
96522
96522
|
revision
|
|
96523
96523
|
});
|
|
96524
|
-
|
|
96524
|
+
const { partialPath } = getDownloadPaths({ filePath: file.path, targetDirectory });
|
|
96525
|
+
const shouldAttemptRange = rangeInfo.supportsRanges || existsSync(partialPath);
|
|
96526
|
+
if (shouldAttemptRange) {
|
|
96525
96527
|
try {
|
|
96526
96528
|
await downloadFileWithRange({
|
|
96527
96529
|
accessToken,
|
|
@@ -96571,6 +96573,12 @@ function encodePathSegments(path) {
|
|
|
96571
96573
|
.map(segment => encodeURIComponent(segment))
|
|
96572
96574
|
.join("/");
|
|
96573
96575
|
}
|
|
96576
|
+
function encodeRepoSlug(modelSlug) {
|
|
96577
|
+
return modelSlug
|
|
96578
|
+
.split("/")
|
|
96579
|
+
.map(segment => encodeURIComponent(segment))
|
|
96580
|
+
.join("/");
|
|
96581
|
+
}
|
|
96574
96582
|
function parseModelRevision(modelSlugWithRevision) {
|
|
96575
96583
|
const revisionIndex = modelSlugWithRevision.indexOf("@");
|
|
96576
96584
|
if (revisionIndex === -1) {
|
|
@@ -96589,11 +96597,17 @@ function getDownloadPaths({ filePath, targetDirectory }) {
|
|
|
96589
96597
|
};
|
|
96590
96598
|
}
|
|
96591
96599
|
function getResolveURL({ filePath, modelSlug, revision }) {
|
|
96592
|
-
const encodedRepo =
|
|
96600
|
+
const encodedRepo = encodeRepoSlug(modelSlug);
|
|
96593
96601
|
const encodedRevision = encodeURIComponent(revision);
|
|
96594
96602
|
const encodedPath = encodePathSegments(filePath);
|
|
96595
96603
|
return `https://huggingface.co/${encodedRepo}/resolve/${encodedRevision}/${encodedPath}`;
|
|
96596
96604
|
}
|
|
96605
|
+
function getResolveDownloadURL({ filePath, modelSlug, revision }) {
|
|
96606
|
+
const baseUrl = getResolveURL({ filePath, modelSlug, revision });
|
|
96607
|
+
const resolvedUrl = new URL(baseUrl);
|
|
96608
|
+
resolvedUrl.searchParams.set("download", "1");
|
|
96609
|
+
return resolvedUrl.toString();
|
|
96610
|
+
}
|
|
96597
96611
|
class RangeNotSupportedError extends Error {
|
|
96598
96612
|
constructor(message) {
|
|
96599
96613
|
super(message);
|
|
@@ -96608,39 +96622,128 @@ function getAuthHeaders(accessToken) {
|
|
|
96608
96622
|
Authorization: `Bearer ${accessToken}`
|
|
96609
96623
|
};
|
|
96610
96624
|
}
|
|
96611
|
-
|
|
96612
|
-
|
|
96625
|
+
function shouldSendAuthHeader(url) {
|
|
96626
|
+
try {
|
|
96627
|
+
const hostname = new URL(url).hostname.toLowerCase();
|
|
96628
|
+
return hostname.endsWith("huggingface.co") || hostname.endsWith("hf.co");
|
|
96629
|
+
}
|
|
96630
|
+
catch {
|
|
96631
|
+
return false;
|
|
96632
|
+
}
|
|
96633
|
+
}
|
|
96634
|
+
function parseContentRangeTotal(contentRange) {
|
|
96635
|
+
if (!contentRange) {
|
|
96636
|
+
return null;
|
|
96637
|
+
}
|
|
96638
|
+
const totalMatch = /\/(\d+)$/.exec(contentRange);
|
|
96639
|
+
if (!totalMatch) {
|
|
96640
|
+
return null;
|
|
96641
|
+
}
|
|
96642
|
+
const totalSize = Number(totalMatch[1]);
|
|
96643
|
+
return Number.isFinite(totalSize) ? totalSize : null;
|
|
96644
|
+
}
|
|
96645
|
+
async function getDownloadURL({ accessToken, filePath, modelSlug, revision }) {
|
|
96646
|
+
const url = getResolveDownloadURL({ filePath, modelSlug, revision });
|
|
96613
96647
|
try {
|
|
96614
96648
|
const response = await undiciExports.fetch(url, {
|
|
96615
|
-
method: "
|
|
96649
|
+
method: "GET",
|
|
96650
|
+
redirect: "manual",
|
|
96616
96651
|
headers: getAuthHeaders(accessToken)
|
|
96617
96652
|
});
|
|
96618
|
-
|
|
96653
|
+
try {
|
|
96654
|
+
if (response.status >= 300 && response.status < 400) {
|
|
96655
|
+
const location = response.headers.get("location");
|
|
96656
|
+
if (location) {
|
|
96657
|
+
return { reason: null, status: response.status, url: location };
|
|
96658
|
+
}
|
|
96659
|
+
}
|
|
96660
|
+
if (response.ok) {
|
|
96661
|
+
return { reason: null, status: response.status, url: response.url };
|
|
96662
|
+
}
|
|
96663
|
+
let responseBody = "<unavailable>";
|
|
96664
|
+
try {
|
|
96665
|
+
responseBody = await response.text();
|
|
96666
|
+
}
|
|
96667
|
+
catch {
|
|
96668
|
+
responseBody = "<failed to read body>";
|
|
96669
|
+
}
|
|
96670
|
+
if (responseBody.length > 2000) {
|
|
96671
|
+
responseBody = responseBody.slice(0, 2000);
|
|
96672
|
+
}
|
|
96673
|
+
console.warn(`Resolve request failed body for ${filePath}: ${responseBody}`);
|
|
96619
96674
|
return {
|
|
96620
|
-
reason: `
|
|
96621
|
-
|
|
96622
|
-
|
|
96675
|
+
reason: `Resolve request failed with status ${response.status}`,
|
|
96676
|
+
status: response.status,
|
|
96677
|
+
url: null
|
|
96623
96678
|
};
|
|
96624
96679
|
}
|
|
96625
|
-
|
|
96626
|
-
|
|
96627
|
-
|
|
96680
|
+
finally {
|
|
96681
|
+
if (response.body && response.bodyUsed === false && response.body.locked === false) {
|
|
96682
|
+
await response.body.cancel();
|
|
96683
|
+
}
|
|
96684
|
+
}
|
|
96685
|
+
}
|
|
96686
|
+
catch (error) {
|
|
96687
|
+
const parsed = asError(error);
|
|
96688
|
+
return {
|
|
96689
|
+
reason: `Resolve request failed: ${parsed.message}`,
|
|
96690
|
+
status: null,
|
|
96691
|
+
url: null
|
|
96692
|
+
};
|
|
96693
|
+
}
|
|
96694
|
+
}
|
|
96695
|
+
async function getRangeInfo({ accessToken, filePath, fileSize, modelSlug, revision }) {
|
|
96696
|
+
const downloadUrlInfo = await getDownloadURL({
|
|
96697
|
+
accessToken,
|
|
96698
|
+
filePath,
|
|
96699
|
+
modelSlug,
|
|
96700
|
+
revision
|
|
96701
|
+
});
|
|
96702
|
+
if (!downloadUrlInfo.url) {
|
|
96703
|
+
return {
|
|
96704
|
+
reason: downloadUrlInfo.reason ?? "Resolve request failed",
|
|
96705
|
+
supportsRanges: false,
|
|
96706
|
+
totalSize: fileSize
|
|
96707
|
+
};
|
|
96708
|
+
}
|
|
96709
|
+
try {
|
|
96710
|
+
const response = await undiciExports.fetch(downloadUrlInfo.url, {
|
|
96711
|
+
method: "GET",
|
|
96712
|
+
headers: {
|
|
96713
|
+
...(shouldSendAuthHeader(downloadUrlInfo.url) ? getAuthHeaders(accessToken) : {}),
|
|
96714
|
+
Range: "bytes=0-0"
|
|
96715
|
+
}
|
|
96716
|
+
});
|
|
96717
|
+
try {
|
|
96718
|
+
if (response.status === 206) {
|
|
96719
|
+
const totalSize = parseContentRangeTotal(response.headers.get("content-range"));
|
|
96720
|
+
return {
|
|
96721
|
+
reason: null,
|
|
96722
|
+
supportsRanges: true,
|
|
96723
|
+
totalSize: totalSize ?? fileSize
|
|
96724
|
+
};
|
|
96725
|
+
}
|
|
96726
|
+
if (response.status === 200) {
|
|
96727
|
+
return {
|
|
96728
|
+
reason: "Server returned 200 to range probe",
|
|
96729
|
+
supportsRanges: false,
|
|
96730
|
+
totalSize: fileSize
|
|
96731
|
+
};
|
|
96732
|
+
}
|
|
96628
96733
|
return {
|
|
96629
|
-
reason:
|
|
96734
|
+
reason: `Range probe failed with status ${response.status}`,
|
|
96630
96735
|
supportsRanges: false,
|
|
96631
|
-
totalSize:
|
|
96736
|
+
totalSize: fileSize
|
|
96632
96737
|
};
|
|
96633
96738
|
}
|
|
96634
|
-
|
|
96635
|
-
|
|
96636
|
-
|
|
96637
|
-
totalSize: Number.isFinite(totalSize) ? totalSize : fileSize
|
|
96638
|
-
};
|
|
96739
|
+
finally {
|
|
96740
|
+
await response.body?.cancel();
|
|
96741
|
+
}
|
|
96639
96742
|
}
|
|
96640
96743
|
catch (error) {
|
|
96641
96744
|
const parsed = asError(error);
|
|
96642
96745
|
return {
|
|
96643
|
-
reason: `
|
|
96746
|
+
reason: `Range probe failed: ${parsed.message}`,
|
|
96644
96747
|
supportsRanges: false,
|
|
96645
96748
|
totalSize: fileSize
|
|
96646
96749
|
};
|
|
@@ -96670,6 +96773,14 @@ async function downloadFileFull({ accessToken, filePath, fileSize, modelSlug, ta
|
|
|
96670
96773
|
let progressTimeout = null;
|
|
96671
96774
|
let lastPercentage = "0.0";
|
|
96672
96775
|
let lastProgressBytes = 0;
|
|
96776
|
+
const resetProgressTimeout = () => {
|
|
96777
|
+
clearTimeout(progressTimeout);
|
|
96778
|
+
progressTimeout = setTimeout(() => {
|
|
96779
|
+
input.destroy(new Error(`Timed out with no progress for ${DOWNLOAD_PROGRESS_TIMEOUT}ms while downloading ${filePath}. Last progress: ${lastPercentage}% (${lastProgressBytes} / ${fileSize})`));
|
|
96780
|
+
}, DOWNLOAD_PROGRESS_TIMEOUT);
|
|
96781
|
+
};
|
|
96782
|
+
input.on("data", resetProgressTimeout);
|
|
96783
|
+
resetProgressTimeout();
|
|
96673
96784
|
meter.progress.on("progress", (totalBytes) => {
|
|
96674
96785
|
lastProgressBytes = totalBytes;
|
|
96675
96786
|
const percentComplete = ((totalBytes / fileSize) * 100).toFixed(1);
|
|
@@ -96677,10 +96788,6 @@ async function downloadFileFull({ accessToken, filePath, fileSize, modelSlug, ta
|
|
|
96677
96788
|
console.log(` => ${percentComplete}% (${totalBytes} / ${fileSize})`);
|
|
96678
96789
|
}
|
|
96679
96790
|
lastPercentage = percentComplete;
|
|
96680
|
-
clearTimeout(progressTimeout);
|
|
96681
|
-
progressTimeout = setTimeout(() => {
|
|
96682
|
-
input.destroy(new Error(`Timed out with no progress for ${DOWNLOAD_PROGRESS_TIMEOUT}ms while downloading ${filePath}. Last progress: ${lastPercentage}% (${lastProgressBytes} / ${fileSize})`));
|
|
96683
|
-
}, DOWNLOAD_PROGRESS_TIMEOUT);
|
|
96684
96791
|
});
|
|
96685
96792
|
try {
|
|
96686
96793
|
await pipeline(input, meter, output);
|
|
@@ -96704,7 +96811,6 @@ async function downloadFileFull({ accessToken, filePath, fileSize, modelSlug, ta
|
|
|
96704
96811
|
}
|
|
96705
96812
|
async function downloadFileWithRange({ accessToken, filePath, fileSize, modelSlug, revision, targetDirectory }) {
|
|
96706
96813
|
const { finalPath, partialPath } = getDownloadPaths({ filePath, targetDirectory });
|
|
96707
|
-
const url = getResolveURL({ filePath, modelSlug, revision });
|
|
96708
96814
|
let lastError = null;
|
|
96709
96815
|
for (let attempt = 1; attempt <= DOWNLOAD_RETRY_ATTEMPTS_RANGE; attempt++) {
|
|
96710
96816
|
let startOffset = 0;
|
|
@@ -96724,13 +96830,38 @@ async function downloadFileWithRange({ accessToken, filePath, fileSize, modelSlu
|
|
|
96724
96830
|
const resumeLabel = startOffset > 0 ? `resuming at ${startOffset}` : "starting";
|
|
96725
96831
|
console.log("Downloading:", filePath, fileSize, `(attempt ${attempt}, ${resumeLabel})`);
|
|
96726
96832
|
await mkdir(dirname(finalPath), { recursive: true });
|
|
96727
|
-
const
|
|
96833
|
+
const downloadUrlInfo = await getDownloadURL({
|
|
96834
|
+
accessToken,
|
|
96835
|
+
filePath,
|
|
96836
|
+
modelSlug,
|
|
96837
|
+
revision
|
|
96838
|
+
});
|
|
96839
|
+
if (!downloadUrlInfo.url) {
|
|
96840
|
+
if (downloadUrlInfo.status === 400) {
|
|
96841
|
+
throw new RangeNotSupportedError(downloadUrlInfo.reason ?? "Resolve request failed");
|
|
96842
|
+
}
|
|
96843
|
+
throw new Error(downloadUrlInfo.reason ?? "Resolve request failed");
|
|
96844
|
+
}
|
|
96845
|
+
const response = await undiciExports.fetch(downloadUrlInfo.url, {
|
|
96728
96846
|
headers: {
|
|
96729
|
-
...
|
|
96847
|
+
...(shouldSendAuthHeader(downloadUrlInfo.url)
|
|
96848
|
+
? getAuthHeaders(accessToken)
|
|
96849
|
+
: {}),
|
|
96730
96850
|
Range: `bytes=${startOffset}-`
|
|
96731
96851
|
}
|
|
96732
96852
|
});
|
|
96733
96853
|
if (!response.ok) {
|
|
96854
|
+
let responseBody = "<unavailable>";
|
|
96855
|
+
try {
|
|
96856
|
+
responseBody = await response.text();
|
|
96857
|
+
}
|
|
96858
|
+
catch {
|
|
96859
|
+
responseBody = "<failed to read body>";
|
|
96860
|
+
}
|
|
96861
|
+
if (responseBody.length > 2000) {
|
|
96862
|
+
responseBody = responseBody.slice(0, 2000);
|
|
96863
|
+
}
|
|
96864
|
+
console.warn(`Range request failed response body for ${filePath}: ${responseBody}`);
|
|
96734
96865
|
throw new Error(`Range request failed with status ${response.status} for ${filePath}`);
|
|
96735
96866
|
}
|
|
96736
96867
|
if (startOffset > 0 && response.status !== 206) {
|
|
@@ -96745,6 +96876,14 @@ async function downloadFileWithRange({ accessToken, filePath, fileSize, modelSlu
|
|
|
96745
96876
|
let progressTimeout = null;
|
|
96746
96877
|
let lastPercentage = ((startOffset / fileSize) * 100).toFixed(1);
|
|
96747
96878
|
let lastProgressBytes = startOffset;
|
|
96879
|
+
const resetProgressTimeout = () => {
|
|
96880
|
+
clearTimeout(progressTimeout);
|
|
96881
|
+
progressTimeout = setTimeout(() => {
|
|
96882
|
+
input.destroy(new Error(`Timed out with no progress for ${DOWNLOAD_PROGRESS_TIMEOUT}ms while downloading ${filePath}. Last progress: ${lastPercentage}% (${lastProgressBytes} / ${fileSize})`));
|
|
96883
|
+
}, DOWNLOAD_PROGRESS_TIMEOUT);
|
|
96884
|
+
};
|
|
96885
|
+
input.on("data", resetProgressTimeout);
|
|
96886
|
+
resetProgressTimeout();
|
|
96748
96887
|
meter.progress.on("progress", (totalBytes) => {
|
|
96749
96888
|
lastProgressBytes = startOffset + totalBytes;
|
|
96750
96889
|
const percentComplete = ((lastProgressBytes / fileSize) * 100).toFixed(1);
|
|
@@ -96752,10 +96891,6 @@ async function downloadFileWithRange({ accessToken, filePath, fileSize, modelSlu
|
|
|
96752
96891
|
console.log(` => ${percentComplete}% (${lastProgressBytes} / ${fileSize})`);
|
|
96753
96892
|
}
|
|
96754
96893
|
lastPercentage = percentComplete;
|
|
96755
|
-
clearTimeout(progressTimeout);
|
|
96756
|
-
progressTimeout = setTimeout(() => {
|
|
96757
|
-
input.destroy(new Error(`Timed out with no progress for ${DOWNLOAD_PROGRESS_TIMEOUT}ms while downloading ${filePath}. Last progress: ${lastPercentage}% (${lastProgressBytes} / ${fileSize})`));
|
|
96758
|
-
}, DOWNLOAD_PROGRESS_TIMEOUT);
|
|
96759
96894
|
});
|
|
96760
96895
|
try {
|
|
96761
96896
|
await pipeline(input, meter, output);
|
|
@@ -96772,6 +96907,9 @@ async function downloadFileWithRange({ accessToken, filePath, fileSize, modelSlu
|
|
|
96772
96907
|
}
|
|
96773
96908
|
catch (error) {
|
|
96774
96909
|
lastError = asError(error);
|
|
96910
|
+
if (lastError instanceof RangeNotSupportedError) {
|
|
96911
|
+
throw lastError;
|
|
96912
|
+
}
|
|
96775
96913
|
if (attempt < DOWNLOAD_RETRY_ATTEMPTS_RANGE) {
|
|
96776
96914
|
console.warn(`Retrying range download (${attempt}/${DOWNLOAD_RETRY_ATTEMPTS_RANGE}) for ${filePath} due to error: ${lastError.message}`);
|
|
96777
96915
|
continue;
|