@anuma/sdk 9.1.5 → 9.1.7

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.
@@ -19,7 +19,7 @@ import {
19
19
  taskTypeHeader,
20
20
  validateEndpointOverride,
21
21
  withInternalFlowMarker
22
- } from "./chunk-7QX4J7KV.mjs";
22
+ } from "./chunk-RSA3S6OA.mjs";
23
23
  import {
24
24
  BASE_URL,
25
25
  MCP_R2_DOMAIN,
@@ -1748,7 +1748,14 @@ function cosineSimilarity(a, b) {
1748
1748
 
1749
1749
  // src/lib/processors/encoding.ts
1750
1750
  var B64_ENCODE_CHUNK = 32768 * 3;
1751
+ function assertFileUrlAllowed(dataUrl) {
1752
+ const isNode = typeof process !== "undefined" && Boolean(process.versions?.node);
1753
+ if (isNode && !dataUrl.startsWith("data:") && !dataUrl.startsWith("blob:")) {
1754
+ throw new Error("Server file preprocessing requires a data URL or blob URL.");
1755
+ }
1756
+ }
1751
1757
  async function dataUrlToArrayBuffer(dataUrl) {
1758
+ assertFileUrlAllowed(dataUrl);
1752
1759
  if (dataUrl.startsWith("blob:") || dataUrl.startsWith("http://") || dataUrl.startsWith("https://")) {
1753
1760
  const response = await fetch(dataUrl);
1754
1761
  return response.arrayBuffer();
@@ -4404,7 +4411,7 @@ var mergeHeaders = (...headers) => {
4404
4411
  if (!header || typeof header !== "object") {
4405
4412
  continue;
4406
4413
  }
4407
- const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
4414
+ const iterator = Array.isArray(header) || header instanceof Headers ? headersEntries(new Headers(header)) : Object.entries(header);
4408
4415
  for (const [key, value] of iterator) {
4409
4416
  if (value === null) {
4410
4417
  mergedHeaders.delete(key);
@@ -4679,6 +4686,18 @@ var createClient = (config = {}) => {
4679
4686
  // src/client/client.gen.ts
4680
4687
  var client = createClient(createClientConfig(createConfig()));
4681
4688
 
4689
+ // src/clientHeaders.ts
4690
+ function normalizeHeaders(headers) {
4691
+ if (headers instanceof Headers || Array.isArray(headers)) {
4692
+ const normalized = /* @__PURE__ */ Object.create(null);
4693
+ new Headers(headers).forEach((value, name) => {
4694
+ normalized[name] = value;
4695
+ });
4696
+ return normalized;
4697
+ }
4698
+ return headers;
4699
+ }
4700
+
4682
4701
  // src/client/sdk.gen.ts
4683
4702
  var getApiV1Config = (options) => (options?.client ?? client).get({ url: "/api/v1/config", ...options });
4684
4703
  var getApiV1CreditsBalance = (options) => (options?.client ?? client).get({ url: "/api/v1/credits/balance", ...options });
@@ -4688,7 +4707,7 @@ var postApiV1CreditsPurchase = (options) => (options.client ?? client).post({
4688
4707
  ...options,
4689
4708
  headers: {
4690
4709
  "Content-Type": "application/json",
4691
- ...options.headers
4710
+ ...normalizeHeaders(options.headers)
4692
4711
  }
4693
4712
  });
4694
4713
  var postApiV1Embeddings = (options) => (options.client ?? client).post({
@@ -4696,7 +4715,7 @@ var postApiV1Embeddings = (options) => (options.client ?? client).post({
4696
4715
  ...options,
4697
4716
  headers: {
4698
4717
  "Content-Type": "application/json",
4699
- ...options.headers
4718
+ ...normalizeHeaders(options.headers)
4700
4719
  }
4701
4720
  });
4702
4721
  var getApiV1Models = (options) => (options?.client ?? client).get({ url: "/api/v1/models", ...options });
@@ -4705,7 +4724,7 @@ var postApiV1PhoneCalls = (options) => (options.client ?? client).post({
4705
4724
  ...options,
4706
4725
  headers: {
4707
4726
  "Content-Type": "application/json",
4708
- ...options.headers
4727
+ ...normalizeHeaders(options.headers)
4709
4728
  }
4710
4729
  });
4711
4730
  var getApiV1PhoneCallsByCallId = (options) => (options.client ?? client).get({ url: "/api/v1/phone-calls/{call_id}", ...options });
@@ -4714,7 +4733,7 @@ var postApiV1SubscriptionsCancel = (options) => (options?.client ?? client).post
4714
4733
  ...options,
4715
4734
  headers: {
4716
4735
  "Content-Type": "application/json",
4717
- ...options?.headers
4736
+ ...normalizeHeaders(options?.headers)
4718
4737
  }
4719
4738
  });
4720
4739
  var postApiV1SubscriptionsCreateCheckoutSession = (options) => (options.client ?? client).post({
@@ -4722,7 +4741,7 @@ var postApiV1SubscriptionsCreateCheckoutSession = (options) => (options.client ?
4722
4741
  ...options,
4723
4742
  headers: {
4724
4743
  "Content-Type": "application/json",
4725
- ...options.headers
4744
+ ...normalizeHeaders(options.headers)
4726
4745
  }
4727
4746
  });
4728
4747
  var postApiV1SubscriptionsCustomerPortal = (options) => (options.client ?? client).post({
@@ -4730,7 +4749,7 @@ var postApiV1SubscriptionsCustomerPortal = (options) => (options.client ?? clien
4730
4749
  ...options,
4731
4750
  headers: {
4732
4751
  "Content-Type": "application/json",
4733
- ...options.headers
4752
+ ...normalizeHeaders(options.headers)
4734
4753
  }
4735
4754
  });
4736
4755
  var postApiV1SubscriptionsRenew = (options) => (options?.client ?? client).post({ url: "/api/v1/subscriptions/renew", ...options });
@@ -4741,7 +4760,7 @@ var postApiV1WalletsBinding = (options) => (options.client ?? client).post({
4741
4760
  ...options,
4742
4761
  headers: {
4743
4762
  "Content-Type": "application/json",
4744
- ...options.headers
4763
+ ...normalizeHeaders(options.headers)
4745
4764
  }
4746
4765
  });
4747
4766
  var postApiV1WalletsBindingNonce = (options) => (options?.client ?? client).post({ url: "/api/v1/wallets/binding/nonce", ...options });
@@ -14957,6 +14976,16 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
14957
14976
  const probe = await ctx.vaultMemoryCollection.find(id2);
14958
14977
  if (probe.isDeleted || probe.supersededBy || !isOwnedByCtxUser(ctx, probe)) return null;
14959
14978
  if (opts.freeFormOnly && isKinded(probe)) return null;
14979
+ const readStoredContent = probe._getRaw("content");
14980
+ if (opts.expectedContent !== void 0) {
14981
+ const current = await vaultMemoryToStored(
14982
+ probe,
14983
+ ctx.walletAddress,
14984
+ ctx.signMessage,
14985
+ ctx.embeddedWalletSigner
14986
+ );
14987
+ if (current.content !== opts.expectedContent) return null;
14988
+ }
14960
14989
  const levelAfter = (current) => {
14961
14990
  if (opts.level !== void 0) return opts.level;
14962
14991
  if (opts.scope === void 0) return resolveMemoryLevel(current.level, current.scope);
@@ -14964,7 +14993,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
14964
14993
  };
14965
14994
  assertValidKindLevel(opts.kind !== void 0 ? opts.kind : probe.kind, levelAfter(probe));
14966
14995
  const encryptedKindValue = await encryptKindValue(ctx, opts.kindValue);
14967
- const encryptedContent = ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
14996
+ const encryptedContent = opts.content !== void 0 && ctx.walletAddress && ctx.signMessage ? await encryptVaultMemoryContent(
14968
14997
  opts.content,
14969
14998
  ctx.walletAddress,
14970
14999
  ctx.signMessage,
@@ -14972,13 +15001,13 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
14972
15001
  ) : opts.content;
14973
15002
  let stale = false;
14974
15003
  const record2 = probe;
14975
- const originalUpdatedAt = record2.updatedAt.getTime();
14976
15004
  await ctx.database.write(async () => {
14977
15005
  await assertCanWrite2(ctx);
14978
- if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2)) {
15006
+ if (record2.isDeleted || record2.supersededBy || !isOwnedByCtxUser(ctx, record2) || opts.freeFormOnly && isKinded(record2) || opts.expectedContent !== void 0 && record2._getRaw("content") !== readStoredContent) {
14979
15007
  stale = true;
14980
15008
  return;
14981
15009
  }
15010
+ const originalUpdatedAt = record2.updatedAt.getTime();
14982
15011
  const nextKind = opts.kind !== void 0 ? opts.kind : record2.kind;
14983
15012
  const nextLevel = levelAfter(record2);
14984
15013
  assertValidKindLevel(nextKind, nextLevel);
@@ -14994,7 +15023,7 @@ async function updateVaultMemoryOp(ctx, id2, opts) {
14994
15023
  replayedObservation = opts.observationSourceIds.every((id3) => observedSources.includes(id3));
14995
15024
  }
14996
15025
  await record2.update((r) => {
14997
- r._setRaw("content", encryptedContent);
15026
+ if (encryptedContent !== void 0) r._setRaw("content", encryptedContent);
14998
15027
  if (opts.level !== void 0) {
14999
15028
  r._setRaw("level", nextLevel);
15000
15029
  r._setRaw("scope", scopeForLevel(nextLevel));
@@ -15761,7 +15790,7 @@ function classifyDecay(m, now, policy) {
15761
15790
  if (m.source === "manual" || m.source === SOURCE_PHOTO) return "keep";
15762
15791
  if (isTimeSensitiveType(m.factType) && m.eventTimeEnd !== null) {
15763
15792
  if (m.eventTimeEnd < now - resolved.pastEventGraceMs) return "archive";
15764
- if (m.eventTimeEnd >= now) return "keep";
15793
+ return "keep";
15765
15794
  }
15766
15795
  if (now - lastActivityAt(m) > ttlForType(m.factType, resolved)) return "archive";
15767
15796
  return "keep";
@@ -19261,7 +19290,6 @@ async function retainWithPersistence(content, ctx, options = {}) {
19261
19290
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
19262
19291
  const resurrect = resurrectFields(existing);
19263
19292
  const updated = await ctx.persistence.update(targetId, {
19264
- content: existing.content,
19265
19293
  freeFormOnly: true,
19266
19294
  proofCountIncrement: 1,
19267
19295
  observationSourceIds: options.sourceChunkIds,
@@ -19465,7 +19493,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
19465
19493
  content: m.content,
19466
19494
  similarity: m.similarity
19467
19495
  }));
19468
- const { consolidateMemory: doConsolidate } = await import("./consolidate-WLDYJF6J.mjs");
19496
+ const { consolidateMemory: doConsolidate } = await import("./consolidate-WFTPBHDV.mjs");
19469
19497
  const decision = await doConsolidate(trimmed, candidates, consolidateOptions);
19470
19498
  if (decision.action === "create") return decision.fallbackReason ? null : { create: true };
19471
19499
  if (decision.action === "supersede" && decision.content) {
@@ -19500,7 +19528,6 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
19500
19528
  const factTypeUpdate = pickFactTypeUpdate(existing, options.factType);
19501
19529
  const resurrect = resurrectFields(existing);
19502
19530
  const updated = await ctx.persistence.update(decision.targetId, {
19503
- content: existing.content,
19504
19531
  freeFormOnly: true,
19505
19532
  proofCountIncrement: 1,
19506
19533
  observationSourceIds: options.sourceChunkIds,
@@ -19528,6 +19555,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
19528
19555
  };
19529
19556
  }
19530
19557
  if (decision.action === "update" && decision.targetId && decision.content) {
19558
+ const expectedContent = candidates.find(
19559
+ (candidate) => candidate.id === decision.targetId
19560
+ )?.content;
19561
+ if (expectedContent === void 0) return null;
19531
19562
  const existing = await ctx.persistence.get(decision.targetId);
19532
19563
  if (!existing || existing.supersededBy) {
19533
19564
  return abandonToRace(
@@ -19535,6 +19566,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
19535
19566
  `update: target ${decision.targetId} ${existing ? "superseded" : "deleted"} before the write`
19536
19567
  );
19537
19568
  }
19569
+ if (existing.content !== expectedContent) {
19570
+ return abandonToRace(options, `update: target ${decision.targetId} edited before the write`);
19571
+ }
19538
19572
  const mergedSourceIds = unionStrings(
19539
19573
  existing.sourceChunkIds ?? [],
19540
19574
  options.sourceChunkIds ?? []
@@ -19547,6 +19581,7 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
19547
19581
  const resurrect = resurrectFields(existing);
19548
19582
  const updated = await ctx.persistence.update(decision.targetId, {
19549
19583
  content: decision.content,
19584
+ expectedContent,
19550
19585
  freeFormOnly: true,
19551
19586
  proofCountIncrement: 1,
19552
19587
  observationSourceIds: options.sourceChunkIds,
@@ -19559,10 +19594,10 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
19559
19594
  ...factTypeUpdate !== void 0 && { factType: factTypeUpdate }
19560
19595
  });
19561
19596
  if (!updated) {
19562
- await assertMergeTargetGoneOrThrow(ctx, decision.targetId);
19597
+ await assertMergeTargetGoneOrThrow(ctx, decision.targetId, expectedContent);
19563
19598
  return abandonToRace(
19564
19599
  options,
19565
- `update: target ${decision.targetId} deleted mid-write (consolidated rewrite lost)`
19600
+ `update: target ${decision.targetId} changed mid-write (consolidated rewrite lost)`
19566
19601
  );
19567
19602
  }
19568
19603
  cacheRowVector(
@@ -19589,9 +19624,9 @@ async function tryConsolidate(trimmed, ctx, options, prepared) {
19589
19624
  );
19590
19625
  return null;
19591
19626
  }
19592
- async function assertMergeTargetGoneOrThrow(ctx, targetId) {
19627
+ async function assertMergeTargetGoneOrThrow(ctx, targetId, expectedContent) {
19593
19628
  const stillExists = await (ctx.persistence.getFresh ? ctx.persistence.getFresh(targetId) : ctx.persistence.get(targetId));
19594
- if (stillExists && (stillExists.kind === null || stillExists.kind === void 0)) {
19629
+ if (stillExists && (stillExists.kind === null || stillExists.kind === void 0) && (expectedContent === void 0 || stillExists.content === expectedContent)) {
19595
19630
  throw new RetainError(
19596
19631
  "merge-not-persisted",
19597
19632
  `retain: merge into memory ${targetId} failed to persist`
@@ -23004,16 +23039,16 @@ function createRemoteMemoryPipeline(options) {
23004
23039
  create: (input) => write(createRow(input), 0),
23005
23040
  update: async (id2, patch) => {
23006
23041
  const existing = await get(id2);
23007
- if (!existing || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
23042
+ if (!existing || patch.expectedContent !== void 0 && existing.content !== patch.expectedContent || patch.freeFormOnly && existing.kind !== null && existing.kind !== void 0)
23008
23043
  return null;
23009
23044
  const snapshot = snapshots.get(id2);
23010
23045
  const memory = {
23011
23046
  ...snapshot.memory,
23012
- content: patch.content,
23047
+ content: patch.content ?? snapshot.memory.content,
23013
23048
  updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Math.max(Date.now(), (snapshot.memory.topics_extracted_at ?? 0) + 1)
23014
23049
  };
23015
23050
  if (patch.scope !== void 0) memory.scope = patch.scope;
23016
- if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
23051
+ if (patch.embedding === void 0 && patch.content !== void 0 && patch.content !== snapshot.memory.content) {
23017
23052
  delete memory.embedding;
23018
23053
  delete memory.embedding_model;
23019
23054
  }
@@ -27685,6 +27720,7 @@ async function getPdfjs() {
27685
27720
  return pdfjsModule;
27686
27721
  }
27687
27722
  async function withPdfDocument(pdfDataUrl, fn) {
27723
+ assertFileUrlAllowed(pdfDataUrl);
27688
27724
  const pdfjs = await getPdfjs();
27689
27725
  const loadingTask = pdfjs.getDocument(pdfDataUrl);
27690
27726
  let pdf;
@@ -28481,6 +28517,7 @@ async function preprocessFiles(files, options = {}) {
28481
28517
  skip("no_data");
28482
28518
  continue;
28483
28519
  }
28520
+ assertFileUrlAllowed(file.url);
28484
28521
  const fileWithData = {
28485
28522
  ...file,
28486
28523
  dataUrl: file.url
@@ -36750,20 +36787,27 @@ function useSubscription(options = {}) {
36750
36787
  }
36751
36788
 
36752
36789
  // src/react/useTools.ts
36753
- import { useCallback as useCallback18, useEffect as useEffect12, useRef as useRef9, useState as useState16 } from "react";
36790
+ import { useCallback as useCallback18, useEffect as useEffect12, useMemo as useMemo10, useRef as useRef9, useState as useState16 } from "react";
36754
36791
  function useTools(options) {
36755
36792
  const { getToken, baseUrl = BASE_URL, includeTools, autoFetch = true } = options;
36756
- const [tools, setTools] = useState16([]);
36793
+ const [allTools, setAllTools] = useState16([]);
36757
36794
  const [checksum, setChecksum] = useState16(getToolsChecksum2);
36758
36795
  const [isLoading, setIsLoading] = useState16(false);
36759
36796
  const [error, setError] = useState16(null);
36797
+ const includeToolsRef = useRef9(includeTools);
36798
+ if (includeTools !== includeToolsRef.current && (includeTools === void 0 || includeToolsRef.current === void 0 || includeTools.length !== includeToolsRef.current.length || includeTools.some((name, i) => name !== includeToolsRef.current?.[i]))) {
36799
+ includeToolsRef.current = includeTools;
36800
+ }
36801
+ const stableIncludeTools = includeToolsRef.current;
36802
+ const tools = useMemo10(
36803
+ () => filterServerTools(allTools, stableIncludeTools),
36804
+ [allTools, stableIncludeTools]
36805
+ );
36760
36806
  const getTokenRef = useRef9(getToken);
36761
36807
  const baseUrlRef = useRef9(baseUrl);
36762
- const includeToolsRef = useRef9(includeTools);
36763
36808
  useEffect12(() => {
36764
36809
  getTokenRef.current = getToken;
36765
36810
  baseUrlRef.current = baseUrl;
36766
- includeToolsRef.current = includeTools;
36767
36811
  });
36768
36812
  const fetchTools = useCallback18(async (forceRefresh = false) => {
36769
36813
  setIsLoading(true);
@@ -36774,8 +36818,7 @@ function useTools(options) {
36774
36818
  baseUrl: baseUrlRef.current,
36775
36819
  forceRefresh
36776
36820
  });
36777
- const filteredTools = filterServerTools(fetchedTools, includeToolsRef.current);
36778
- setTools(filteredTools);
36821
+ setAllTools(fetchedTools);
36779
36822
  setChecksum(getToolsChecksum2());
36780
36823
  } catch (err) {
36781
36824
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -36799,11 +36842,6 @@ function useTools(options) {
36799
36842
  },
36800
36843
  [refresh]
36801
36844
  );
36802
- useEffect12(() => {
36803
- if (tools.length > 0 && includeTools !== void 0) {
36804
- setTools((currentTools) => filterServerTools(currentTools, includeTools));
36805
- }
36806
- }, [includeTools, tools.length]);
36807
36845
  const hasFetchedRef = useRef9(false);
36808
36846
  useEffect12(() => {
36809
36847
  if (autoFetch && !hasFetchedRef.current) {
@@ -36830,7 +36868,7 @@ import {
36830
36868
  createElement as createElement4,
36831
36869
  useCallback as useCallback19,
36832
36870
  useContext as useContext5,
36833
- useMemo as useMemo10,
36871
+ useMemo as useMemo11,
36834
36872
  useRef as useRef10,
36835
36873
  useState as useState17
36836
36874
  } from "react";
@@ -36967,7 +37005,7 @@ function UIInteractionProvider({
36967
37005
  },
36968
37006
  [pendingInteractions]
36969
37007
  );
36970
- const contextValue = useMemo10(
37008
+ const contextValue = useMemo11(
36971
37009
  () => ({
36972
37010
  pendingInteractions,
36973
37011
  createInteraction,
@@ -36991,7 +37029,7 @@ function UIInteractionProvider({
36991
37029
  }
36992
37030
 
36993
37031
  // src/react/useVoice.ts
36994
- import { useCallback as useCallback20, useMemo as useMemo11, useRef as useRef11, useState as useState18 } from "react";
37032
+ import { useCallback as useCallback20, useMemo as useMemo12, useRef as useRef11, useState as useState18 } from "react";
36995
37033
  function getOnDeviceSpeechRecognition() {
36996
37034
  if (typeof window === "undefined") return null;
36997
37035
  if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
@@ -37195,7 +37233,7 @@ function useVoice(options) {
37195
37233
  },
37196
37234
  [recording, loadPipeline, options?.language]
37197
37235
  );
37198
- const nativeSpeechAvailable = useMemo11(() => getOnDeviceSpeechRecognition() !== null, []);
37236
+ const nativeSpeechAvailable = useMemo12(() => getOnDeviceSpeechRecognition() !== null, []);
37199
37237
  const [isNativeListening, setIsNativeListening] = useState18(false);
37200
37238
  const nativeRecognitionRef = useRef11(null);
37201
37239
  const nativeTextRef = useRef11("");
@@ -710,6 +710,12 @@ function assertTransportMatchesEndpoint(transport, endpoint) {
710
710
  `endpointOverride "${endpoint}" is the other transport's endpoint, but transport is "${transport}". The request body is built for the transport, so this sends the wrong shape and 400s without retry.`
711
711
  );
712
712
  }
713
+ var TIME_BUDGET_EXHAUSTED = {
714
+ kind: "terminal",
715
+ code: "time-budget-exhausted",
716
+ reason: "time budget exhausted"
717
+ };
718
+ var MAX_TIMER_DELAY_MS = 2147483647;
713
719
  var RETRYABLE_HTTP = /* @__PURE__ */ new Set([408, 409, 425, 429]);
714
720
  function isRetryableStatus(status) {
715
721
  return status >= 500 || RETRYABLE_HTTP.has(status);
@@ -765,7 +771,8 @@ async function callPortalJsonCompletion(req) {
765
771
  }
766
772
  const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
767
773
  const startedAt = Date.now();
768
- const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
774
+ const deadlineAt = req.totalTimeoutMs === void 0 ? void 0 : startedAt + req.totalTimeoutMs;
775
+ const overBudget = () => deadlineAt !== void 0 && Date.now() >= deadlineAt;
769
776
  let lastFailure;
770
777
  let reinforce = false;
771
778
  const giveUp = () => {
@@ -778,17 +785,11 @@ async function callPortalJsonCompletion(req) {
778
785
  lastFailure = { reason: "time-budget-exhausted", attempts: attempt - 1 };
779
786
  break;
780
787
  }
781
- const attemptReq = req.totalTimeoutMs !== void 0 ? {
782
- ...req,
783
- timeoutMs: Math.max(
784
- 1,
785
- Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
786
- ),
787
- ...reinforce && { reinforceJsonContract: true }
788
- } : reinforce ? { ...req, reinforceJsonContract: true } : req;
788
+ const attemptReq = reinforce ? { ...req, reinforceJsonContract: true } : req;
789
789
  const outcome = await attemptPortalJson(
790
790
  { ...attemptReq, transport },
791
- endpoint
791
+ endpoint,
792
+ deadlineAt
792
793
  );
793
794
  if (outcome.kind === "ok") {
794
795
  req.onAttempt?.({ attempt, ok: true });
@@ -828,13 +829,38 @@ async function callPortalJsonCompletion(req) {
828
829
  }
829
830
  return giveUp();
830
831
  }
831
- async function attemptPortalJson(req, endpoint) {
832
+ async function attemptPortalJson(req, endpoint, deadlineAt) {
833
+ const controller = new AbortController();
834
+ if (deadlineAt === void 0 || deadlineAt - Date.now() > MAX_TIMER_DELAY_MS) {
835
+ return requestPortalJson(req, endpoint, controller);
836
+ }
837
+ const remainingMs = deadlineAt - Date.now();
838
+ if (remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
839
+ let timer;
840
+ try {
841
+ const outcome = await Promise.race([
842
+ new Promise((resolve) => {
843
+ timer = setTimeout(() => {
844
+ resolve(TIME_BUDGET_EXHAUSTED);
845
+ controller.abort();
846
+ }, remainingMs);
847
+ }),
848
+ requestPortalJson(req, endpoint, controller, deadlineAt)
849
+ ]);
850
+ return Date.now() >= deadlineAt ? TIME_BUDGET_EXHAUSTED : outcome;
851
+ } finally {
852
+ clearTimeout(timer);
853
+ }
854
+ }
855
+ async function requestPortalJson(req, endpoint, controller, deadlineAt) {
832
856
  const baseUrl = req.baseUrl ?? defaultBaseUrl();
833
857
  const fetchImpl = req.fetchFn ?? fetch;
834
- const timeoutMs = req.timeoutMs ?? 6e4;
835
858
  const authHeaders = await resolvePortalAuthHeaders(req, req.tag);
859
+ const remainingMs = deadlineAt === void 0 ? Infinity : deadlineAt - Date.now();
860
+ if (controller.signal.aborted || remainingMs <= 0) return TIME_BUDGET_EXHAUSTED;
836
861
  if (authHeaders === null)
837
862
  return { kind: "terminal", code: "auth-unavailable", reason: "auth unavailable (no token)" };
863
+ const timeoutMs = Math.min(req.timeoutMs ?? 6e4, remainingMs);
838
864
  const usesPrefill = req.transport !== "responses" && req.model.startsWith("anthropic/");
839
865
  const prefill = usesPrefill ? "{" : "";
840
866
  const messages = [
@@ -844,7 +870,6 @@ async function attemptPortalJson(req, endpoint) {
844
870
  ];
845
871
  if (prefill) messages.push({ role: "assistant", content: prefill });
846
872
  const supportsJsonObjectFormat = supportsResponseFormat(req.model);
847
- const controller = new AbortController();
848
873
  const timer = setTimeout(() => controller.abort(), timeoutMs);
849
874
  const requestBody = req.transport === "responses" ? {
850
875
  model: req.model,
@@ -4,7 +4,7 @@ import {
4
4
  notifyConsolidationFallback,
5
5
  requiresResponsesTransport,
6
6
  resolvePiiRedactor
7
- } from "./chunk-AU3Z7NBC.mjs";
7
+ } from "./chunk-QEROZ4VH.mjs";
8
8
  import "./chunk-3RPGXXPZ.mjs";
9
9
 
10
10
  // src/lib/memory/consolidate.ts