@t2000/engine 0.54.2 → 0.56.0

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/index.js CHANGED
@@ -532,11 +532,139 @@ function resetDefiCacheStore() {
532
532
  activeStore = new InMemoryDefiCacheStore();
533
533
  }
534
534
 
535
+ // src/wallet-cache.ts
536
+ var InMemoryWalletCacheStore = class {
537
+ store = /* @__PURE__ */ new Map();
538
+ async get(address) {
539
+ const slot = this.store.get(address.toLowerCase());
540
+ if (!slot) return null;
541
+ if (Date.now() >= slot.expiresAt) {
542
+ this.store.delete(address.toLowerCase());
543
+ return null;
544
+ }
545
+ return slot.entry;
546
+ }
547
+ async set(address, entry, ttlSec) {
548
+ this.store.set(address.toLowerCase(), {
549
+ entry,
550
+ expiresAt: Date.now() + ttlSec * 1e3
551
+ });
552
+ }
553
+ async delete(address) {
554
+ this.store.delete(address.toLowerCase());
555
+ }
556
+ async clear() {
557
+ this.store.clear();
558
+ }
559
+ };
560
+ var activeStore2 = new InMemoryWalletCacheStore();
561
+ function setWalletCacheStore(store) {
562
+ activeStore2 = store;
563
+ }
564
+ function getWalletCacheStore() {
565
+ return activeStore2;
566
+ }
567
+ function resetWalletCacheStore() {
568
+ activeStore2 = new InMemoryWalletCacheStore();
569
+ }
570
+
571
+ // src/cross-instance-lock.ts
572
+ var InMemoryFetchLock = class {
573
+ held = /* @__PURE__ */ new Map();
574
+ async acquire(key, leaseSec) {
575
+ const now = Date.now();
576
+ const expiry = this.held.get(key);
577
+ if (expiry !== void 0 && expiry > now) return false;
578
+ this.held.set(key, now + leaseSec * 1e3);
579
+ return true;
580
+ }
581
+ async release(key) {
582
+ this.held.delete(key);
583
+ }
584
+ };
585
+ var activeLock = new InMemoryFetchLock();
586
+ function setFetchLock(lock) {
587
+ activeLock = lock;
588
+ }
589
+ function getFetchLock() {
590
+ return activeLock;
591
+ }
592
+ function resetFetchLock() {
593
+ activeLock = new InMemoryFetchLock();
594
+ }
595
+ var DEFAULT_LEASE_SEC = 15;
596
+ var DEFAULT_POLL_BUDGET_MS = 4500;
597
+ var DEFAULT_POLL_INTERVAL_MS = 100;
598
+ async function awaitOrFetch(key, fetcher, opts = {}) {
599
+ const lock = opts.lock ?? getFetchLock();
600
+ const leaseSec = opts.leaseSec ?? DEFAULT_LEASE_SEC;
601
+ const pollBudgetMs = opts.pollBudgetMs ?? DEFAULT_POLL_BUDGET_MS;
602
+ const pollIntervalMs = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
603
+ const rng = opts.rng ?? Math.random;
604
+ const now = opts.now ?? Date.now;
605
+ const sleep2 = opts.sleep ?? ((ms) => new Promise((resolve, reject) => {
606
+ const timer = setTimeout(resolve, ms);
607
+ if (opts.signal) {
608
+ const onAbort = () => {
609
+ clearTimeout(timer);
610
+ reject(new DOMException("Aborted", "AbortError"));
611
+ };
612
+ if (opts.signal.aborted) onAbort();
613
+ else opts.signal.addEventListener("abort", onAbort, { once: true });
614
+ }
615
+ }));
616
+ let acquired = false;
617
+ try {
618
+ acquired = await lock.acquire(key, leaseSec);
619
+ } catch (err) {
620
+ console.warn(`[fetch-lock] acquire(${key}) threw; falling through to direct fetch:`, err);
621
+ return fetcher();
622
+ }
623
+ if (acquired) {
624
+ try {
625
+ return await fetcher();
626
+ } finally {
627
+ try {
628
+ await lock.release(key);
629
+ } catch (err) {
630
+ console.warn(`[fetch-lock] release(${key}) failed (non-fatal):`, err);
631
+ }
632
+ }
633
+ }
634
+ if (!opts.pollCache) {
635
+ return fetcher();
636
+ }
637
+ const deadline = now() + pollBudgetMs;
638
+ while (now() < deadline) {
639
+ const jitterPx = (rng() * 0.4 - 0.2) * pollIntervalMs;
640
+ const wait = Math.max(0, pollIntervalMs + jitterPx);
641
+ try {
642
+ await sleep2(wait);
643
+ } catch (err) {
644
+ if (err?.name === "AbortError") throw err;
645
+ return fetcher();
646
+ }
647
+ let cached = null;
648
+ try {
649
+ cached = await opts.pollCache();
650
+ } catch (err) {
651
+ console.warn(`[fetch-lock] pollCache(${key}) threw; continuing to poll:`, err);
652
+ }
653
+ if (cached !== null) return cached;
654
+ }
655
+ return fetcher();
656
+ }
657
+
535
658
  // src/blockvision-prices.ts
