@infersec/conduit 1.5.2 → 1.5.3

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 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-B9UMbDDZ.js';
9
+ import { a as asError, s as startInferenceAgent } from './start-C7RTzXTv.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-B9UMbDDZ.js';
8
+ import { s as startInferenceAgent, a as asError } from './start-C7RTzXTv.js';
9
9
  import 'argon2';
10
10
  import 'node:child_process';
11
11
  import 'node:stream';
@@ -94890,7 +94890,8 @@ const ModelDownloadProgressSchema = object({
94890
94890
  completedFiles: array(string().min(1))
94891
94891
  });
94892
94892
 
94893
- const DOWNLOAD_PROGRESS_TIMEOUT = 15000;
94893
+ const DOWNLOAD_PROGRESS_TIMEOUT = 30000;
94894
+ const DOWNLOAD_RETRY_ATTEMPTS = 3;
94894
94895
  async function downloadModelViaHuggingFace({ format, huggingFaceToken, modelSlug: rawModelSlug, progressFilePath, targetDirectory }) {
94895
94896
  // Sanitise model ID
94896
94897
  const [modelSlug, variant = null] = rawModelSlug.split(":");
@@ -94928,37 +94929,60 @@ async function downloadModelViaHuggingFace({ format, huggingFaceToken, modelSlug
94928
94929
  console.log("Skipping due to already having completed file:", file.path, file.size);
94929
94930
  continue;
94930
94931
  }
94931
- console.log("Downloading:", file.path, file.size);
94932
- await mkdir(dirname(join(targetDirectory, file.path)), { recursive: true });
94933
- const response = await downloadFile({
94934
- accessToken,
94935
- repo: modelSlug,
94936
- path: file.path
94937
- // path: join(targetDirectory, file.path)
94938
- });
94939
- if (!response) {
94940
- throw new Error(`Requested file did not return a valid response: ${file.path}`);
94941
- }
94942
- const input = Readable.fromWeb(response.stream());
94943
- const meter = watchStreamProgress(25 * 1024 * 1024); // 25 MiB intervals
94944
- const output = createWriteStream(join(targetDirectory, file.path));
94945
- let progressTimeout = null;
94946
- let lastPercentage = "";
94947
- meter.progress.on("progress", (totalBytes) => {
94948
- const percentComplete = ((totalBytes / file.size) * 100).toFixed(1);
94949
- if (lastPercentage !== percentComplete) {
94950
- console.log(` => ${percentComplete}% (${totalBytes} / ${file.size})`);
94932
+ let downloaded = false;
94933
+ let lastError = null;
94934
+ for (let attempt = 1; attempt <= DOWNLOAD_RETRY_ATTEMPTS; attempt++) {
94935
+ try {
94936
+ console.log("Downloading:", file.path, file.size, `(attempt ${attempt})`);
94937
+ await mkdir(dirname(join(targetDirectory, file.path)), { recursive: true });
94938
+ const response = await downloadFile({
94939
+ accessToken,
94940
+ repo: modelSlug,
94941
+ path: file.path
94942
+ // path: join(targetDirectory, file.path)
94943
+ });
94944
+ if (!response) {
94945
+ throw new Error(`Requested file did not return a valid response: ${file.path}`);
94946
+ }
94947
+ const input = Readable.fromWeb(response.stream());
94948
+ const meter = watchStreamProgress(25 * 1024 * 1024); // 25 MiB intervals
94949
+ const output = createWriteStream(join(targetDirectory, file.path));
94950
+ let progressTimeout = null;
94951
+ let lastPercentage = "0.0";
94952
+ let lastProgressBytes = 0;
94953
+ meter.progress.on("progress", (totalBytes) => {
94954
+ lastProgressBytes = totalBytes;
94955
+ const percentComplete = ((totalBytes / file.size) * 100).toFixed(1);
94956
+ if (lastPercentage !== percentComplete) {
94957
+ console.log(` => ${percentComplete}% (${totalBytes} / ${file.size})`);
94958
+ }
94959
+ lastPercentage = percentComplete;
94960
+ clearTimeout(progressTimeout);
94961
+ progressTimeout = setTimeout(() => {
94962
+ input.destroy(new Error(`Timed out with no progress for ${DOWNLOAD_PROGRESS_TIMEOUT}ms while downloading ${file.path}. Last progress: ${lastPercentage}% (${lastProgressBytes} / ${file.size})`));
94963
+ }, DOWNLOAD_PROGRESS_TIMEOUT);
94964
+ });
94965
+ try {
94966
+ await pipeline(input, meter, output);
94967
+ }
94968
+ finally {
94969
+ clearTimeout(progressTimeout);
94970
+ }
94971
+ downloaded = true;
94972
+ break;
94951
94973
  }
94952
- lastPercentage = percentComplete;
94953
- clearTimeout(progressTimeout);
94954
- progressTimeout = setTimeout(() => {
94955
- input.destroy(new Error(`Timed out with no progress in: ${DOWNLOAD_PROGRESS_TIMEOUT}ms`));
94956
- }, DOWNLOAD_PROGRESS_TIMEOUT);
94957
- });
94958
- await pipeline(input, meter, output);
94959
- // const stream = Readable.fromWeb(response.stream()).pipe(createWriteStream(join(targetDirectory, file.path)));
94960
- // await finished(stream);
94961
- clearTimeout(progressTimeout);
94974
+ catch (error) {
94975
+ lastError = asError(error);
94976
+ if (attempt < DOWNLOAD_RETRY_ATTEMPTS) {
94977
+ console.warn(`Retrying download (${attempt}/${DOWNLOAD_RETRY_ATTEMPTS}) for ${file.path} due to error: ${lastError.message}`);
94978
+ continue;
94979
+ }
94980
+ }
94981
+ }
94982
+ if (!downloaded) {
94983
+ const errorMessage = `Failed downloading ${file.path} (${file.size} bytes) after ${DOWNLOAD_RETRY_ATTEMPTS} attempts. Last error: ${lastError?.message ?? "Unknown error"}`;
94984
+ throw new Error(errorMessage);
94985
+ }
94962
94986
  // Update progress
94963
94987
  progress.completedFiles.push(file.path);
94964
94988
  await writeFile(progressFilePath, JSON.stringify(progress, undefined, 4));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@infersec/conduit",
3
3
  "description": "End user conduit agent for connecting local LLMs to the cloud.",
4
- "version": "1.5.2",
4
+ "version": "1.5.3",
5
5
  "bin": {
6
6
  "infersec-conduit": "./dist/cli.js"
7
7
  },