@anuma/sdk 2.7.0 → 3.1.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/expo/{chunk-TCRDSUC6.mjs → chunk-22CSPJLL.mjs} +164 -891
- package/dist/expo/index.cjs +1812 -1112
- package/dist/expo/index.d.mts +226 -12
- package/dist/expo/index.d.ts +226 -12
- package/dist/expo/index.mjs +1558 -68
- package/dist/expo/{recall-FQU3NUTL.mjs → recall-LICO3TJ7.mjs} +1 -1
- package/dist/index.cjs +418 -395
- package/dist/index.mjs +415 -392
- package/dist/react/{chunk-ZXS3KOY4.mjs → chunk-FD5MB73N.mjs} +158 -1030
- package/dist/react/index.cjs +1839 -1742
- package/dist/react/index.d.mts +150 -14
- package/dist/react/index.d.ts +150 -14
- package/dist/react/index.mjs +1235 -229
- package/dist/react/{recall-PV7L3SN3.mjs → recall-FPACUZGD.mjs} +1 -1
- package/dist/server/{chunk-Z6II54I7.mjs → chunk-RKUNGNBF.mjs} +163 -842
- package/dist/server/index.cjs +392 -970
- package/dist/server/index.d.mts +170 -14
- package/dist/server/index.d.ts +170 -14
- package/dist/server/index.mjs +198 -27
- package/dist/server/{recall-CQT24XLH.mjs → recall-WT5HY2IA.mjs} +1 -1
- package/dist/tools/selection/chunk-4ETHWSXJ.mjs +25 -0
- package/dist/tools/selection/clientConfig-WITO4T6L.mjs +12 -0
- package/dist/tools/selection/index.cjs +1977 -0
- package/dist/tools/selection/index.d.mts +1380 -0
- package/dist/tools/selection/index.d.ts +1380 -0
- package/dist/tools/selection/index.mjs +1859 -0
- package/package.json +8 -1
package/dist/index.cjs
CHANGED
|
@@ -1655,6 +1655,204 @@ var getHealth = (options) => {
|
|
|
1655
1655
|
});
|
|
1656
1656
|
};
|
|
1657
1657
|
|
|
1658
|
+
// src/lib/memoryEngine/generate.ts
|
|
1659
|
+
init_clientConfig();
|
|
1660
|
+
|
|
1661
|
+
// src/lib/memoryEngine/constants.ts
|
|
1662
|
+
var DEFAULT_API_EMBEDDING_MODEL = "qwen/qwen3-embedding-8b";
|
|
1663
|
+
|
|
1664
|
+
// src/lib/memoryEngine/generate.ts
|
|
1665
|
+
var EMBED_MAX_ATTEMPTS = 4;
|
|
1666
|
+
async function withEmbeddingRetry(call) {
|
|
1667
|
+
let last;
|
|
1668
|
+
let lastThrown;
|
|
1669
|
+
let threw = false;
|
|
1670
|
+
for (let attempt = 1; attempt <= EMBED_MAX_ATTEMPTS; attempt++) {
|
|
1671
|
+
try {
|
|
1672
|
+
threw = false;
|
|
1673
|
+
last = await call();
|
|
1674
|
+
if (!last.error) return last;
|
|
1675
|
+
const status = last.response?.status;
|
|
1676
|
+
const retryable = status === void 0 || status === 429 || status >= 500;
|
|
1677
|
+
if (!retryable) return last;
|
|
1678
|
+
} catch (err) {
|
|
1679
|
+
threw = true;
|
|
1680
|
+
lastThrown = err;
|
|
1681
|
+
}
|
|
1682
|
+
if (attempt < EMBED_MAX_ATTEMPTS) {
|
|
1683
|
+
const base = 250 * 2 ** (attempt - 1);
|
|
1684
|
+
await new Promise((r) => setTimeout(r, base + Math.random() * 0.4 * base));
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
if (threw) throw lastThrown;
|
|
1688
|
+
return last;
|
|
1689
|
+
}
|
|
1690
|
+
var EmbeddingHttpError = class extends Error {
|
|
1691
|
+
constructor(message, status) {
|
|
1692
|
+
super(message);
|
|
1693
|
+
this.name = "EmbeddingHttpError";
|
|
1694
|
+
this.status = status;
|
|
1695
|
+
}
|
|
1696
|
+
};
|
|
1697
|
+
function embeddingErrorFrom(response) {
|
|
1698
|
+
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
1699
|
+
return new EmbeddingHttpError(message, response.response?.status);
|
|
1700
|
+
}
|
|
1701
|
+
async function generateEmbedding(text, options) {
|
|
1702
|
+
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
1703
|
+
if (cache) {
|
|
1704
|
+
const cached = cache.get(text);
|
|
1705
|
+
if (cached) return Array.from(cached);
|
|
1706
|
+
}
|
|
1707
|
+
let headers;
|
|
1708
|
+
if (apiKey) {
|
|
1709
|
+
headers = { "X-API-Key": apiKey };
|
|
1710
|
+
} else if (getToken) {
|
|
1711
|
+
const token = await getToken();
|
|
1712
|
+
if (!token) {
|
|
1713
|
+
throw new Error("No token available for embedding generation");
|
|
1714
|
+
}
|
|
1715
|
+
headers = { Authorization: `Bearer ${token}` };
|
|
1716
|
+
} else {
|
|
1717
|
+
throw new Error("Either apiKey or getToken must be provided");
|
|
1718
|
+
}
|
|
1719
|
+
const response = await withEmbeddingRetry(
|
|
1720
|
+
() => postApiV1Embeddings({
|
|
1721
|
+
baseUrl,
|
|
1722
|
+
body: {
|
|
1723
|
+
// Mask PII from the request body only — the cache above still keys on
|
|
1724
|
+
// the original `text`, so callers keep their original values.
|
|
1725
|
+
input: options.maskInput ? options.maskInput(text) : text,
|
|
1726
|
+
model: model ?? DEFAULT_API_EMBEDDING_MODEL
|
|
1727
|
+
},
|
|
1728
|
+
headers
|
|
1729
|
+
})
|
|
1730
|
+
);
|
|
1731
|
+
if (response.error) {
|
|
1732
|
+
throw embeddingErrorFrom(response);
|
|
1733
|
+
}
|
|
1734
|
+
if (!response.data?.data?.[0]?.embedding) {
|
|
1735
|
+
throw new Error("No embedding returned from API");
|
|
1736
|
+
}
|
|
1737
|
+
const embedding = response.data.data[0].embedding;
|
|
1738
|
+
if (options.onUsage && response.data.usage) {
|
|
1739
|
+
options.onUsage({
|
|
1740
|
+
promptTokens: response.data.usage.prompt_tokens ?? 0,
|
|
1741
|
+
totalTokens: response.data.usage.total_tokens ?? 0
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
const f32Embedding = Float32Array.from(embedding);
|
|
1745
|
+
if (cache) {
|
|
1746
|
+
cache.set(text, f32Embedding);
|
|
1747
|
+
}
|
|
1748
|
+
return Array.from(f32Embedding);
|
|
1749
|
+
}
|
|
1750
|
+
var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
|
|
1751
|
+
var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
|
|
1752
|
+
async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput) {
|
|
1753
|
+
const response = await withEmbeddingRetry(
|
|
1754
|
+
() => postApiV1Embeddings({
|
|
1755
|
+
baseUrl,
|
|
1756
|
+
// Mask PII from the request body only; cache/order still key on originals.
|
|
1757
|
+
body: { input: maskInput ? texts.map(maskInput) : texts, model },
|
|
1758
|
+
headers
|
|
1759
|
+
})
|
|
1760
|
+
);
|
|
1761
|
+
if (response.error) {
|
|
1762
|
+
throw embeddingErrorFrom(response);
|
|
1763
|
+
}
|
|
1764
|
+
if (!response.data?.data) {
|
|
1765
|
+
throw new Error("No embeddings returned from API");
|
|
1766
|
+
}
|
|
1767
|
+
if (onUsage && response.data.usage) {
|
|
1768
|
+
onUsage({
|
|
1769
|
+
promptTokens: response.data.usage.prompt_tokens ?? 0,
|
|
1770
|
+
totalTokens: response.data.usage.total_tokens ?? 0
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
return response.data.data.map((item) => item.embedding ?? []);
|
|
1774
|
+
}
|
|
1775
|
+
async function generateEmbeddings(texts, options) {
|
|
1776
|
+
if (texts.length === 0) return [];
|
|
1777
|
+
const { baseUrl = BASE_URL, getToken, apiKey, model, batchSize, cache } = options;
|
|
1778
|
+
const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
|
|
1779
|
+
const results = new Array(texts.length).fill(null);
|
|
1780
|
+
const uncachedIndices = [];
|
|
1781
|
+
const uncachedTexts = [];
|
|
1782
|
+
for (let i = 0; i < texts.length; i++) {
|
|
1783
|
+
if (cache) {
|
|
1784
|
+
const cached = cache.get(texts[i]);
|
|
1785
|
+
if (cached) {
|
|
1786
|
+
results[i] = Array.from(cached);
|
|
1787
|
+
continue;
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
uncachedIndices.push(i);
|
|
1791
|
+
uncachedTexts.push(texts[i]);
|
|
1792
|
+
}
|
|
1793
|
+
if (uncachedTexts.length === 0) {
|
|
1794
|
+
return results;
|
|
1795
|
+
}
|
|
1796
|
+
let headers;
|
|
1797
|
+
if (apiKey) {
|
|
1798
|
+
headers = { "X-API-Key": apiKey };
|
|
1799
|
+
} else if (getToken) {
|
|
1800
|
+
const token = await getToken();
|
|
1801
|
+
if (!token) {
|
|
1802
|
+
throw new Error("No token available for embedding generation");
|
|
1803
|
+
}
|
|
1804
|
+
headers = { Authorization: `Bearer ${token}` };
|
|
1805
|
+
} else {
|
|
1806
|
+
throw new Error("Either apiKey or getToken must be provided");
|
|
1807
|
+
}
|
|
1808
|
+
const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
|
|
1809
|
+
let newEmbeddings;
|
|
1810
|
+
if (uncachedTexts.length <= chunkSize) {
|
|
1811
|
+
newEmbeddings = await generateEmbeddingsBatch(
|
|
1812
|
+
uncachedTexts,
|
|
1813
|
+
headers,
|
|
1814
|
+
baseUrl,
|
|
1815
|
+
embeddingModel,
|
|
1816
|
+
options.onUsage,
|
|
1817
|
+
options.maskInput
|
|
1818
|
+
);
|
|
1819
|
+
} else {
|
|
1820
|
+
const chunks = [];
|
|
1821
|
+
for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
|
|
1822
|
+
chunks.push(uncachedTexts.slice(i, i + chunkSize));
|
|
1823
|
+
}
|
|
1824
|
+
const allEmbeddings = new Array(chunks.length);
|
|
1825
|
+
let nextIndex = 0;
|
|
1826
|
+
const worker = async () => {
|
|
1827
|
+
while (nextIndex < chunks.length) {
|
|
1828
|
+
const idx = nextIndex++;
|
|
1829
|
+
allEmbeddings[idx] = await generateEmbeddingsBatch(
|
|
1830
|
+
chunks[idx],
|
|
1831
|
+
headers,
|
|
1832
|
+
baseUrl,
|
|
1833
|
+
embeddingModel,
|
|
1834
|
+
options.onUsage,
|
|
1835
|
+
options.maskInput
|
|
1836
|
+
);
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1839
|
+
const workers = Array.from(
|
|
1840
|
+
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks.length) },
|
|
1841
|
+
() => worker()
|
|
1842
|
+
);
|
|
1843
|
+
await Promise.all(workers);
|
|
1844
|
+
newEmbeddings = allEmbeddings.flat();
|
|
1845
|
+
}
|
|
1846
|
+
for (let i = 0; i < uncachedIndices.length; i++) {
|
|
1847
|
+
const f32Embedding = Float32Array.from(newEmbeddings[i]);
|
|
1848
|
+
results[uncachedIndices[i]] = Array.from(f32Embedding);
|
|
1849
|
+
if (cache) {
|
|
1850
|
+
cache.set(uncachedTexts[i], f32Embedding);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
return results;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1658
1856
|
// src/tools/appBuilderPrompt.ts
|
|
1659
1857
|
var APP_BUILDER_PROMPT = `App Builder tools (create_file, patch_file, and the rest described below) are available this turn, but they are OPTIONAL \u2014 having them does not mean you should build anything.
|
|
1660
1858
|
|
|
@@ -1869,399 +2067,67 @@ function chunkText(text, options) {
|
|
|
1869
2067
|
const overlapSentences = [];
|
|
1870
2068
|
let overlapLength = 0;
|
|
1871
2069
|
for (let j = currentChunkSentences.length - 1; j >= 0 && overlapLength < chunkOverlap; j--) {
|
|
1872
|
-
overlapSentences.unshift(currentChunkSentences[j]);
|
|
1873
|
-
overlapLength += currentChunkSentences[j].length + 1;
|
|
1874
|
-
}
|
|
1875
|
-
if (overlapSentences.length > 0) {
|
|
1876
|
-
currentChunkSentences = [...overlapSentences, sentence];
|
|
1877
|
-
const overlapText = overlapSentences[0];
|
|
1878
|
-
const overlapStart = text.lastIndexOf(overlapText, currentOffset);
|
|
1879
|
-
currentChunkStart = overlapStart === -1 ? sentenceStart : overlapStart;
|
|
1880
|
-
} else {
|
|
1881
|
-
currentChunkSentences = [sentence];
|
|
1882
|
-
currentChunkStart = sentenceStart;
|
|
1883
|
-
}
|
|
1884
|
-
} else {
|
|
1885
|
-
if (currentChunkSentences.length === 0) {
|
|
1886
|
-
currentChunkStart = sentenceStart;
|
|
1887
|
-
}
|
|
1888
|
-
currentChunkSentences.push(sentence);
|
|
1889
|
-
}
|
|
1890
|
-
currentOffset = sentenceEnd;
|
|
1891
|
-
}
|
|
1892
|
-
if (currentChunkSentences.length > 0) {
|
|
1893
|
-
const chunkText2 = currentChunkSentences.join(" ");
|
|
1894
|
-
if (chunkText2.length >= minChunkSize) {
|
|
1895
|
-
chunks.push({
|
|
1896
|
-
text: chunkText2,
|
|
1897
|
-
startOffset: currentChunkStart,
|
|
1898
|
-
endOffset: text.length
|
|
1899
|
-
});
|
|
1900
|
-
}
|
|
1901
|
-
}
|
|
1902
|
-
if (chunks.length === 0) {
|
|
1903
|
-
const trimmedText = text.trim();
|
|
1904
|
-
if (trimmedText.length > 0) {
|
|
1905
|
-
return [
|
|
1906
|
-
{
|
|
1907
|
-
text: trimmedText,
|
|
1908
|
-
startOffset: 0,
|
|
1909
|
-
endOffset: text.length
|
|
1910
|
-
}
|
|
1911
|
-
];
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
return chunks;
|
|
1915
|
-
}
|
|
1916
|
-
function shouldChunkMessage(content, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
1917
|
-
return content.length > chunkSize;
|
|
1918
|
-
}
|
|
1919
|
-
|
|
1920
|
-
// src/lib/memoryEngine/embeddings.ts
|
|
1921
|
-
init_clientConfig();
|
|
1922
|
-
|
|
1923
|
-
// src/react/useEncryption.ts
|
|
1924
|
-
var encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
1925
|
-
var cryptoKeyCache = /* @__PURE__ */ new Map();
|
|
1926
|
-
var clearAllEncryptionStateCallbacks = /* @__PURE__ */ new Set();
|
|
1927
|
-
function onClearAllEncryptionState(callback) {
|
|
1928
|
-
clearAllEncryptionStateCallbacks.add(callback);
|
|
1929
|
-
return () => {
|
|
1930
|
-
clearAllEncryptionStateCallbacks.delete(callback);
|
|
1931
|
-
};
|
|
1932
|
-
}
|
|
1933
|
-
function getStoredKey(address) {
|
|
1934
|
-
const keys = encryptionKeyStore.get(address);
|
|
1935
|
-
return keys?.current ?? null;
|
|
1936
|
-
}
|
|
1937
|
-
function getStoredKeyByVersion(address, version) {
|
|
1938
|
-
const keys = encryptionKeyStore.get(address);
|
|
1939
|
-
if (!keys) return null;
|
|
1940
|
-
return version === "v2" ? keys.legacy : keys.current;
|
|
1941
|
-
}
|
|
1942
|
-
function hexToBytes(hex) {
|
|
1943
|
-
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1944
|
-
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
1945
|
-
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
1946
|
-
bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
|
|
1947
|
-
}
|
|
1948
|
-
return bytes;
|
|
1949
|
-
}
|
|
1950
|
-
var SHARED_TEXT_ENCODER = new TextEncoder();
|
|
1951
|
-
var SHARED_TEXT_DECODER = new TextDecoder();
|
|
1952
|
-
async function getEncryptionKey(address, version = "v3") {
|
|
1953
|
-
const cacheKey = `${address}:${version}`;
|
|
1954
|
-
const cachedKey = cryptoKeyCache.get(cacheKey);
|
|
1955
|
-
if (cachedKey) {
|
|
1956
|
-
return cachedKey;
|
|
1957
|
-
}
|
|
1958
|
-
const keyHex = getStoredKeyByVersion(address, version);
|
|
1959
|
-
if (!keyHex) {
|
|
1960
|
-
throw new Error(
|
|
1961
|
-
"Encryption key not found. Please sign a message to generate your encryption key."
|
|
1962
|
-
);
|
|
1963
|
-
}
|
|
1964
|
-
const keyBytes = hexToBytes(keyHex);
|
|
1965
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
1966
|
-
"raw",
|
|
1967
|
-
keyBytes.buffer,
|
|
1968
|
-
{ name: "AES-GCM" },
|
|
1969
|
-
false,
|
|
1970
|
-
["encrypt", "decrypt"]
|
|
1971
|
-
);
|
|
1972
|
-
cryptoKeyCache.set(cacheKey, cryptoKey);
|
|
1973
|
-
return cryptoKey;
|
|
1974
|
-
}
|
|
1975
|
-
async function decryptData(encryptedHex, address, version = "v3") {
|
|
1976
|
-
const key = await getEncryptionKey(address, version);
|
|
1977
|
-
return decryptDataWithKey(encryptedHex, key);
|
|
1978
|
-
}
|
|
1979
|
-
function hasEncryptionKey(address) {
|
|
1980
|
-
return getStoredKey(address) !== null;
|
|
1981
|
-
}
|
|
1982
|
-
async function decryptDataWithKey(encryptedHex, key) {
|
|
1983
|
-
const combined = hexToBytes(encryptedHex);
|
|
1984
|
-
const iv = combined.subarray(0, 12);
|
|
1985
|
-
const encryptedData = combined.subarray(12);
|
|
1986
|
-
const decryptedData = await crypto.subtle.decrypt(
|
|
1987
|
-
{
|
|
1988
|
-
name: "AES-GCM",
|
|
1989
|
-
iv
|
|
1990
|
-
},
|
|
1991
|
-
key,
|
|
1992
|
-
encryptedData
|
|
1993
|
-
);
|
|
1994
|
-
return SHARED_TEXT_DECODER.decode(decryptedData);
|
|
1995
|
-
}
|
|
1996
|
-
|
|
1997
|
-
// src/lib/memoryEngine/vector.ts
|
|
1998
|
-
function cosineSimilarity(a, b) {
|
|
1999
|
-
if (a.length !== b.length) return 0;
|
|
2000
|
-
let dot = 0;
|
|
2001
|
-
let normA = 0;
|
|
2002
|
-
let normB = 0;
|
|
2003
|
-
for (let i = 0; i < a.length; i++) {
|
|
2004
|
-
dot += a[i] * b[i];
|
|
2005
|
-
normA += a[i] * a[i];
|
|
2006
|
-
normB += b[i] * b[i];
|
|
2007
|
-
}
|
|
2008
|
-
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
2009
|
-
return denom === 0 ? 0 : dot / denom;
|
|
2010
|
-
}
|
|
2011
|
-
|
|
2012
|
-
// src/lib/db/encryption-utils.ts
|
|
2013
|
-
function isEncrypted(value) {
|
|
2014
|
-
const prefix = value.startsWith("enc:v3:") ? "enc:v3:" : value.startsWith("enc:v2:") ? "enc:v2:" : null;
|
|
2015
|
-
if (!prefix) return false;
|
|
2016
|
-
const payload = value.slice(prefix.length);
|
|
2017
|
-
return payload.length >= 56 && /^[0-9a-f]+$/i.test(payload);
|
|
2018
|
-
}
|
|
2019
|
-
function detectEncryptionVersion(value) {
|
|
2020
|
-
if (value.startsWith("enc:v3:")) {
|
|
2021
|
-
return { version: "v3", encryptedData: value.slice("enc:v3:".length) };
|
|
2022
|
-
}
|
|
2023
|
-
if (value.startsWith("enc:v2:")) {
|
|
2024
|
-
return { version: "v2", encryptedData: value.slice("enc:v2:".length) };
|
|
2025
|
-
}
|
|
2026
|
-
return null;
|
|
2027
|
-
}
|
|
2028
|
-
async function decryptField(value, address) {
|
|
2029
|
-
if (!value) return value;
|
|
2030
|
-
const detected = detectEncryptionVersion(value);
|
|
2031
|
-
if (!detected) return value;
|
|
2032
|
-
if (detected.encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(detected.encryptedData)) {
|
|
2033
|
-
return value;
|
|
2034
|
-
}
|
|
2035
|
-
try {
|
|
2036
|
-
return await decryptData(detected.encryptedData, address, detected.version);
|
|
2037
|
-
} catch (error) {
|
|
2038
|
-
getLogger().warn("Failed to decrypt field, returning as-is:", error);
|
|
2039
|
-
return value;
|
|
2040
|
-
}
|
|
2041
|
-
}
|
|
2042
|
-
|
|
2043
|
-
// src/lib/chat/useChat/strategies/types.ts
|
|
2044
|
-
function isChatCompletionResponse(r) {
|
|
2045
|
-
if (r.object === "response") return false;
|
|
2046
|
-
if (Array.isArray(r.output)) return false;
|
|
2047
|
-
return true;
|
|
2048
|
-
}
|
|
2049
|
-
function getToolCallEvents(r) {
|
|
2050
|
-
if (isChatCompletionResponse(r)) {
|
|
2051
|
-
return r.portal?.tool_call_events ?? r.tool_call_events;
|
|
2052
|
-
}
|
|
2053
|
-
return r.tool_call_events;
|
|
2054
|
-
}
|
|
2055
|
-
function getCostMicroUsd(r) {
|
|
2056
|
-
if (isChatCompletionResponse(r)) {
|
|
2057
|
-
return r.portal?.cost_micro_usd ?? r.usage?.cost_micro_usd;
|
|
2058
|
-
}
|
|
2059
|
-
return r.usage?.cost_micro_usd;
|
|
2060
|
-
}
|
|
2061
|
-
function getCreditsUsed(r) {
|
|
2062
|
-
if (isChatCompletionResponse(r)) {
|
|
2063
|
-
return r.portal?.credits_used ?? r.usage?.credits_used;
|
|
2064
|
-
}
|
|
2065
|
-
return r.usage?.credits_used;
|
|
2066
|
-
}
|
|
2067
|
-
function getImageModel(r) {
|
|
2068
|
-
if (isChatCompletionResponse(r)) {
|
|
2069
|
-
return r.portal?.image_model ?? r.image_model;
|
|
2070
|
-
}
|
|
2071
|
-
return r.image_model;
|
|
2072
|
-
}
|
|
2073
|
-
|
|
2074
|
-
// src/lib/memoryEngine/constants.ts
|
|
2075
|
-
var DEFAULT_API_EMBEDDING_MODEL = "qwen/qwen3-embedding-8b";
|
|
2076
|
-
|
|
2077
|
-
// src/lib/memoryEngine/embeddings.ts
|
|
2078
|
-
var EMBED_MAX_ATTEMPTS = 4;
|
|
2079
|
-
async function withEmbeddingRetry(call) {
|
|
2080
|
-
let last;
|
|
2081
|
-
let lastThrown;
|
|
2082
|
-
let threw = false;
|
|
2083
|
-
for (let attempt = 1; attempt <= EMBED_MAX_ATTEMPTS; attempt++) {
|
|
2084
|
-
try {
|
|
2085
|
-
threw = false;
|
|
2086
|
-
last = await call();
|
|
2087
|
-
if (!last.error) return last;
|
|
2088
|
-
const status = last.response?.status;
|
|
2089
|
-
const retryable = status === void 0 || status === 429 || status >= 500;
|
|
2090
|
-
if (!retryable) return last;
|
|
2091
|
-
} catch (err) {
|
|
2092
|
-
threw = true;
|
|
2093
|
-
lastThrown = err;
|
|
2094
|
-
}
|
|
2095
|
-
if (attempt < EMBED_MAX_ATTEMPTS) {
|
|
2096
|
-
const base = 250 * 2 ** (attempt - 1);
|
|
2097
|
-
await new Promise((r) => setTimeout(r, base + Math.random() * 0.4 * base));
|
|
2098
|
-
}
|
|
2099
|
-
}
|
|
2100
|
-
if (threw) throw lastThrown;
|
|
2101
|
-
return last;
|
|
2102
|
-
}
|
|
2103
|
-
var EmbeddingHttpError = class extends Error {
|
|
2104
|
-
constructor(message, status) {
|
|
2105
|
-
super(message);
|
|
2106
|
-
this.name = "EmbeddingHttpError";
|
|
2107
|
-
this.status = status;
|
|
2108
|
-
}
|
|
2109
|
-
};
|
|
2110
|
-
function embeddingErrorFrom(response) {
|
|
2111
|
-
const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
|
|
2112
|
-
return new EmbeddingHttpError(message, response.response?.status);
|
|
2113
|
-
}
|
|
2114
|
-
async function generateEmbedding(text, options) {
|
|
2115
|
-
const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
|
|
2116
|
-
if (cache) {
|
|
2117
|
-
const cached = cache.get(text);
|
|
2118
|
-
if (cached) return cached;
|
|
2119
|
-
}
|
|
2120
|
-
let headers;
|
|
2121
|
-
if (apiKey) {
|
|
2122
|
-
headers = { "X-API-Key": apiKey };
|
|
2123
|
-
} else if (getToken) {
|
|
2124
|
-
const token = await getToken();
|
|
2125
|
-
if (!token) {
|
|
2126
|
-
throw new Error("No token available for embedding generation");
|
|
2127
|
-
}
|
|
2128
|
-
headers = { Authorization: `Bearer ${token}` };
|
|
2129
|
-
} else {
|
|
2130
|
-
throw new Error("Either apiKey or getToken must be provided");
|
|
2131
|
-
}
|
|
2132
|
-
const response = await withEmbeddingRetry(
|
|
2133
|
-
() => postApiV1Embeddings({
|
|
2134
|
-
baseUrl,
|
|
2135
|
-
body: {
|
|
2136
|
-
// Mask PII from the request body only — the cache above still keys on
|
|
2137
|
-
// the original `text`, so callers keep their original values.
|
|
2138
|
-
input: options.maskInput ? options.maskInput(text) : text,
|
|
2139
|
-
model: model ?? DEFAULT_API_EMBEDDING_MODEL
|
|
2140
|
-
},
|
|
2141
|
-
headers
|
|
2142
|
-
})
|
|
2143
|
-
);
|
|
2144
|
-
if (response.error) {
|
|
2145
|
-
throw embeddingErrorFrom(response);
|
|
2146
|
-
}
|
|
2147
|
-
if (!response.data?.data?.[0]?.embedding) {
|
|
2148
|
-
throw new Error("No embedding returned from API");
|
|
2149
|
-
}
|
|
2150
|
-
const embedding = response.data.data[0].embedding;
|
|
2151
|
-
if (options.onUsage && response.data.usage) {
|
|
2152
|
-
options.onUsage({
|
|
2153
|
-
promptTokens: response.data.usage.prompt_tokens ?? 0,
|
|
2154
|
-
totalTokens: response.data.usage.total_tokens ?? 0
|
|
2155
|
-
});
|
|
2156
|
-
}
|
|
2157
|
-
if (cache) {
|
|
2158
|
-
cache.set(text, embedding);
|
|
2159
|
-
}
|
|
2160
|
-
return embedding;
|
|
2161
|
-
}
|
|
2162
|
-
var DEFAULT_EMBEDDING_BATCH_SIZE = 100;
|
|
2163
|
-
var DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
|
|
2164
|
-
async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput) {
|
|
2165
|
-
const response = await withEmbeddingRetry(
|
|
2166
|
-
() => postApiV1Embeddings({
|
|
2167
|
-
baseUrl,
|
|
2168
|
-
// Mask PII from the request body only; cache/order still key on originals.
|
|
2169
|
-
body: { input: maskInput ? texts.map(maskInput) : texts, model },
|
|
2170
|
-
headers
|
|
2171
|
-
})
|
|
2172
|
-
);
|
|
2173
|
-
if (response.error) {
|
|
2174
|
-
throw embeddingErrorFrom(response);
|
|
2175
|
-
}
|
|
2176
|
-
if (!response.data?.data) {
|
|
2177
|
-
throw new Error("No embeddings returned from API");
|
|
2178
|
-
}
|
|
2179
|
-
if (onUsage && response.data.usage) {
|
|
2180
|
-
onUsage({
|
|
2181
|
-
promptTokens: response.data.usage.prompt_tokens ?? 0,
|
|
2182
|
-
totalTokens: response.data.usage.total_tokens ?? 0
|
|
2183
|
-
});
|
|
2184
|
-
}
|
|
2185
|
-
return response.data.data.map((item) => item.embedding ?? []);
|
|
2186
|
-
}
|
|
2187
|
-
async function generateEmbeddings(texts, options) {
|
|
2188
|
-
if (texts.length === 0) return [];
|
|
2189
|
-
const { baseUrl = BASE_URL, getToken, apiKey, model, batchSize, cache } = options;
|
|
2190
|
-
const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
|
|
2191
|
-
const results = new Array(texts.length).fill(null);
|
|
2192
|
-
const uncachedIndices = [];
|
|
2193
|
-
const uncachedTexts = [];
|
|
2194
|
-
for (let i = 0; i < texts.length; i++) {
|
|
2195
|
-
if (cache) {
|
|
2196
|
-
const cached = cache.get(texts[i]);
|
|
2197
|
-
if (cached) {
|
|
2198
|
-
results[i] = cached;
|
|
2199
|
-
continue;
|
|
2070
|
+
overlapSentences.unshift(currentChunkSentences[j]);
|
|
2071
|
+
overlapLength += currentChunkSentences[j].length + 1;
|
|
2072
|
+
}
|
|
2073
|
+
if (overlapSentences.length > 0) {
|
|
2074
|
+
currentChunkSentences = [...overlapSentences, sentence];
|
|
2075
|
+
const overlapText = overlapSentences[0];
|
|
2076
|
+
const overlapStart = text.lastIndexOf(overlapText, currentOffset);
|
|
2077
|
+
currentChunkStart = overlapStart === -1 ? sentenceStart : overlapStart;
|
|
2078
|
+
} else {
|
|
2079
|
+
currentChunkSentences = [sentence];
|
|
2080
|
+
currentChunkStart = sentenceStart;
|
|
2081
|
+
}
|
|
2082
|
+
} else {
|
|
2083
|
+
if (currentChunkSentences.length === 0) {
|
|
2084
|
+
currentChunkStart = sentenceStart;
|
|
2200
2085
|
}
|
|
2086
|
+
currentChunkSentences.push(sentence);
|
|
2201
2087
|
}
|
|
2202
|
-
|
|
2203
|
-
uncachedTexts.push(texts[i]);
|
|
2204
|
-
}
|
|
2205
|
-
if (uncachedTexts.length === 0) {
|
|
2206
|
-
return results;
|
|
2088
|
+
currentOffset = sentenceEnd;
|
|
2207
2089
|
}
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2090
|
+
if (currentChunkSentences.length > 0) {
|
|
2091
|
+
const chunkText2 = currentChunkSentences.join(" ");
|
|
2092
|
+
if (chunkText2.length >= minChunkSize) {
|
|
2093
|
+
chunks.push({
|
|
2094
|
+
text: chunkText2,
|
|
2095
|
+
startOffset: currentChunkStart,
|
|
2096
|
+
endOffset: text.length
|
|
2097
|
+
});
|
|
2215
2098
|
}
|
|
2216
|
-
headers = { Authorization: `Bearer ${token}` };
|
|
2217
|
-
} else {
|
|
2218
|
-
throw new Error("Either apiKey or getToken must be provided");
|
|
2219
2099
|
}
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
);
|
|
2231
|
-
} else {
|
|
2232
|
-
const chunks = [];
|
|
2233
|
-
for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
|
|
2234
|
-
chunks.push(uncachedTexts.slice(i, i + chunkSize));
|
|
2100
|
+
if (chunks.length === 0) {
|
|
2101
|
+
const trimmedText = text.trim();
|
|
2102
|
+
if (trimmedText.length > 0) {
|
|
2103
|
+
return [
|
|
2104
|
+
{
|
|
2105
|
+
text: trimmedText,
|
|
2106
|
+
startOffset: 0,
|
|
2107
|
+
endOffset: text.length
|
|
2108
|
+
}
|
|
2109
|
+
];
|
|
2235
2110
|
}
|
|
2236
|
-
const allEmbeddings = new Array(chunks.length);
|
|
2237
|
-
let nextIndex = 0;
|
|
2238
|
-
const worker = async () => {
|
|
2239
|
-
while (nextIndex < chunks.length) {
|
|
2240
|
-
const idx = nextIndex++;
|
|
2241
|
-
allEmbeddings[idx] = await generateEmbeddingsBatch(
|
|
2242
|
-
chunks[idx],
|
|
2243
|
-
headers,
|
|
2244
|
-
baseUrl,
|
|
2245
|
-
embeddingModel,
|
|
2246
|
-
options.onUsage,
|
|
2247
|
-
options.maskInput
|
|
2248
|
-
);
|
|
2249
|
-
}
|
|
2250
|
-
};
|
|
2251
|
-
const workers = Array.from(
|
|
2252
|
-
{ length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks.length) },
|
|
2253
|
-
() => worker()
|
|
2254
|
-
);
|
|
2255
|
-
await Promise.all(workers);
|
|
2256
|
-
newEmbeddings = allEmbeddings.flat();
|
|
2257
2111
|
}
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2112
|
+
return chunks;
|
|
2113
|
+
}
|
|
2114
|
+
function shouldChunkMessage(content, chunkSize = DEFAULT_CHUNK_SIZE) {
|
|
2115
|
+
return content.length > chunkSize;
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
// src/lib/memoryEngine/vector.ts
|
|
2119
|
+
function cosineSimilarity(a, b) {
|
|
2120
|
+
if (a.length !== b.length) return 0;
|
|
2121
|
+
let dot = 0;
|
|
2122
|
+
let normA = 0;
|
|
2123
|
+
let normB = 0;
|
|
2124
|
+
for (let i = 0; i < a.length; i++) {
|
|
2125
|
+
dot += a[i] * b[i];
|
|
2126
|
+
normA += a[i] * a[i];
|
|
2127
|
+
normB += b[i] * b[i];
|
|
2263
2128
|
}
|
|
2264
|
-
|
|
2129
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
2130
|
+
return denom === 0 ? 0 : dot / denom;
|
|
2265
2131
|
}
|
|
2266
2132
|
|
|
2267
2133
|
// src/lib/tools/serverTools.ts
|
|
@@ -2328,7 +2194,7 @@ function getCachedServerTools() {
|
|
|
2328
2194
|
if (!cached) return null;
|
|
2329
2195
|
const parsed = JSON.parse(cached);
|
|
2330
2196
|
if (parsed.version !== CACHE_VERSION) {
|
|
2331
|
-
|
|
2197
|
+
removeLocalStorageCache();
|
|
2332
2198
|
return null;
|
|
2333
2199
|
}
|
|
2334
2200
|
return parsed;
|
|
@@ -2340,24 +2206,31 @@ function isCacheExpired(cache, expirationMs = DEFAULT_CACHE_EXPIRATION_MS) {
|
|
|
2340
2206
|
if (!cache) return true;
|
|
2341
2207
|
return Date.now() - cache.timestamp > expirationMs;
|
|
2342
2208
|
}
|
|
2343
|
-
function
|
|
2344
|
-
|
|
2345
|
-
const cacheData = {
|
|
2209
|
+
function buildCacheEntry(tools, checksum) {
|
|
2210
|
+
return {
|
|
2346
2211
|
tools,
|
|
2347
2212
|
timestamp: Date.now(),
|
|
2348
2213
|
version: CACHE_VERSION,
|
|
2349
2214
|
...checksum && { checksum }
|
|
2350
2215
|
};
|
|
2216
|
+
}
|
|
2217
|
+
function writeLocalStorageCache(entry) {
|
|
2218
|
+
if (typeof localStorage === "undefined") return;
|
|
2351
2219
|
try {
|
|
2352
|
-
localStorage.setItem(SERVER_TOOLS_CACHE_KEY, JSON.stringify(
|
|
2220
|
+
localStorage.setItem(SERVER_TOOLS_CACHE_KEY, JSON.stringify(entry));
|
|
2353
2221
|
} catch (error) {
|
|
2354
2222
|
getLogger().warn("[serverTools] Failed to cache tools:", error);
|
|
2355
2223
|
}
|
|
2356
2224
|
}
|
|
2357
|
-
function
|
|
2225
|
+
function removeLocalStorageCache() {
|
|
2358
2226
|
if (typeof localStorage === "undefined") return;
|
|
2359
2227
|
localStorage.removeItem(SERVER_TOOLS_CACHE_KEY);
|
|
2360
2228
|
}
|
|
2229
|
+
var localStorageToolsCache = {
|
|
2230
|
+
get: getCachedServerTools,
|
|
2231
|
+
set: writeLocalStorageCache,
|
|
2232
|
+
clear: removeLocalStorageCache
|
|
2233
|
+
};
|
|
2361
2234
|
async function fetchServerToolsFromApi(baseUrl, token) {
|
|
2362
2235
|
const response = await fetch(`${baseUrl}/api/v1/tools`, {
|
|
2363
2236
|
method: "GET",
|
|
@@ -2378,9 +2251,23 @@ async function getServerTools(options) {
|
|
|
2378
2251
|
cacheExpirationMs = DEFAULT_CACHE_EXPIRATION_MS,
|
|
2379
2252
|
forceRefresh = false,
|
|
2380
2253
|
getToken,
|
|
2381
|
-
apiKey
|
|
2254
|
+
apiKey,
|
|
2255
|
+
cache = localStorageToolsCache
|
|
2382
2256
|
} = options;
|
|
2383
|
-
const
|
|
2257
|
+
const persistCache = async (entry) => {
|
|
2258
|
+
try {
|
|
2259
|
+
await cache.set(entry);
|
|
2260
|
+
} catch (error) {
|
|
2261
|
+
getLogger().warn("[serverTools] Cache write failed (non-fatal):", error);
|
|
2262
|
+
}
|
|
2263
|
+
};
|
|
2264
|
+
let rawCached = null;
|
|
2265
|
+
try {
|
|
2266
|
+
rawCached = await cache.get();
|
|
2267
|
+
} catch (error) {
|
|
2268
|
+
getLogger().warn("[serverTools] Cache read failed; falling through to server fetch:", error);
|
|
2269
|
+
}
|
|
2270
|
+
const cached = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
|
|
2384
2271
|
const cacheValid = !isCacheExpired(cached, cacheExpirationMs);
|
|
2385
2272
|
if (cached && cacheValid && !forceRefresh) {
|
|
2386
2273
|
return cached.tools;
|
|
@@ -2401,7 +2288,7 @@ async function getServerTools(options) {
|
|
|
2401
2288
|
}
|
|
2402
2289
|
const data = await response.json();
|
|
2403
2290
|
const { tools: tools2, checksum: checksum2 } = convertServerToolsResponse(data);
|
|
2404
|
-
|
|
2291
|
+
await persistCache(buildCacheEntry(tools2, checksum2));
|
|
2405
2292
|
return tools2;
|
|
2406
2293
|
}
|
|
2407
2294
|
if (!getToken) {
|
|
@@ -2414,7 +2301,7 @@ async function getServerTools(options) {
|
|
|
2414
2301
|
return cached?.tools ?? [];
|
|
2415
2302
|
}
|
|
2416
2303
|
const { tools, checksum } = await fetchServerToolsFromApi(effectiveBaseUrl, token);
|
|
2417
|
-
|
|
2304
|
+
await persistCache(buildCacheEntry(tools, checksum));
|
|
2418
2305
|
return tools;
|
|
2419
2306
|
} catch (error) {
|
|
2420
2307
|
getLogger().error("[serverTools] Failed to fetch server tools:", error);
|
|
@@ -3272,6 +3159,142 @@ function buildSystemPrompt(ctx, options) {
|
|
|
3272
3159
|
return { prompt, activeSections };
|
|
3273
3160
|
}
|
|
3274
3161
|
|
|
3162
|
+
// src/react/useEncryption.ts
|
|
3163
|
+
var encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
3164
|
+
var cryptoKeyCache = /* @__PURE__ */ new Map();
|
|
3165
|
+
var clearAllEncryptionStateCallbacks = /* @__PURE__ */ new Set();
|
|
3166
|
+
function onClearAllEncryptionState(callback) {
|
|
3167
|
+
clearAllEncryptionStateCallbacks.add(callback);
|
|
3168
|
+
return () => {
|
|
3169
|
+
clearAllEncryptionStateCallbacks.delete(callback);
|
|
3170
|
+
};
|
|
3171
|
+
}
|
|
3172
|
+
function getStoredKey(address) {
|
|
3173
|
+
const keys = encryptionKeyStore.get(address);
|
|
3174
|
+
return keys?.current ?? null;
|
|
3175
|
+
}
|
|
3176
|
+
function getStoredKeyByVersion(address, version) {
|
|
3177
|
+
const keys = encryptionKeyStore.get(address);
|
|
3178
|
+
if (!keys) return null;
|
|
3179
|
+
return version === "v2" ? keys.legacy : keys.current;
|
|
3180
|
+
}
|
|
3181
|
+
function hexToBytes(hex) {
|
|
3182
|
+
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
3183
|
+
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
3184
|
+
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
3185
|
+
bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
|
|
3186
|
+
}
|
|
3187
|
+
return bytes;
|
|
3188
|
+
}
|
|
3189
|
+
var SHARED_TEXT_ENCODER = new TextEncoder();
|
|
3190
|
+
var SHARED_TEXT_DECODER = new TextDecoder();
|
|
3191
|
+
async function getEncryptionKey(address, version = "v3") {
|
|
3192
|
+
const cacheKey = `${address}:${version}`;
|
|
3193
|
+
const cachedKey = cryptoKeyCache.get(cacheKey);
|
|
3194
|
+
if (cachedKey) {
|
|
3195
|
+
return cachedKey;
|
|
3196
|
+
}
|
|
3197
|
+
const keyHex = getStoredKeyByVersion(address, version);
|
|
3198
|
+
if (!keyHex) {
|
|
3199
|
+
throw new Error(
|
|
3200
|
+
"Encryption key not found. Please sign a message to generate your encryption key."
|
|
3201
|
+
);
|
|
3202
|
+
}
|
|
3203
|
+
const keyBytes = hexToBytes(keyHex);
|
|
3204
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
3205
|
+
"raw",
|
|
3206
|
+
keyBytes.buffer,
|
|
3207
|
+
{ name: "AES-GCM" },
|
|
3208
|
+
false,
|
|
3209
|
+
["encrypt", "decrypt"]
|
|
3210
|
+
);
|
|
3211
|
+
cryptoKeyCache.set(cacheKey, cryptoKey);
|
|
3212
|
+
return cryptoKey;
|
|
3213
|
+
}
|
|
3214
|
+
async function decryptData(encryptedHex, address, version = "v3") {
|
|
3215
|
+
const key = await getEncryptionKey(address, version);
|
|
3216
|
+
return decryptDataWithKey(encryptedHex, key);
|
|
3217
|
+
}
|
|
3218
|
+
function hasEncryptionKey(address) {
|
|
3219
|
+
return getStoredKey(address) !== null;
|
|
3220
|
+
}
|
|
3221
|
+
async function decryptDataWithKey(encryptedHex, key) {
|
|
3222
|
+
const combined = hexToBytes(encryptedHex);
|
|
3223
|
+
const iv = combined.subarray(0, 12);
|
|
3224
|
+
const encryptedData = combined.subarray(12);
|
|
3225
|
+
const decryptedData = await crypto.subtle.decrypt(
|
|
3226
|
+
{
|
|
3227
|
+
name: "AES-GCM",
|
|
3228
|
+
iv
|
|
3229
|
+
},
|
|
3230
|
+
key,
|
|
3231
|
+
encryptedData
|
|
3232
|
+
);
|
|
3233
|
+
return SHARED_TEXT_DECODER.decode(decryptedData);
|
|
3234
|
+
}
|
|
3235
|
+
|
|
3236
|
+
// src/lib/db/encryption-utils.ts
|
|
3237
|
+
function isEncrypted(value) {
|
|
3238
|
+
const prefix = value.startsWith("enc:v3:") ? "enc:v3:" : value.startsWith("enc:v2:") ? "enc:v2:" : null;
|
|
3239
|
+
if (!prefix) return false;
|
|
3240
|
+
const payload = value.slice(prefix.length);
|
|
3241
|
+
return payload.length >= 56 && /^[0-9a-f]+$/i.test(payload);
|
|
3242
|
+
}
|
|
3243
|
+
function detectEncryptionVersion(value) {
|
|
3244
|
+
if (value.startsWith("enc:v3:")) {
|
|
3245
|
+
return { version: "v3", encryptedData: value.slice("enc:v3:".length) };
|
|
3246
|
+
}
|
|
3247
|
+
if (value.startsWith("enc:v2:")) {
|
|
3248
|
+
return { version: "v2", encryptedData: value.slice("enc:v2:".length) };
|
|
3249
|
+
}
|
|
3250
|
+
return null;
|
|
3251
|
+
}
|
|
3252
|
+
async function decryptField(value, address) {
|
|
3253
|
+
if (!value) return value;
|
|
3254
|
+
const detected = detectEncryptionVersion(value);
|
|
3255
|
+
if (!detected) return value;
|
|
3256
|
+
if (detected.encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(detected.encryptedData)) {
|
|
3257
|
+
return value;
|
|
3258
|
+
}
|
|
3259
|
+
try {
|
|
3260
|
+
return await decryptData(detected.encryptedData, address, detected.version);
|
|
3261
|
+
} catch (error) {
|
|
3262
|
+
getLogger().warn("Failed to decrypt field, returning as-is:", error);
|
|
3263
|
+
return value;
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3267
|
+
// src/lib/chat/useChat/strategies/types.ts
|
|
3268
|
+
function isChatCompletionResponse(r) {
|
|
3269
|
+
if (r.object === "response") return false;
|
|
3270
|
+
if (Array.isArray(r.output)) return false;
|
|
3271
|
+
return true;
|
|
3272
|
+
}
|
|
3273
|
+
function getToolCallEvents(r) {
|
|
3274
|
+
if (isChatCompletionResponse(r)) {
|
|
3275
|
+
return r.portal?.tool_call_events ?? r.tool_call_events;
|
|
3276
|
+
}
|
|
3277
|
+
return r.tool_call_events;
|
|
3278
|
+
}
|
|
3279
|
+
function getCostMicroUsd(r) {
|
|
3280
|
+
if (isChatCompletionResponse(r)) {
|
|
3281
|
+
return r.portal?.cost_micro_usd ?? r.usage?.cost_micro_usd;
|
|
3282
|
+
}
|
|
3283
|
+
return r.usage?.cost_micro_usd;
|
|
3284
|
+
}
|
|
3285
|
+
function getCreditsUsed(r) {
|
|
3286
|
+
if (isChatCompletionResponse(r)) {
|
|
3287
|
+
return r.portal?.credits_used ?? r.usage?.credits_used;
|
|
3288
|
+
}
|
|
3289
|
+
return r.usage?.credits_used;
|
|
3290
|
+
}
|
|
3291
|
+
function getImageModel(r) {
|
|
3292
|
+
if (isChatCompletionResponse(r)) {
|
|
3293
|
+
return r.portal?.image_model ?? r.image_model;
|
|
3294
|
+
}
|
|
3295
|
+
return r.image_model;
|
|
3296
|
+
}
|
|
3297
|
+
|
|
3275
3298
|
// src/lib/memoryEngine/quantization.ts
|
|
3276
3299
|
var INT8_MAX = 127;
|
|
3277
3300
|
function quantizeEmbedding(v) {
|