536
659
  var BLOCKVISION_BASE = "https://api.blockvision.org/v2/sui";
537
660
  var PORTFOLIO_TIMEOUT_MS = 4e3;
538
661
  var PRICES_TIMEOUT_MS = 3e3;
539
662
  var CACHE_TTL_MS = 6e4;
663
+ var WALLET_FRESH_TTL_MS_BLOCKVISION = 6e4;
664
+ var WALLET_FRESH_TTL_MS_DEGRADED = 15e3;
665
+ var WALLET_STICKY_TTL_SEC = 30 * 60;
666
+ var WALLET_LOCK_KEY = (address) => `bv-lock:wallet:${address.toLowerCase()}`;
667
+ var DEFI_LOCK_KEY = (address) => `bv-lock:defi:${address.toLowerCase()}`;
540
668
  var BV_RETRY_MAX_ATTEMPTS = 3;
541
669
  var BV_RETRY_BASE_DELAY_MS = 250;
542
670
  var BV_RETRY_BACKOFF_FACTOR = 3;
@@ -617,7 +745,6 @@ async function fetchBlockVisionWithRetry(url, init, opts = {}) {
617
745
  if (lastResponse) return lastResponse;
618
746
  throw lastError ?? new Error("fetch failed after retries");
619
747
  }
620
- var DEGRADED_CACHE_TTL_MS = 15e3;
621
748
  var PRICE_LIST_CHUNK = 10;
