sealnet-mcp 0.2.0 → 0.2.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.cjs CHANGED
@@ -2914,7 +2914,6 @@ var upload_default = {
2914
2914
  HEDGE_MIN_INFLIGHT_MS: 3e3,
2915
2915
  HEDGE_LAG_FACTOR: 3,
2916
2916
  HEDGE_POLL_MS: 1e3,
2917
- HEDGE_MAX_CONCURRENT: 1,
2918
2917
  LIVENESS_SILENCE_MS: 3e4,
2919
2918
  RETRY_BACKOFF_MS: [1e3, 3e3, 7e3, 15e3, 3e4],
2920
2919
  RETRY_JITTER_RATIO: 0.2,
@@ -4209,7 +4208,6 @@ var DEFAULT_TRANSPORT_POLICY = {
4209
4208
  hedgeMinInflightMs: upload_default.upload.HEDGE_MIN_INFLIGHT_MS,
4210
4209
  hedgeLagFactor: upload_default.upload.HEDGE_LAG_FACTOR,
4211
4210
  hedgePollMs: upload_default.upload.HEDGE_POLL_MS,
4212
- hedgeMaxConcurrent: upload_default.upload.HEDGE_MAX_CONCURRENT,
4213
4211
  livenessSilenceMs: upload_default.upload.LIVENESS_SILENCE_MS,
4214
4212
  verifyPollBackoffMs: upload_default.upload.VERIFY_POLL_BACKOFF_MS,
4215
4213
  verifyFallbackWaitMs: upload_default.upload.VERIFY_FALLBACK_WAIT_MS,
@@ -4531,7 +4529,6 @@ async function multipartUploadStream(options) {
4531
4529
  let lastRoundRate = null;
4532
4530
  let roomWaiters = [];
4533
4531
  const fullPartPace = [];
4534
- let hedgesInFlight = 0;
4535
4532
  const partsInFlight = /* @__PURE__ */ new Set();
4536
4533
  let lastSocketActivityAt = performance.now();
4537
4534
  let socketActivityObservable = false;
@@ -4576,10 +4573,10 @@ async function multipartUploadStream(options) {
4576
4573
  roundBytes = 0;
4577
4574
  roundDeliveries = 0;
4578
4575
  }
4579
- function hedgeDue(item, lastLaunchAt, ownDuplicates) {
4576
+ function hedgeDue(item, lastLaunchAt) {
4580
4577
  const inFlightMs = performance.now() - lastLaunchAt;
4581
4578
  if (inFlightMs < policy.hedgeMinInflightMs) return false;
4582
- const flowsNow = runningParts.size + hedgesInFlight - ownDuplicates;
4579
+ const flowsNow = runningParts.size;
4583
4580
  const peers = fullPartPace.filter((p) => p.flows >= flowsNow).map((p) => p.rate);
4584
4581
  if (peers.length === 0) return false;
4585
4582
  peers.sort((a, b) => a - b);
@@ -4701,135 +4698,80 @@ async function multipartUploadStream(options) {
4701
4698
  }
4702
4699
  async function hedgedPut(item, presignedUrl) {
4703
4700
  const t0 = performance.now();
4704
- let controllers = [];
4705
- const detachFns = [];
4706
4701
  let hedgeTicker = null;
4707
4702
  let hedgeCount = 0;
4708
- let liveHedges = 0;
4709
- let currentHedge = null;
4710
4703
  let lastLaunchAt = t0;
4711
- let generation = 0;
4712
- const unsentByCopy = /* @__PURE__ */ new Map();
4713
- let reconnect = () => {
4714
- };
4715
- const launchCopy = async (isHedge) => {
4716
- const ctl = new AbortController();
4717
- controllers.push(ctl);
4718
- if (isHedge) currentHedge = ctl;
4719
- unsentByCopy.set(ctl, true);
4720
- lastSocketActivityAt = performance.now();
4721
- if (runSignal) {
4722
- if (runSignal.aborted) {
4723
- ctl.abort();
4724
- } else {
4725
- const onAbort = () => ctl.abort();
4726
- runSignal.addEventListener("abort", onAbort, { once: true });
4727
- detachFns.push(() => runSignal.removeEventListener("abort", onAbort));
4728
- }
4729
- }
4730
- try {
4731
- const outcome = await transportPut(
4732
- item.ciphertext,
4733
- item.contentMd5,
4734
- item.partNumber,
4735
- presignedUrl,
4736
- ctl.signal,
4737
- {
4738
- onSocketActivity: (loaded, total) => {
4739
- lastSocketActivityAt = performance.now();
4740
- unsentByCopy.set(ctl, loaded < total);
4741
- },
4742
- onDeadline: () => reconnect("copy deadline")
4743
- }
4744
- );
4745
- return validatePutOutcome(item.partNumber, outcome);
4746
- } finally {
4747
- unsentByCopy.delete(ctl);
4748
- }
4704
+ let current = null;
4705
+ let replace = () => {
4749
4706
  };
4750
4707
  const inFlight = {
4751
- reconnect: (why) => reconnect(why),
4752
- hasUnsentBytes: () => [...unsentByCopy.values()].some(Boolean)
4708
+ reconnect: (why) => replace(why, false),
4709
+ hasUnsentBytes: () => current?.unsent ?? false
4753
4710
  };
4754
4711
  partsInFlight.add(inFlight);
4755
4712
  try {
4756
4713
  const etag = await new Promise((resolve5, reject) => {
4757
- let pending = 0;
4758
4714
  let settled = false;
4759
- const run = (label) => {
4760
- const born = generation;
4761
- pending++;
4762
- launchCopy(label === "hedge").then((confirmedEtag) => {
4763
- if (settled) return;
4764
- settled = true;
4765
- if (label === "hedge") log3.debug(`hedge won part=${item.partNumber}`);
4766
- resolve5(confirmedEtag);
4767
- }).catch((err2) => {
4768
- if (settled || born !== generation) return;
4769
- pending--;
4770
- const failure = toUploadError(err2, `Failed to upload part ${item.partNumber}`);
4771
- if (label === "hedge") {
4772
- liveHedges--;
4773
- hedgesInFlight--;
4774
- currentHedge = null;
4775
- if (failure.code !== "ABORTED") hedgeCount--;
4776
- }
4777
- if (failure.code === "ABORTED" && signal?.aborted) {
4778
- settled = true;
4779
- reject(failure);
4780
- return;
4781
- }
4782
- if (pending === 0) {
4783
- if (hedgeTicker !== null) {
4784
- clearInterval(hedgeTicker);
4785
- hedgeTicker = null;
4715
+ const settle = (outcome) => {
4716
+ if (settled) return;
4717
+ settled = true;
4718
+ outcome();
4719
+ };
4720
+ const launch = () => {
4721
+ const ctl = new AbortController();
4722
+ const onUploadEnd = () => ctl.abort();
4723
+ if (runSignal?.aborted) ctl.abort();
4724
+ else runSignal?.addEventListener("abort", onUploadEnd, { once: true });
4725
+ const copy = { ctl, unsent: true, ended: Promise.resolve() };
4726
+ current = copy;
4727
+ lastLaunchAt = performance.now();
4728
+ lastSocketActivityAt = lastLaunchAt;
4729
+ copy.ended = transportPut(item.ciphertext, item.contentMd5, item.partNumber, presignedUrl, ctl.signal, {
4730
+ onSocketActivity: (loaded, total) => {
4731
+ lastSocketActivityAt = performance.now();
4732
+ copy.unsent = loaded < total;
4733
+ },
4734
+ onDeadline: () => replace("copy deadline", false)
4735
+ }).then(
4736
+ (outcome) => {
4737
+ if (current !== copy) return;
4738
+ try {
4739
+ const confirmed = validatePutOutcome(item.partNumber, outcome);
4740
+ settle(() => resolve5(confirmed));
4741
+ } catch (err2) {
4742
+ settle(() => reject(err2));
4786
4743
  }
4787
- settled = true;
4788
- reject(failure);
4744
+ },
4745
+ (err2) => {
4746
+ if (current === copy) settle(() => reject(toUploadError(err2, `Failed to upload part ${item.partNumber}`)));
4789
4747
  }
4748
+ ).finally(() => {
4749
+ copy.unsent = false;
4750
+ runSignal?.removeEventListener("abort", onUploadEnd);
4790
4751
  });
4791
4752
  };
4792
- reconnect = (why) => {
4793
- if (settled || signal?.aborted) return;
4794
- generation++;
4795
- pending = 0;
4796
- hedgesInFlight -= liveHedges;
4797
- liveHedges = 0;
4798
- hedgeCount = 0;
4799
- currentHedge = null;
4800
- const stale = controllers;
4801
- controllers = [];
4802
- for (const ctl of stale) ctl.abort();
4803
- lastLaunchAt = performance.now();
4804
- log3.debug(`reconnect part=${item.partNumber} (${why})`);
4805
- run("primary");
4753
+ replace = (why, spendsTicket) => {
4754
+ const old = current;
4755
+ if (settled || old === null || signal?.aborted) return;
4756
+ current = null;
4757
+ hedgeCount = spendsTicket ? hedgeCount + 1 : 0;
4758
+ log3.debug(`${spendsTicket ? "replace" : "reconnect"} part=${item.partNumber} (${why})`);
4759
+ old.ctl.abort();
4760
+ void old.ended.then(() => {
4761
+ if (settled) return;
4762
+ if (runSignal?.aborted) {
4763
+ settle(() => reject(new UploadError("Upload aborted", "ABORTED", void 0, item.partNumber)));
4764
+ } else {
4765
+ launch();
4766
+ }
4767
+ });
4806
4768
  };
4807
- run("primary");
4769
+ launch();
4808
4770
  hedgeTicker = setInterval(() => {
4809
- if (settled || signal?.aborted) {
4810
- if (hedgeTicker !== null) {
4811
- clearInterval(hedgeTicker);
4812
- hedgeTicker = null;
4813
- }
4814
- return;
4815
- }
4771
+ if (settled || signal?.aborted || current === null) return;
4816
4772
  if (hedgeCount >= HEDGE_MAX_PER_PART) return;
4817
- if (!hedgeDue(item, lastLaunchAt, liveHedges)) return;
4818
- if (hedgesInFlight >= policy.hedgeMaxConcurrent) {
4819
- if (currentHedge !== null) {
4820
- currentHedge.abort();
4821
- currentHedge = null;
4822
- }
4823
- return;
4824
- }
4825
- hedgeCount++;
4826
- liveHedges++;
4827
- hedgesInFlight++;
4828
- lastLaunchAt = performance.now();
4829
- log3.debug(
4830
- `hedge launched part=${item.partNumber} copy=${hedgeCount + 1} after ${Math.round(performance.now() - t0)}ms`
4831
- );
4832
- run("hedge");
4773
+ if (!hedgeDue(item, lastLaunchAt)) return;
4774
+ replace(`slower than its peers after ${Math.round(performance.now() - t0)}ms`, true);
4833
4775
  }, policy.hedgePollMs);
4834
4776
  });
4835
4777
  const tPut = performance.now();
@@ -4840,17 +4782,15 @@ async function multipartUploadStream(options) {
4840
4782
  clock.delivered();
4841
4783
  lastSocketActivityAt = tPut;
4842
4784
  log3.debug(
4843
- `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` hedged\xD7${hedgeCount}` : ""}`
4785
+ `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` replaced\xD7${hedgeCount}` : ""}`
4844
4786
  );
4845
4787
  report("uploading");
4846
4788
  } finally {
4847
4789
  partsInFlight.delete(inFlight);
4848
- reconnect = () => {
4790
+ replace = () => {
4849
4791
  };
4850
4792
  if (hedgeTicker !== null) clearInterval(hedgeTicker);
4851
- hedgesInFlight -= liveHedges;
4852
- for (const ctl of controllers) ctl.abort();
4853
- for (const detach of detachFns) detach();
4793
+ current?.ctl.abort();
4854
4794
  }
4855
4795
  }
4856
4796
  const controlFetch = (url, init3, timeoutMs) => policyFetch(url, init3, timeoutMs, runSignal);
@@ -4955,6 +4895,10 @@ async function multipartUploadStream(options) {
4955
4895
  item.round = round;
4956
4896
  item.flowsAtStart = runningParts.size;
4957
4897
  let url = presignedUrlCache.get(item.partNumber);
4898
+ if (!url && presignPrefetchInFlight) {
4899
+ await presignPrefetchInFlight;
4900
+ url = presignedUrlCache.get(item.partNumber);
4901
+ }
4958
4902
  presignedUrlCache.delete(item.partNumber);
4959
4903
  schedulePresignPrefetch(item.partNumber + 1);
4960
4904
  await retrying(
@@ -13989,7 +13933,7 @@ function proFileGetOutputToWire(out) {
13989
13933
  }
13990
13934
 
13991
13935
  // src/server.ts
13992
- var SERVER_VERSION = "0.2.0";
13936
+ var SERVER_VERSION = "0.2.2";
13993
13937
  var toolMeta = (name) => {
13994
13938
  const { title, description, annotations } = seal_mcp_v1_default.tools[name];
13995
13939
  return { title, description, annotations };
package/dist/cli.js CHANGED
@@ -2886,7 +2886,6 @@ var upload_default = {
2886
2886
  HEDGE_MIN_INFLIGHT_MS: 3e3,
2887
2887
  HEDGE_LAG_FACTOR: 3,
2888
2888
  HEDGE_POLL_MS: 1e3,
2889
- HEDGE_MAX_CONCURRENT: 1,
2890
2889
  LIVENESS_SILENCE_MS: 3e4,
2891
2890
  RETRY_BACKOFF_MS: [1e3, 3e3, 7e3, 15e3, 3e4],
2892
2891
  RETRY_JITTER_RATIO: 0.2,
@@ -4181,7 +4180,6 @@ var DEFAULT_TRANSPORT_POLICY = {
4181
4180
  hedgeMinInflightMs: upload_default.upload.HEDGE_MIN_INFLIGHT_MS,
4182
4181
  hedgeLagFactor: upload_default.upload.HEDGE_LAG_FACTOR,
4183
4182
  hedgePollMs: upload_default.upload.HEDGE_POLL_MS,
4184
- hedgeMaxConcurrent: upload_default.upload.HEDGE_MAX_CONCURRENT,
4185
4183
  livenessSilenceMs: upload_default.upload.LIVENESS_SILENCE_MS,
4186
4184
  verifyPollBackoffMs: upload_default.upload.VERIFY_POLL_BACKOFF_MS,
4187
4185
  verifyFallbackWaitMs: upload_default.upload.VERIFY_FALLBACK_WAIT_MS,
@@ -4503,7 +4501,6 @@ async function multipartUploadStream(options) {
4503
4501
  let lastRoundRate = null;
4504
4502
  let roomWaiters = [];
4505
4503
  const fullPartPace = [];
4506
- let hedgesInFlight = 0;
4507
4504
  const partsInFlight = /* @__PURE__ */ new Set();
4508
4505
  let lastSocketActivityAt = performance.now();
4509
4506
  let socketActivityObservable = false;
@@ -4548,10 +4545,10 @@ async function multipartUploadStream(options) {
4548
4545
  roundBytes = 0;
4549
4546
  roundDeliveries = 0;
4550
4547
  }
4551
- function hedgeDue(item, lastLaunchAt, ownDuplicates) {
4548
+ function hedgeDue(item, lastLaunchAt) {
4552
4549
  const inFlightMs = performance.now() - lastLaunchAt;
4553
4550
  if (inFlightMs < policy.hedgeMinInflightMs) return false;
4554
- const flowsNow = runningParts.size + hedgesInFlight - ownDuplicates;
4551
+ const flowsNow = runningParts.size;
4555
4552
  const peers = fullPartPace.filter((p) => p.flows >= flowsNow).map((p) => p.rate);
4556
4553
  if (peers.length === 0) return false;
4557
4554
  peers.sort((a, b) => a - b);
@@ -4673,135 +4670,80 @@ async function multipartUploadStream(options) {
4673
4670
  }
4674
4671
  async function hedgedPut(item, presignedUrl) {
4675
4672
  const t0 = performance.now();
4676
- let controllers = [];
4677
- const detachFns = [];
4678
4673
  let hedgeTicker = null;
4679
4674
  let hedgeCount = 0;
4680
- let liveHedges = 0;
4681
- let currentHedge = null;
4682
4675
  let lastLaunchAt = t0;
4683
- let generation = 0;
4684
- const unsentByCopy = /* @__PURE__ */ new Map();
4685
- let reconnect = () => {
4686
- };
4687
- const launchCopy = async (isHedge) => {
4688
- const ctl = new AbortController();
4689
- controllers.push(ctl);
4690
- if (isHedge) currentHedge = ctl;
4691
- unsentByCopy.set(ctl, true);
4692
- lastSocketActivityAt = performance.now();
4693
- if (runSignal) {
4694
- if (runSignal.aborted) {
4695
- ctl.abort();
4696
- } else {
4697
- const onAbort = () => ctl.abort();
4698
- runSignal.addEventListener("abort", onAbort, { once: true });
4699
- detachFns.push(() => runSignal.removeEventListener("abort", onAbort));
4700
- }
4701
- }
4702
- try {
4703
- const outcome = await transportPut(
4704
- item.ciphertext,
4705
- item.contentMd5,
4706
- item.partNumber,
4707
- presignedUrl,
4708
- ctl.signal,
4709
- {
4710
- onSocketActivity: (loaded, total) => {
4711
- lastSocketActivityAt = performance.now();
4712
- unsentByCopy.set(ctl, loaded < total);
4713
- },
4714
- onDeadline: () => reconnect("copy deadline")
4715
- }
4716
- );
4717
- return validatePutOutcome(item.partNumber, outcome);
4718
- } finally {
4719
- unsentByCopy.delete(ctl);
4720
- }
4676
+ let current = null;
4677
+ let replace = () => {
4721
4678
  };
4722
4679
  const inFlight = {
4723
- reconnect: (why) => reconnect(why),
4724
- hasUnsentBytes: () => [...unsentByCopy.values()].some(Boolean)
4680
+ reconnect: (why) => replace(why, false),
4681
+ hasUnsentBytes: () => current?.unsent ?? false
4725
4682
  };
4726
4683
  partsInFlight.add(inFlight);
4727
4684
  try {
4728
4685
  const etag = await new Promise((resolve5, reject) => {
4729
- let pending = 0;
4730
4686
  let settled = false;
4731
- const run = (label) => {
4732
- const born = generation;
4733
- pending++;
4734
- launchCopy(label === "hedge").then((confirmedEtag) => {
4735
- if (settled) return;
4736
- settled = true;
4737
- if (label === "hedge") log3.debug(`hedge won part=${item.partNumber}`);
4738
- resolve5(confirmedEtag);
4739
- }).catch((err2) => {
4740
- if (settled || born !== generation) return;
4741
- pending--;
4742
- const failure = toUploadError(err2, `Failed to upload part ${item.partNumber}`);
4743
- if (label === "hedge") {
4744
- liveHedges--;
4745
- hedgesInFlight--;
4746
- currentHedge = null;
4747
- if (failure.code !== "ABORTED") hedgeCount--;
4748
- }
4749
- if (failure.code === "ABORTED" && signal?.aborted) {
4750
- settled = true;
4751
- reject(failure);
4752
- return;
4753
- }
4754
- if (pending === 0) {
4755
- if (hedgeTicker !== null) {
4756
- clearInterval(hedgeTicker);
4757
- hedgeTicker = null;
4687
+ const settle = (outcome) => {
4688
+ if (settled) return;
4689
+ settled = true;
4690
+ outcome();
4691
+ };
4692
+ const launch = () => {
4693
+ const ctl = new AbortController();
4694
+ const onUploadEnd = () => ctl.abort();
4695
+ if (runSignal?.aborted) ctl.abort();
4696
+ else runSignal?.addEventListener("abort", onUploadEnd, { once: true });
4697
+ const copy = { ctl, unsent: true, ended: Promise.resolve() };
4698
+ current = copy;
4699
+ lastLaunchAt = performance.now();
4700
+ lastSocketActivityAt = lastLaunchAt;
4701
+ copy.ended = transportPut(item.ciphertext, item.contentMd5, item.partNumber, presignedUrl, ctl.signal, {
4702
+ onSocketActivity: (loaded, total) => {
4703
+ lastSocketActivityAt = performance.now();
4704
+ copy.unsent = loaded < total;
4705
+ },
4706
+ onDeadline: () => replace("copy deadline", false)
4707
+ }).then(
4708
+ (outcome) => {
4709
+ if (current !== copy) return;
4710
+ try {
4711
+ const confirmed = validatePutOutcome(item.partNumber, outcome);
4712
+ settle(() => resolve5(confirmed));
4713
+ } catch (err2) {
4714
+ settle(() => reject(err2));
4758
4715
  }
4759
- settled = true;
4760
- reject(failure);
4716
+ },
4717
+ (err2) => {
4718
+ if (current === copy) settle(() => reject(toUploadError(err2, `Failed to upload part ${item.partNumber}`)));
4761
4719
  }
4720
+ ).finally(() => {
4721
+ copy.unsent = false;
4722
+ runSignal?.removeEventListener("abort", onUploadEnd);
4762
4723
  });
4763
4724
  };
4764
- reconnect = (why) => {
4765
- if (settled || signal?.aborted) return;
4766
- generation++;
4767
- pending = 0;
4768
- hedgesInFlight -= liveHedges;
4769
- liveHedges = 0;
4770
- hedgeCount = 0;
4771
- currentHedge = null;
4772
- const stale = controllers;
4773
- controllers = [];
4774
- for (const ctl of stale) ctl.abort();
4775
- lastLaunchAt = performance.now();
4776
- log3.debug(`reconnect part=${item.partNumber} (${why})`);
4777
- run("primary");
4725
+ replace = (why, spendsTicket) => {
4726
+ const old = current;
4727
+ if (settled || old === null || signal?.aborted) return;
4728
+ current = null;
4729
+ hedgeCount = spendsTicket ? hedgeCount + 1 : 0;
4730
+ log3.debug(`${spendsTicket ? "replace" : "reconnect"} part=${item.partNumber} (${why})`);
4731
+ old.ctl.abort();
4732
+ void old.ended.then(() => {
4733
+ if (settled) return;
4734
+ if (runSignal?.aborted) {
4735
+ settle(() => reject(new UploadError("Upload aborted", "ABORTED", void 0, item.partNumber)));
4736
+ } else {
4737
+ launch();
4738
+ }
4739
+ });
4778
4740
  };
4779
- run("primary");
4741
+ launch();
4780
4742
  hedgeTicker = setInterval(() => {
4781
- if (settled || signal?.aborted) {
4782
- if (hedgeTicker !== null) {
4783
- clearInterval(hedgeTicker);
4784
- hedgeTicker = null;
4785
- }
4786
- return;
4787
- }
4743
+ if (settled || signal?.aborted || current === null) return;
4788
4744
  if (hedgeCount >= HEDGE_MAX_PER_PART) return;
4789
- if (!hedgeDue(item, lastLaunchAt, liveHedges)) return;
4790
- if (hedgesInFlight >= policy.hedgeMaxConcurrent) {
4791
- if (currentHedge !== null) {
4792
- currentHedge.abort();
4793
- currentHedge = null;
4794
- }
4795
- return;
4796
- }
4797
- hedgeCount++;
4798
- liveHedges++;
4799
- hedgesInFlight++;
4800
- lastLaunchAt = performance.now();
4801
- log3.debug(
4802
- `hedge launched part=${item.partNumber} copy=${hedgeCount + 1} after ${Math.round(performance.now() - t0)}ms`
4803
- );
4804
- run("hedge");
4745
+ if (!hedgeDue(item, lastLaunchAt)) return;
4746
+ replace(`slower than its peers after ${Math.round(performance.now() - t0)}ms`, true);
4805
4747
  }, policy.hedgePollMs);
4806
4748
  });
4807
4749
  const tPut = performance.now();
@@ -4812,17 +4754,15 @@ async function multipartUploadStream(options) {
4812
4754
  clock.delivered();
4813
4755
  lastSocketActivityAt = tPut;
4814
4756
  log3.debug(
4815
- `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` hedged\xD7${hedgeCount}` : ""}`
4757
+ `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` replaced\xD7${hedgeCount}` : ""}`
4816
4758
  );
4817
4759
  report("uploading");
4818
4760
  } finally {
4819
4761
  partsInFlight.delete(inFlight);
4820
- reconnect = () => {
4762
+ replace = () => {
4821
4763
  };
4822
4764
  if (hedgeTicker !== null) clearInterval(hedgeTicker);
4823
- hedgesInFlight -= liveHedges;
4824
- for (const ctl of controllers) ctl.abort();
4825
- for (const detach of detachFns) detach();
4765
+ current?.ctl.abort();
4826
4766
  }
4827
4767
  }
4828
4768
  const controlFetch = (url, init3, timeoutMs) => policyFetch(url, init3, timeoutMs, runSignal);
@@ -4927,6 +4867,10 @@ async function multipartUploadStream(options) {
4927
4867
  item.round = round;
4928
4868
  item.flowsAtStart = runningParts.size;
4929
4869
  let url = presignedUrlCache.get(item.partNumber);
4870
+ if (!url && presignPrefetchInFlight) {
4871
+ await presignPrefetchInFlight;
4872
+ url = presignedUrlCache.get(item.partNumber);
4873
+ }
4930
4874
  presignedUrlCache.delete(item.partNumber);
4931
4875
  schedulePresignPrefetch(item.partNumber + 1);
4932
4876
  await retrying(
@@ -13961,7 +13905,7 @@ function proFileGetOutputToWire(out) {
13961
13905
  }
13962
13906
 
13963
13907
  // src/server.ts
13964
- var SERVER_VERSION = "0.2.0";
13908
+ var SERVER_VERSION = "0.2.2";
13965
13909
  var toolMeta = (name) => {
13966
13910
  const { title, description, annotations } = seal_mcp_v1_default.tools[name];
13967
13911
  return { title, description, annotations };
package/dist/index.cjs CHANGED
@@ -7579,7 +7579,6 @@ var upload_default = {
7579
7579
  HEDGE_MIN_INFLIGHT_MS: 3e3,
7580
7580
  HEDGE_LAG_FACTOR: 3,
7581
7581
  HEDGE_POLL_MS: 1e3,
7582
- HEDGE_MAX_CONCURRENT: 1,
7583
7582
  LIVENESS_SILENCE_MS: 3e4,
7584
7583
  RETRY_BACKOFF_MS: [1e3, 3e3, 7e3, 15e3, 3e4],
7585
7584
  RETRY_JITTER_RATIO: 0.2,
@@ -8874,7 +8873,6 @@ var DEFAULT_TRANSPORT_POLICY = {
8874
8873
  hedgeMinInflightMs: upload_default.upload.HEDGE_MIN_INFLIGHT_MS,
8875
8874
  hedgeLagFactor: upload_default.upload.HEDGE_LAG_FACTOR,
8876
8875
  hedgePollMs: upload_default.upload.HEDGE_POLL_MS,
8877
- hedgeMaxConcurrent: upload_default.upload.HEDGE_MAX_CONCURRENT,
8878
8876
  livenessSilenceMs: upload_default.upload.LIVENESS_SILENCE_MS,
8879
8877
  verifyPollBackoffMs: upload_default.upload.VERIFY_POLL_BACKOFF_MS,
8880
8878
  verifyFallbackWaitMs: upload_default.upload.VERIFY_FALLBACK_WAIT_MS,
@@ -9196,7 +9194,6 @@ async function multipartUploadStream(options) {
9196
9194
  let lastRoundRate = null;
9197
9195
  let roomWaiters = [];
9198
9196
  const fullPartPace = [];
9199
- let hedgesInFlight = 0;
9200
9197
  const partsInFlight = /* @__PURE__ */ new Set();
9201
9198
  let lastSocketActivityAt = performance.now();
9202
9199
  let socketActivityObservable = false;
@@ -9241,10 +9238,10 @@ async function multipartUploadStream(options) {
9241
9238
  roundBytes = 0;
9242
9239
  roundDeliveries = 0;
9243
9240
  }
9244
- function hedgeDue(item, lastLaunchAt, ownDuplicates) {
9241
+ function hedgeDue(item, lastLaunchAt) {
9245
9242
  const inFlightMs = performance.now() - lastLaunchAt;
9246
9243
  if (inFlightMs < policy.hedgeMinInflightMs) return false;
9247
- const flowsNow = runningParts.size + hedgesInFlight - ownDuplicates;
9244
+ const flowsNow = runningParts.size;
9248
9245
  const peers = fullPartPace.filter((p) => p.flows >= flowsNow).map((p) => p.rate);
9249
9246
  if (peers.length === 0) return false;
9250
9247
  peers.sort((a, b) => a - b);
@@ -9366,135 +9363,80 @@ async function multipartUploadStream(options) {
9366
9363
  }
9367
9364
  async function hedgedPut(item, presignedUrl) {
9368
9365
  const t0 = performance.now();
9369
- let controllers = [];
9370
- const detachFns = [];
9371
9366
  let hedgeTicker = null;
9372
9367
  let hedgeCount = 0;
9373
- let liveHedges = 0;
9374
- let currentHedge = null;
9375
9368
  let lastLaunchAt = t0;
9376
- let generation = 0;
9377
- const unsentByCopy = /* @__PURE__ */ new Map();
9378
- let reconnect = () => {
9379
- };
9380
- const launchCopy = async (isHedge) => {
9381
- const ctl = new AbortController();
9382
- controllers.push(ctl);
9383
- if (isHedge) currentHedge = ctl;
9384
- unsentByCopy.set(ctl, true);
9385
- lastSocketActivityAt = performance.now();
9386
- if (runSignal) {
9387
- if (runSignal.aborted) {
9388
- ctl.abort();
9389
- } else {
9390
- const onAbort = () => ctl.abort();
9391
- runSignal.addEventListener("abort", onAbort, { once: true });
9392
- detachFns.push(() => runSignal.removeEventListener("abort", onAbort));
9393
- }
9394
- }
9395
- try {
9396
- const outcome = await transportPut(
9397
- item.ciphertext,
9398
- item.contentMd5,
9399
- item.partNumber,
9400
- presignedUrl,
9401
- ctl.signal,
9402
- {
9403
- onSocketActivity: (loaded, total) => {
9404
- lastSocketActivityAt = performance.now();
9405
- unsentByCopy.set(ctl, loaded < total);
9406
- },
9407
- onDeadline: () => reconnect("copy deadline")
9408
- }
9409
- );
9410
- return validatePutOutcome(item.partNumber, outcome);
9411
- } finally {
9412
- unsentByCopy.delete(ctl);
9413
- }
9369
+ let current = null;
9370
+ let replace = () => {
9414
9371
  };
9415
9372
  const inFlight = {
9416
- reconnect: (why) => reconnect(why),
9417
- hasUnsentBytes: () => [...unsentByCopy.values()].some(Boolean)
9373
+ reconnect: (why) => replace(why, false),
9374
+ hasUnsentBytes: () => current?.unsent ?? false
9418
9375
  };
9419
9376
  partsInFlight.add(inFlight);
9420
9377
  try {
9421
9378
  const etag = await new Promise((resolve5, reject) => {
9422
- let pending = 0;
9423
9379
  let settled = false;
9424
- const run = (label) => {
9425
- const born = generation;
9426
- pending++;
9427
- launchCopy(label === "hedge").then((confirmedEtag) => {
9428
- if (settled) return;
9429
- settled = true;
9430
- if (label === "hedge") log3.debug(`hedge won part=${item.partNumber}`);
9431
- resolve5(confirmedEtag);
9432
- }).catch((err2) => {
9433
- if (settled || born !== generation) return;
9434
- pending--;
9435
- const failure = toUploadError(err2, `Failed to upload part ${item.partNumber}`);
9436
- if (label === "hedge") {
9437
- liveHedges--;
9438
- hedgesInFlight--;
9439
- currentHedge = null;
9440
- if (failure.code !== "ABORTED") hedgeCount--;
9441
- }
9442
- if (failure.code === "ABORTED" && signal?.aborted) {
9443
- settled = true;
9444
- reject(failure);
9445
- return;
9446
- }
9447
- if (pending === 0) {
9448
- if (hedgeTicker !== null) {
9449
- clearInterval(hedgeTicker);
9450
- hedgeTicker = null;
9380
+ const settle = (outcome) => {
9381
+ if (settled) return;
9382
+ settled = true;
9383
+ outcome();
9384
+ };
9385
+ const launch = () => {
9386
+ const ctl = new AbortController();
9387
+ const onUploadEnd = () => ctl.abort();
9388
+ if (runSignal?.aborted) ctl.abort();
9389
+ else runSignal?.addEventListener("abort", onUploadEnd, { once: true });
9390
+ const copy = { ctl, unsent: true, ended: Promise.resolve() };
9391
+ current = copy;
9392
+ lastLaunchAt = performance.now();
9393
+ lastSocketActivityAt = lastLaunchAt;
9394
+ copy.ended = transportPut(item.ciphertext, item.contentMd5, item.partNumber, presignedUrl, ctl.signal, {
9395
+ onSocketActivity: (loaded, total) => {
9396
+ lastSocketActivityAt = performance.now();
9397
+ copy.unsent = loaded < total;
9398
+ },
9399
+ onDeadline: () => replace("copy deadline", false)
9400
+ }).then(
9401
+ (outcome) => {
9402
+ if (current !== copy) return;
9403
+ try {
9404
+ const confirmed = validatePutOutcome(item.partNumber, outcome);
9405
+ settle(() => resolve5(confirmed));
9406
+ } catch (err2) {
9407
+ settle(() => reject(err2));
9451
9408
  }
9452
- settled = true;
9453
- reject(failure);
9409
+ },
9410
+ (err2) => {
9411
+ if (current === copy) settle(() => reject(toUploadError(err2, `Failed to upload part ${item.partNumber}`)));
9454
9412
  }
9413
+ ).finally(() => {
9414
+ copy.unsent = false;
9415
+ runSignal?.removeEventListener("abort", onUploadEnd);
9455
9416
  });
9456
9417
  };
9457
- reconnect = (why) => {
9458
- if (settled || signal?.aborted) return;
9459
- generation++;
9460
- pending = 0;
9461
- hedgesInFlight -= liveHedges;
9462
- liveHedges = 0;
9463
- hedgeCount = 0;
9464
- currentHedge = null;
9465
- const stale = controllers;
9466
- controllers = [];
9467
- for (const ctl of stale) ctl.abort();
9468
- lastLaunchAt = performance.now();
9469
- log3.debug(`reconnect part=${item.partNumber} (${why})`);
9470
- run("primary");
9418
+ replace = (why, spendsTicket) => {
9419
+ const old = current;
9420
+ if (settled || old === null || signal?.aborted) return;
9421
+ current = null;
9422
+ hedgeCount = spendsTicket ? hedgeCount + 1 : 0;
9423
+ log3.debug(`${spendsTicket ? "replace" : "reconnect"} part=${item.partNumber} (${why})`);
9424
+ old.ctl.abort();
9425
+ void old.ended.then(() => {
9426
+ if (settled) return;
9427
+ if (runSignal?.aborted) {
9428
+ settle(() => reject(new UploadError("Upload aborted", "ABORTED", void 0, item.partNumber)));
9429
+ } else {
9430
+ launch();
9431
+ }
9432
+ });
9471
9433
  };
9472
- run("primary");
9434
+ launch();
9473
9435
  hedgeTicker = setInterval(() => {
9474
- if (settled || signal?.aborted) {
9475
- if (hedgeTicker !== null) {
9476
- clearInterval(hedgeTicker);
9477
- hedgeTicker = null;
9478
- }
9479
- return;
9480
- }
9436
+ if (settled || signal?.aborted || current === null) return;
9481
9437
  if (hedgeCount >= HEDGE_MAX_PER_PART) return;
9482
- if (!hedgeDue(item, lastLaunchAt, liveHedges)) return;
9483
- if (hedgesInFlight >= policy.hedgeMaxConcurrent) {
9484
- if (currentHedge !== null) {
9485
- currentHedge.abort();
9486
- currentHedge = null;
9487
- }
9488
- return;
9489
- }
9490
- hedgeCount++;
9491
- liveHedges++;
9492
- hedgesInFlight++;
9493
- lastLaunchAt = performance.now();
9494
- log3.debug(
9495
- `hedge launched part=${item.partNumber} copy=${hedgeCount + 1} after ${Math.round(performance.now() - t0)}ms`
9496
- );
9497
- run("hedge");
9438
+ if (!hedgeDue(item, lastLaunchAt)) return;
9439
+ replace(`slower than its peers after ${Math.round(performance.now() - t0)}ms`, true);
9498
9440
  }, policy.hedgePollMs);
9499
9441
  });
9500
9442
  const tPut = performance.now();
@@ -9505,17 +9447,15 @@ async function multipartUploadStream(options) {
9505
9447
  clock.delivered();
9506
9448
  lastSocketActivityAt = tPut;
9507
9449
  log3.debug(
9508
- `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` hedged\xD7${hedgeCount}` : ""}`
9450
+ `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` replaced\xD7${hedgeCount}` : ""}`
9509
9451
  );
9510
9452
  report("uploading");
9511
9453
  } finally {
9512
9454
  partsInFlight.delete(inFlight);
9513
- reconnect = () => {
9455
+ replace = () => {
9514
9456
  };
9515
9457
  if (hedgeTicker !== null) clearInterval(hedgeTicker);
9516
- hedgesInFlight -= liveHedges;
9517
- for (const ctl of controllers) ctl.abort();
9518
- for (const detach of detachFns) detach();
9458
+ current?.ctl.abort();
9519
9459
  }
9520
9460
  }
9521
9461
  const controlFetch = (url, init3, timeoutMs) => policyFetch(url, init3, timeoutMs, runSignal);
@@ -9620,6 +9560,10 @@ async function multipartUploadStream(options) {
9620
9560
  item.round = round;
9621
9561
  item.flowsAtStart = runningParts.size;
9622
9562
  let url = presignedUrlCache.get(item.partNumber);
9563
+ if (!url && presignPrefetchInFlight) {
9564
+ await presignPrefetchInFlight;
9565
+ url = presignedUrlCache.get(item.partNumber);
9566
+ }
9623
9567
  presignedUrlCache.delete(item.partNumber);
9624
9568
  schedulePresignPrefetch(item.partNumber + 1);
9625
9569
  await retrying(
@@ -13844,7 +13788,7 @@ function proFileGetOutputToWire(out) {
13844
13788
  }
13845
13789
 
13846
13790
  // src/server.ts
13847
- var SERVER_VERSION = "0.2.0";
13791
+ var SERVER_VERSION = "0.2.2";
13848
13792
  var toolMeta = (name) => {
13849
13793
  const { title, description, annotations } = seal_mcp_v1_default.tools[name];
13850
13794
  return { title, description, annotations };
package/dist/index.d.cts CHANGED
@@ -218,7 +218,8 @@ interface TransportPolicy {
218
218
  /**
219
219
  * Parallel part PUTs: where the pool starts, and how wide it may get.
220
220
  * Storage speaks HTTP/1.1 only, so every PUT is a connection of its own and
221
- * a browser gives a host six: `poolMax` + `hedgeMaxConcurrent` must fit.
221
+ * a browser gives a host six: `poolMax` must fit. A replacement takes the
222
+ * connection of the copy it replaces, never a second one (F-263).
222
223
  */
223
224
  poolStart: number;
224
225
  poolMax: number;
@@ -234,13 +235,11 @@ interface TransportPolicy {
234
235
  poolShrinkRatio: number;
235
236
  /** Encrypted parts that may wait for a slot (bounds memory). */
236
237
  partQueueLimit: number;
237
- /** Never duplicate a part before it has been in flight this long. */
238
+ /** Never replace a copy before it has been in flight this long. */
238
239
  hedgeMinInflightMs: number;
239
240
  /** A part is an outlier when it is this many times slower than its peers' median. */
240
241
  hedgeLagFactor: number;
241
242
  hedgePollMs: number;
242
- /** Duplicate copies in flight across the whole upload, at most. */
243
- hedgeMaxConcurrent: number;
244
243
  /**
245
244
  * No part delivered and no socket of ANY copy taking bytes for this long,
246
245
  * while some copy still has bytes to send ⇒ the connections are dead: every
package/dist/index.d.ts CHANGED
@@ -218,7 +218,8 @@ interface TransportPolicy {
218
218
  /**
219
219
  * Parallel part PUTs: where the pool starts, and how wide it may get.
220
220
  * Storage speaks HTTP/1.1 only, so every PUT is a connection of its own and
221
- * a browser gives a host six: `poolMax` + `hedgeMaxConcurrent` must fit.
221
+ * a browser gives a host six: `poolMax` must fit. A replacement takes the
222
+ * connection of the copy it replaces, never a second one (F-263).
222
223
  */
223
224
  poolStart: number;
224
225
  poolMax: number;
@@ -234,13 +235,11 @@ interface TransportPolicy {
234
235
  poolShrinkRatio: number;
235
236
  /** Encrypted parts that may wait for a slot (bounds memory). */
236
237
  partQueueLimit: number;
237
- /** Never duplicate a part before it has been in flight this long. */
238
+ /** Never replace a copy before it has been in flight this long. */
238
239
  hedgeMinInflightMs: number;
239
240
  /** A part is an outlier when it is this many times slower than its peers' median. */
240
241
  hedgeLagFactor: number;
241
242
  hedgePollMs: number;
242
- /** Duplicate copies in flight across the whole upload, at most. */
243
- hedgeMaxConcurrent: number;
244
243
  /**
245
244
  * No part delivered and no socket of ANY copy taking bytes for this long,
246
245
  * while some copy still has bytes to send ⇒ the connections are dead: every
package/dist/index.js CHANGED
@@ -7507,7 +7507,6 @@ var upload_default = {
7507
7507
  HEDGE_MIN_INFLIGHT_MS: 3e3,
7508
7508
  HEDGE_LAG_FACTOR: 3,
7509
7509
  HEDGE_POLL_MS: 1e3,
7510
- HEDGE_MAX_CONCURRENT: 1,
7511
7510
  LIVENESS_SILENCE_MS: 3e4,
7512
7511
  RETRY_BACKOFF_MS: [1e3, 3e3, 7e3, 15e3, 3e4],
7513
7512
  RETRY_JITTER_RATIO: 0.2,
@@ -8802,7 +8801,6 @@ var DEFAULT_TRANSPORT_POLICY = {
8802
8801
  hedgeMinInflightMs: upload_default.upload.HEDGE_MIN_INFLIGHT_MS,
8803
8802
  hedgeLagFactor: upload_default.upload.HEDGE_LAG_FACTOR,
8804
8803
  hedgePollMs: upload_default.upload.HEDGE_POLL_MS,
8805
- hedgeMaxConcurrent: upload_default.upload.HEDGE_MAX_CONCURRENT,
8806
8804
  livenessSilenceMs: upload_default.upload.LIVENESS_SILENCE_MS,
8807
8805
  verifyPollBackoffMs: upload_default.upload.VERIFY_POLL_BACKOFF_MS,
8808
8806
  verifyFallbackWaitMs: upload_default.upload.VERIFY_FALLBACK_WAIT_MS,
@@ -9124,7 +9122,6 @@ async function multipartUploadStream(options) {
9124
9122
  let lastRoundRate = null;
9125
9123
  let roomWaiters = [];
9126
9124
  const fullPartPace = [];
9127
- let hedgesInFlight = 0;
9128
9125
  const partsInFlight = /* @__PURE__ */ new Set();
9129
9126
  let lastSocketActivityAt = performance.now();
9130
9127
  let socketActivityObservable = false;
@@ -9169,10 +9166,10 @@ async function multipartUploadStream(options) {
9169
9166
  roundBytes = 0;
9170
9167
  roundDeliveries = 0;
9171
9168
  }
9172
- function hedgeDue(item, lastLaunchAt, ownDuplicates) {
9169
+ function hedgeDue(item, lastLaunchAt) {
9173
9170
  const inFlightMs = performance.now() - lastLaunchAt;
9174
9171
  if (inFlightMs < policy.hedgeMinInflightMs) return false;
9175
- const flowsNow = runningParts.size + hedgesInFlight - ownDuplicates;
9172
+ const flowsNow = runningParts.size;
9176
9173
  const peers = fullPartPace.filter((p) => p.flows >= flowsNow).map((p) => p.rate);
9177
9174
  if (peers.length === 0) return false;
9178
9175
  peers.sort((a, b) => a - b);
@@ -9294,135 +9291,80 @@ async function multipartUploadStream(options) {
9294
9291
  }
9295
9292
  async function hedgedPut(item, presignedUrl) {
9296
9293
  const t0 = performance.now();
9297
- let controllers = [];
9298
- const detachFns = [];
9299
9294
  let hedgeTicker = null;
9300
9295
  let hedgeCount = 0;
9301
- let liveHedges = 0;
9302
- let currentHedge = null;
9303
9296
  let lastLaunchAt = t0;
9304
- let generation = 0;
9305
- const unsentByCopy = /* @__PURE__ */ new Map();
9306
- let reconnect = () => {
9307
- };
9308
- const launchCopy = async (isHedge) => {
9309
- const ctl = new AbortController();
9310
- controllers.push(ctl);
9311
- if (isHedge) currentHedge = ctl;
9312
- unsentByCopy.set(ctl, true);
9313
- lastSocketActivityAt = performance.now();
9314
- if (runSignal) {
9315
- if (runSignal.aborted) {
9316
- ctl.abort();
9317
- } else {
9318
- const onAbort = () => ctl.abort();
9319
- runSignal.addEventListener("abort", onAbort, { once: true });
9320
- detachFns.push(() => runSignal.removeEventListener("abort", onAbort));
9321
- }
9322
- }
9323
- try {
9324
- const outcome = await transportPut(
9325
- item.ciphertext,
9326
- item.contentMd5,
9327
- item.partNumber,
9328
- presignedUrl,
9329
- ctl.signal,
9330
- {
9331
- onSocketActivity: (loaded, total) => {
9332
- lastSocketActivityAt = performance.now();
9333
- unsentByCopy.set(ctl, loaded < total);
9334
- },
9335
- onDeadline: () => reconnect("copy deadline")
9336
- }
9337
- );
9338
- return validatePutOutcome(item.partNumber, outcome);
9339
- } finally {
9340
- unsentByCopy.delete(ctl);
9341
- }
9297
+ let current = null;
9298
+ let replace = () => {
9342
9299
  };
9343
9300
  const inFlight = {
9344
- reconnect: (why) => reconnect(why),
9345
- hasUnsentBytes: () => [...unsentByCopy.values()].some(Boolean)
9301
+ reconnect: (why) => replace(why, false),
9302
+ hasUnsentBytes: () => current?.unsent ?? false
9346
9303
  };
9347
9304
  partsInFlight.add(inFlight);
9348
9305
  try {
9349
9306
  const etag = await new Promise((resolve5, reject) => {
9350
- let pending = 0;
9351
9307
  let settled = false;
9352
- const run = (label) => {
9353
- const born = generation;
9354
- pending++;
9355
- launchCopy(label === "hedge").then((confirmedEtag) => {
9356
- if (settled) return;
9357
- settled = true;
9358
- if (label === "hedge") log3.debug(`hedge won part=${item.partNumber}`);
9359
- resolve5(confirmedEtag);
9360
- }).catch((err2) => {
9361
- if (settled || born !== generation) return;
9362
- pending--;
9363
- const failure = toUploadError(err2, `Failed to upload part ${item.partNumber}`);
9364
- if (label === "hedge") {
9365
- liveHedges--;
9366
- hedgesInFlight--;
9367
- currentHedge = null;
9368
- if (failure.code !== "ABORTED") hedgeCount--;
9369
- }
9370
- if (failure.code === "ABORTED" && signal?.aborted) {
9371
- settled = true;
9372
- reject(failure);
9373
- return;
9374
- }
9375
- if (pending === 0) {
9376
- if (hedgeTicker !== null) {
9377
- clearInterval(hedgeTicker);
9378
- hedgeTicker = null;
9308
+ const settle = (outcome) => {
9309
+ if (settled) return;
9310
+ settled = true;
9311
+ outcome();
9312
+ };
9313
+ const launch = () => {
9314
+ const ctl = new AbortController();
9315
+ const onUploadEnd = () => ctl.abort();
9316
+ if (runSignal?.aborted) ctl.abort();
9317
+ else runSignal?.addEventListener("abort", onUploadEnd, { once: true });
9318
+ const copy = { ctl, unsent: true, ended: Promise.resolve() };
9319
+ current = copy;
9320
+ lastLaunchAt = performance.now();
9321
+ lastSocketActivityAt = lastLaunchAt;
9322
+ copy.ended = transportPut(item.ciphertext, item.contentMd5, item.partNumber, presignedUrl, ctl.signal, {
9323
+ onSocketActivity: (loaded, total) => {
9324
+ lastSocketActivityAt = performance.now();
9325
+ copy.unsent = loaded < total;
9326
+ },
9327
+ onDeadline: () => replace("copy deadline", false)
9328
+ }).then(
9329
+ (outcome) => {
9330
+ if (current !== copy) return;
9331
+ try {
9332
+ const confirmed = validatePutOutcome(item.partNumber, outcome);
9333
+ settle(() => resolve5(confirmed));
9334
+ } catch (err2) {
9335
+ settle(() => reject(err2));
9379
9336
  }
9380
- settled = true;
9381
- reject(failure);
9337
+ },
9338
+ (err2) => {
9339
+ if (current === copy) settle(() => reject(toUploadError(err2, `Failed to upload part ${item.partNumber}`)));
9382
9340
  }
9341
+ ).finally(() => {
9342
+ copy.unsent = false;
9343
+ runSignal?.removeEventListener("abort", onUploadEnd);
9383
9344
  });
9384
9345
  };
9385
- reconnect = (why) => {
9386
- if (settled || signal?.aborted) return;
9387
- generation++;
9388
- pending = 0;
9389
- hedgesInFlight -= liveHedges;
9390
- liveHedges = 0;
9391
- hedgeCount = 0;
9392
- currentHedge = null;
9393
- const stale = controllers;
9394
- controllers = [];
9395
- for (const ctl of stale) ctl.abort();
9396
- lastLaunchAt = performance.now();
9397
- log3.debug(`reconnect part=${item.partNumber} (${why})`);
9398
- run("primary");
9346
+ replace = (why, spendsTicket) => {
9347
+ const old = current;
9348
+ if (settled || old === null || signal?.aborted) return;
9349
+ current = null;
9350
+ hedgeCount = spendsTicket ? hedgeCount + 1 : 0;
9351
+ log3.debug(`${spendsTicket ? "replace" : "reconnect"} part=${item.partNumber} (${why})`);
9352
+ old.ctl.abort();
9353
+ void old.ended.then(() => {
9354
+ if (settled) return;
9355
+ if (runSignal?.aborted) {
9356
+ settle(() => reject(new UploadError("Upload aborted", "ABORTED", void 0, item.partNumber)));
9357
+ } else {
9358
+ launch();
9359
+ }
9360
+ });
9399
9361
  };
9400
- run("primary");
9362
+ launch();
9401
9363
  hedgeTicker = setInterval(() => {
9402
- if (settled || signal?.aborted) {
9403
- if (hedgeTicker !== null) {
9404
- clearInterval(hedgeTicker);
9405
- hedgeTicker = null;
9406
- }
9407
- return;
9408
- }
9364
+ if (settled || signal?.aborted || current === null) return;
9409
9365
  if (hedgeCount >= HEDGE_MAX_PER_PART) return;
9410
- if (!hedgeDue(item, lastLaunchAt, liveHedges)) return;
9411
- if (hedgesInFlight >= policy.hedgeMaxConcurrent) {
9412
- if (currentHedge !== null) {
9413
- currentHedge.abort();
9414
- currentHedge = null;
9415
- }
9416
- return;
9417
- }
9418
- hedgeCount++;
9419
- liveHedges++;
9420
- hedgesInFlight++;
9421
- lastLaunchAt = performance.now();
9422
- log3.debug(
9423
- `hedge launched part=${item.partNumber} copy=${hedgeCount + 1} after ${Math.round(performance.now() - t0)}ms`
9424
- );
9425
- run("hedge");
9366
+ if (!hedgeDue(item, lastLaunchAt)) return;
9367
+ replace(`slower than its peers after ${Math.round(performance.now() - t0)}ms`, true);
9426
9368
  }, policy.hedgePollMs);
9427
9369
  });
9428
9370
  const tPut = performance.now();
@@ -9433,17 +9375,15 @@ async function multipartUploadStream(options) {
9433
9375
  clock.delivered();
9434
9376
  lastSocketActivityAt = tPut;
9435
9377
  log3.debug(
9436
- `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` hedged\xD7${hedgeCount}` : ""}`
9378
+ `part=${item.partNumber}/${totalParts} put=${Math.round(tPut - t0)}ms size=${item.ciphertext.length}${hedgeCount > 0 ? ` replaced\xD7${hedgeCount}` : ""}`
9437
9379
  );
9438
9380
  report("uploading");
9439
9381
  } finally {
9440
9382
  partsInFlight.delete(inFlight);
9441
- reconnect = () => {
9383
+ replace = () => {
9442
9384
  };
9443
9385
  if (hedgeTicker !== null) clearInterval(hedgeTicker);
9444
- hedgesInFlight -= liveHedges;
9445
- for (const ctl of controllers) ctl.abort();
9446
- for (const detach of detachFns) detach();
9386
+ current?.ctl.abort();
9447
9387
  }
9448
9388
  }
9449
9389
  const controlFetch = (url, init3, timeoutMs) => policyFetch(url, init3, timeoutMs, runSignal);
@@ -9548,6 +9488,10 @@ async function multipartUploadStream(options) {
9548
9488
  item.round = round;
9549
9489
  item.flowsAtStart = runningParts.size;
9550
9490
  let url = presignedUrlCache.get(item.partNumber);
9491
+ if (!url && presignPrefetchInFlight) {
9492
+ await presignPrefetchInFlight;
9493
+ url = presignedUrlCache.get(item.partNumber);
9494
+ }
9551
9495
  presignedUrlCache.delete(item.partNumber);
9552
9496
  schedulePresignPrefetch(item.partNumber + 1);
9553
9497
  await retrying(
@@ -13772,7 +13716,7 @@ function proFileGetOutputToWire(out) {
13772
13716
  }
13773
13717
 
13774
13718
  // src/server.ts
13775
- var SERVER_VERSION = "0.2.0";
13719
+ var SERVER_VERSION = "0.2.2";
13776
13720
  var toolMeta = (name) => {
13777
13721
  const { title, description, annotations } = seal_mcp_v1_default.tools[name];
13778
13722
  return { title, description, annotations };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sealnet-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "mcpName": "net.seal/mcp",
5
5
  "description": "Model Context Protocol server for SEAL — model never holds capability by default (handoff mode); explicit opt-in to forward mode with strict TTL/recipient policy.",
6
6
  "type": "module",