622
749
  var STABLE_USD_PRICES = {
623
750
  "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC": 1,
@@ -627,38 +754,103 @@ var STABLE_USD_PRICES = {
627
754
  "0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN": 1,
628
755
  "0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN": 1
629
756
  };
630
- var portfolioCache = /* @__PURE__ */ new Map();
631
757
  var portfolioInflight = /* @__PURE__ */ new Map();
632
758
  var priceMapCache = null;
759
+ function walletFreshTtlMs(source) {
760
+ switch (source) {
761
+ case "blockvision":
762
+ return WALLET_FRESH_TTL_MS_BLOCKVISION;
763
+ case "sui-rpc-degraded":
764
+ return WALLET_FRESH_TTL_MS_DEGRADED;
765
+ }
766
+ }
767
+ async function safeWalletStoreSet(store, address, entry, ttlSec) {
768
+ try {
769
+ await store.set(address, entry, ttlSec);
770
+ } catch (err) {
771
+ console.warn("[wallet] cache set failed (non-fatal):", err);
772
+ }
773
+ }
774
+ async function safeWalletStoreGet(store, address) {
775
+ try {
776
+ return await store.get(address);
777
+ } catch (err) {
778
+ console.warn("[wallet] cache get failed (continuing as cache miss):", err);
779
+ return null;
780
+ }
781
+ }
633
782
  async function fetchAddressPortfolio(address, apiKey, fallbackRpcUrl) {
634
- const now = Date.now();
635
- const cached = portfolioCache.get(address);
636
- if (cached && now - cached.ts < CACHE_TTL_MS) {
637
- return cached.data;
783
+ const store = getWalletCacheStore();
784
+ const cachedEntry = await safeWalletStoreGet(store, address);
785
+ if (cachedEntry) {
786
+ const ageMs = Date.now() - cachedEntry.pricedAt;
787
+ if (ageMs < walletFreshTtlMs(cachedEntry.data.source)) {
788
+ return cachedEntry.data;
789
+ }
638
790
  }
639
- let inflight = portfolioInflight.get(address);
640
- if (inflight) return inflight;
641
- inflight = (async () => {
791
+ const existing = portfolioInflight.get(address);
792
+ if (existing) return existing;
793
+ const promise = (async () => {
642
794
  try {
643
- if (apiKey && apiKey.trim().length > 0) {
644
- const blockvision = await fetchPortfolioFromBlockVision(address, apiKey);
645
- if (blockvision) {
646
- portfolioCache.set(address, { data: blockvision, ts: Date.now() });
647
- return blockvision;
795
+ return await awaitOrFetch(
796
+ WALLET_LOCK_KEY(address),
797
+ // ----------------------------------------------------------
798
+ // Leader path runs after we've won the cross-instance lock.
799
+ // Re-checks the cache (small window where another leader on a
800
+ // different process just wrote) before paying for the BV call.
801
+ // ----------------------------------------------------------
802
+ async () => {
803
+ const recheck = await safeWalletStoreGet(store, address);
804
+ if (recheck) {
805
+ const ageMs = Date.now() - recheck.pricedAt;
806
+ if (ageMs < walletFreshTtlMs(recheck.data.source)) {
807
+ return recheck.data;
808
+ }
809
+ }
810
+ if (apiKey && apiKey.trim().length > 0) {
811
+ const blockvision = await fetchPortfolioFromBlockVision(address, apiKey);
812
+ if (blockvision) {
813
+ await safeWalletStoreSet(
814
+ store,
815
+ address,
816
+ { data: blockvision, pricedAt: Date.now() },
817
+ WALLET_STICKY_TTL_SEC
818
+ );
819
+ return blockvision;
820
+ }
821
+ }
822
+ const degraded = await fetchPortfolioFromSuiRpc(address, apiKey, fallbackRpcUrl);
823
+ const stickyCandidate = recheck && recheck.data.source === "blockvision" && recheck.data.totalUsd > 0 ? recheck : cachedEntry && cachedEntry.data.source === "blockvision" && cachedEntry.data.totalUsd > 0 ? cachedEntry : null;
824
+ const stickyFresh = stickyCandidate && Date.now() - stickyCandidate.pricedAt < WALLET_STICKY_TTL_SEC * 1e3;
825
+ if (stickyFresh) {
826
+ return stickyCandidate.data;
827
+ }
828
+ await safeWalletStoreSet(
829
+ store,
830
+ address,
831
+ { data: degraded, pricedAt: Date.now() },
832
+ Math.ceil(WALLET_FRESH_TTL_MS_DEGRADED / 1e3)
833
+ );
834
+ return degraded;
835
+ },
836
+ {
837
+ // Followers poll the wallet cache while the leader fetches.
838
+ // Returns non-null only when the leader has written a
839
+ // fresh-for-source entry — stale entries keep the poll going.
840
+ pollCache: async () => {
841
+ const e = await safeWalletStoreGet(store, address);
842
+ if (!e) return null;
843
+ const ageMs = Date.now() - e.pricedAt;
844
+ return ageMs < walletFreshTtlMs(e.data.source) ? e.data : null;
845
+ }
648
846
  }
649
- }
650
- const degraded = await fetchPortfolioFromSuiRpc(address, apiKey, fallbackRpcUrl);
651
- portfolioCache.set(address, {
652
- data: degraded,
653
- ts: Date.now() - (CACHE_TTL_MS - DEGRADED_CACHE_TTL_MS)
654
- });
655
- return degraded;
847
+ );
656
848
  } finally {
657
849
  portfolioInflight.delete(address);
658
850
  }
659
851
  })();
660
- portfolioInflight.set(address, inflight);
661
- return inflight;
852
+ portfolioInflight.set(address, promise);
853
+ return promise;
662
854
  }
663
855
  async function fetchPortfolioFromBlockVision(address, apiKey) {
664
856
  const url = `${BLOCKVISION_BASE}/account/coins?account=${encodeURIComponent(address)}`;
@@ -889,6 +1081,14 @@ async function safeStoreSet(store, address, entry) {
889
1081
  console.warn("[defi] cache set failed (non-fatal):", err);
890
1082
  }
891
1083
  }
1084
+ async function safeDefiStoreGet(store, address) {
1085
+ try {
1086
+ return await store.get(address);
1087
+ } catch (err) {
1088
+ console.warn("[defi] cache get failed (continuing as cache miss):", err);
1089
+ return null;
1090
+ }
1091
+ }
892
1092
  var warnedMissingApiKey = false;
893
1093
  async function fetchAddressDefiPortfolio(address, apiKey, priceHints = {}) {
894
1094
  if (!apiKey || apiKey.trim().length === 0) {
@@ -901,15 +1101,9 @@ async function fetchAddressDefiPortfolio(address, apiKey, priceHints = {}) {
901
1101
  return { totalUsd: 0, perProtocol: {}, pricedAt: Date.now(), source: "degraded" };
902
1102
  }
903
1103
  const store = getDefiCacheStore();
904
- const now = Date.now();
905
- let cachedEntry = null;
906
- try {
907
- cachedEntry = await store.get(address);
908
- } catch (err) {
909
- console.warn("[defi] cache get failed (continuing as cache miss):", err);
910
- }
1104
+ const cachedEntry = await safeDefiStoreGet(store, address);
911
1105
  if (cachedEntry) {
912
- const ageMs = now - cachedEntry.pricedAt;
1106
+ const ageMs = Date.now() - cachedEntry.pricedAt;
913
1107
  const freshTtlMs = freshTtlForSource(cachedEntry.data.source);
914
1108
  if (ageMs < freshTtlMs) {
915
1109
  return cachedEntry.data;
@@ -919,82 +1113,108 @@ async function fetchAddressDefiPortfolio(address, apiKey, priceHints = {}) {
919
1113
  if (inflight) return inflight;
920
1114
  inflight = (async () => {
921
1115
  try {
922
- const settled = await Promise.allSettled(
923
- DEFI_PROTOCOLS.map((p) => fetchOneDefiProtocol(address, p, apiKey))
924
- );
925
- const seen = /* @__PURE__ */ new Set();
926
- for (const s of settled) {
927
- if (s.status === "fulfilled" && s.value) collectCoinTypes(s.value, seen);
928
- }
929
- const normalizedHints = {};
930
- for (const [k, v] of Object.entries(priceHints)) {
931
- normalizedHints[normalizeCoinType(k)] = v;
932
- }
933
- const missing = Array.from(seen).filter((ct) => {
934
- const norm = normalizeCoinType(ct);
935
- return !normalizedHints[norm] && !STABLE_USD_PRICES[norm];
936
- });
937
- let fetchedPrices = {};
938
- if (missing.length > 0) {
939
- try {
940
- fetchedPrices = await fetchTokenPrices(missing, apiKey);
941
- } catch (err) {
942
- console.warn("[defi] fill-missing-prices failed:", err);
943
- }
944
- }
945
- const prices = { ...normalizedHints };
946
- for (const [ct, v] of Object.entries(fetchedPrices)) {
947
- prices[normalizeCoinType(ct)] ??= v.price;
948
- }
949
- for (const [ct, p] of Object.entries(STABLE_USD_PRICES)) {
950
- prices[normalizeCoinType(ct)] ??= p;
951
- }
952
- let totalUsd = 0;
953
- let failures = 0;
954
- const perProtocol = {};
955
- for (let i = 0; i < DEFI_PROTOCOLS.length; i++) {
956
- const proto = DEFI_PROTOCOLS[i];
957
- const s = settled[i];
958
- if (s.status !== "fulfilled" || !s.value) {
959
- failures++;
960
- continue;
961
- }
962
- try {
963
- const usd = normalizeProtocol(proto, s.value, prices);
964
- if (Number.isFinite(usd) && usd !== 0) {
965
- perProtocol[proto] = usd;
966
- totalUsd += usd;
1116
+ return await awaitOrFetch(
1117
+ DEFI_LOCK_KEY(address),
1118
+ // Leader path — runs after acquiring the lock.
1119
+ async () => {
1120
+ const recheck = await safeDefiStoreGet(store, address);
1121
+ if (recheck) {
1122
+ const ageMs = Date.now() - recheck.pricedAt;
1123
+ if (ageMs < freshTtlForSource(recheck.data.source)) {
1124
+ return recheck.data;
1125
+ }
1126
+ }
1127
+ const stickyBasis = recheck ?? cachedEntry;
1128
+ const fanoutAt = Date.now();
1129
+ const settled = await Promise.allSettled(
1130
+ DEFI_PROTOCOLS.map((p) => fetchOneDefiProtocol(address, p, apiKey))
1131
+ );
1132
+ const seen = /* @__PURE__ */ new Set();
1133
+ for (const s of settled) {
1134
+ if (s.status === "fulfilled" && s.value) collectCoinTypes(s.value, seen);
1135
+ }
1136
+ const normalizedHints = {};
1137
+ for (const [k, v] of Object.entries(priceHints)) {
1138
+ normalizedHints[normalizeCoinType(k)] = v;
1139
+ }
1140
+ const missing = Array.from(seen).filter((ct) => {
1141
+ const norm = normalizeCoinType(ct);
1142
+ return !normalizedHints[norm] && !STABLE_USD_PRICES[norm];
1143
+ });
1144
+ let fetchedPrices = {};
1145
+ if (missing.length > 0) {
1146
+ try {
1147
+ fetchedPrices = await fetchTokenPrices(missing, apiKey);
1148
+ } catch (err) {
1149
+ console.warn("[defi] fill-missing-prices failed:", err);
1150
+ }
1151
+ }
1152
+ const prices = { ...normalizedHints };
1153
+ for (const [ct, v] of Object.entries(fetchedPrices)) {
1154
+ prices[normalizeCoinType(ct)] ??= v.price;
1155
+ }
1156
+ for (const [ct, p] of Object.entries(STABLE_USD_PRICES)) {
1157
+ prices[normalizeCoinType(ct)] ??= p;
1158
+ }
1159
+ let totalUsd = 0;
1160
+ let failures = 0;
1161
+ const perProtocol = {};
1162
+ for (let i = 0; i < DEFI_PROTOCOLS.length; i++) {
1163
+ const proto = DEFI_PROTOCOLS[i];
1164
+ const s = settled[i];
1165
+ if (s.status !== "fulfilled" || !s.value) {
1166
+ failures++;
1167
+ continue;
1168
+ }
1169
+ try {
1170
+ const usd = normalizeProtocol(proto, s.value, prices);
1171
+ if (Number.isFinite(usd) && usd !== 0) {
1172
+ perProtocol[proto] = usd;
1173
+ totalUsd += usd;
1174
+ }
1175
+ } catch (err) {
1176
+ console.warn(`[defi] ${proto} normaliser threw:`, err);
1177
+ failures++;
1178
+ }
1179
+ }
1180
+ if (totalUsd < 0) totalUsd = 0;
1181
+ const fetchedAt = Date.now();
1182
+ const summary = {
1183
+ totalUsd,
1184
+ perProtocol,
1185
+ pricedAt: fetchedAt,
1186
+ source: failures === DEFI_PROTOCOLS.length ? "degraded" : failures > 0 ? "partial" : "blockvision"
1187
+ };
1188
+ const cachedPositive = stickyBasis && stickyBasis.data.totalUsd > 0 && fanoutAt - stickyBasis.pricedAt < DEFI_STICKY_TTL_SEC * 1e3;
1189
+ if (summary.source === "blockvision") {
1190
+ await safeStoreSet(store, address, { data: summary, pricedAt: fetchedAt });
1191
+ return summary;
1192
+ }
1193
+ if (summary.source === "partial" && summary.totalUsd > 0) {
1194
+ await safeStoreSet(store, address, { data: summary, pricedAt: fetchedAt });
1195
+ return summary;
1196
+ }
1197
+ if (cachedPositive) {
1198
+ const stale = {
1199
+ ...stickyBasis.data,
1200
+ source: "partial-stale"
1201
+ };
1202
+ return stale;
1203
+ }
1204
+ return summary;
1205
+ },
1206
+ {
1207
+ // Followers poll the DeFi cache while the leader fans out.
1208
+ // Returns non-null only when the leader has written a
1209
+ // fresh-for-source entry — stale entries keep the poll going.
1210
+ pollCache: async () => {
1211
+ const e = await safeDefiStoreGet(store, address);
1212
+ if (!e) return null;
1213
+ const ageMs = Date.now() - e.pricedAt;
1214
+ return ageMs < freshTtlForSource(e.data.source) ? e.data : null;
967
1215
  }
968
- } catch (err) {
969
- console.warn(`[defi] ${proto} normaliser threw:`, err);
970
- failures++;
971
1216
  }
972
- }
973
- if (totalUsd < 0) totalUsd = 0;
974
- const fetchedAt = Date.now();
975
- const summary = {
976
- totalUsd,
977
- perProtocol,
978
- pricedAt: fetchedAt,
979
- source: failures === DEFI_PROTOCOLS.length ? "degraded" : failures > 0 ? "partial" : "blockvision"
980
- };
981
- const cachedPositive = cachedEntry && cachedEntry.data.totalUsd > 0 && now - cachedEntry.pricedAt < DEFI_STICKY_TTL_SEC * 1e3;
982
- if (summary.source === "blockvision") {
983
- await safeStoreSet(store, address, { data: summary, pricedAt: fetchedAt });
984
- return summary;
985
- }
986
- if (summary.source === "partial" && summary.totalUsd > 0) {
987
- await safeStoreSet(store, address, { data: summary, pricedAt: fetchedAt });
988
- return summary;
989
- }
990
- if (cachedPositive) {
991
- const stale = {
992
- ...cachedEntry.data,
993
- source: "partial-stale"
994
- };
995
- return stale;
996
- }
997
- return summary;
1217
+ );
998
1218
  } finally {
999
1219
  defiInflight.delete(address);
1000
1220
  }
@@ -1280,12 +1500,12 @@ function normalizeProtocol(protocol, result, prices) {
1280
1500
  if (bespoke) return bespoke(result, prices);
1281
1501
  return walkProtocolResponse(result, prices);
1282
1502
  }
1283
- function clearPortfolioCache() {
1284
- portfolioCache.clear();
1503
+ async function clearPortfolioCache() {
1504
+ await getWalletCacheStore().clear();
1285
1505
  portfolioInflight.clear();
1286
1506
  }
1287
- function clearPortfolioCacheFor(address) {
1288
- portfolioCache.delete(address);
1507
+ async function clearPortfolioCacheFor(address) {
1508
+ await getWalletCacheStore().delete(address);
1289
1509
  portfolioInflight.delete(address);
1290
1510
  }
1291
1511
  function clearPriceMapCache() {
@@ -4532,7 +4752,7 @@ function getModifiableFields(toolName) {
4532
4752
  }
4533
4753
 
4534
4754
  // src/prompt.ts
4535
- var DEFAULT_SYSTEM_PROMPT = `You are Audric \u2014 a financial agent on Sui. Audric is exactly five products: Audric Passport (the trust layer \u2014 Google sign-in, non-custodial wallet, tap-to-confirm consent, sponsored gas \u2014 wraps every other product), Audric Intelligence (you \u2014 the 5-system brain: Agent Harness with 34 tools, Reasoning Engine with 9 guards and 7 skill recipes, Silent Profile, Chain Memory, AdviceLog), Audric Finance (manage money on Sui \u2014 Save via NAVI lending at 3-8% APY USDC, Credit via NAVI borrowing with health factor, Swap via Cetus aggregator across 20+ DEXs at 0.1% fee, Charts for yield/health/portfolio viz), Audric Pay (move money \u2014 send USDC, receive via payment links / invoices / QR; free, global, instant on Sui), and Audric Store (creator marketplace, ships Phase 5 \u2014 say "coming soon" if asked). Save, swap, borrow, repay, withdraw, charts \u2192 Audric Finance. Send, receive, payment-link, invoice, QR \u2192 Audric Pay. Your silent context (profile, memory, chain facts, advice log) shapes your replies but never surfaces as a notification \u2014 you act only when the user asks, and every write waits on their tap-to-confirm via Passport. You can also call 41 paid APIs (music, image, research, translation, weather, fulfilment) via MPP micropayments using the pay_api tool \u2014 this is an internal capability, not a promoted product, so only mention it when the user asks for something that needs it.
4755
+ var DEFAULT_SYSTEM_PROMPT = `You are Audric \u2014 a financial agent on Sui. Audric is exactly five products: Audric Passport (the trust layer \u2014 Google sign-in, non-custodial wallet, tap-to-confirm consent, sponsored gas \u2014 wraps every other product), Audric Intelligence (you \u2014 the 5-system brain: Agent Harness with 34 tools, Reasoning Engine with 14 guards and 6 skill recipes, Silent Profile, Chain Memory, AdviceLog), Audric Finance (manage money on Sui \u2014 Save via NAVI lending at 3-8% APY USDC, Credit via NAVI borrowing with health factor, Swap via Cetus aggregator across 20+ DEXs at 0.1% fee, Charts for yield/health/portfolio viz), Audric Pay (move money \u2014 send USDC, receive via payment links / invoices / QR; free, global, instant on Sui), and Audric Store (creator marketplace, ships Phase 5 \u2014 say "coming soon" if asked). Save, swap, borrow, repay, withdraw, charts \u2192 Audric Finance. Send, receive, payment-link, invoice, QR \u2192 Audric Pay. Your silent context (profile, memory, chain facts, advice log) shapes your replies but never surfaces as a notification \u2014 you act only when the user asks, and every write waits on their tap-to-confirm via Passport. You can also call 41 paid APIs (music, image, research, translation, weather, fulfilment) via MPP micropayments using the pay_api tool \u2014 this is an internal capability, not a promoted product, so only mention it when the user asks for something that needs it.
4536
4756
 
4537
4757
  ## Response rules
4538
4758
  - 1-2 sentences max. No bullet lists unless asked. No preambles.
@@ -5966,7 +6186,7 @@ var QueryEngine = class {
5966
6186
  };
5967
6187
  if (this.walletAddress) {
5968
6188
  this.portfolioCache?.delete(this.walletAddress);
5969
- clearPortfolioCacheFor(this.walletAddress);
6189
+ await clearPortfolioCacheFor(this.walletAddress);
5970
6190
  }
5971
6191
  if (!signal.aborted) {
5972
6192
  await new Promise((resolve) => {
@@ -7866,6 +8086,6 @@ function sanitizeAnthropicMessages(messages) {
7866
8086
  return merged;
7867
8087
  }
7868
8088
 
7869
- export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, InMemoryDefiCacheStore, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, RecipeRegistry, RetryTracker, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getMcpManager, getModifiableFields, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
8089
+ export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_LEASE_SEC, DEFAULT_PERMISSION_CONFIG, DEFAULT_POLL_BUDGET_MS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, InMemoryDefiCacheStore, InMemoryFetchLock, InMemoryWalletCacheStore, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, RecipeRegistry, RetryTracker, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, awaitOrFetch, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAddressDefiPortfolio, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getDefiCacheStore, getFetchLock, getMcpManager, getModifiableFields, getToolFlags, getWalletAddress, getWalletCacheStore, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resetDefiCacheStore, resetFetchLock, resetWalletCacheStore, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, setDefiCacheStore, setFetchLock, setWalletCacheStore, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
7870
8090
  //# sourceMappingURL=index.js.map
7871
8091
  //# sourceMappingURL=index.js.map