mitra-interactions-sdk 1.0.63 → 1.0.64-rc.1
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 +103 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +103 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -386,7 +386,18 @@ function buildUrl(endpoint, params) {
|
|
|
386
386
|
}
|
|
387
387
|
return url;
|
|
388
388
|
}
|
|
389
|
-
|
|
389
|
+
var refreshInFlight = null;
|
|
390
|
+
function tryRefreshToken() {
|
|
391
|
+
if (refreshInFlight) return refreshInFlight;
|
|
392
|
+
const attempt = doRefreshToken();
|
|
393
|
+
refreshInFlight = attempt;
|
|
394
|
+
const clear = () => {
|
|
395
|
+
if (refreshInFlight === attempt) refreshInFlight = null;
|
|
396
|
+
};
|
|
397
|
+
attempt.then(clear, clear);
|
|
398
|
+
return attempt;
|
|
399
|
+
}
|
|
400
|
+
async function doRefreshToken() {
|
|
390
401
|
var _a, _b;
|
|
391
402
|
const config = getConfig();
|
|
392
403
|
if (!config.token || config.projectId == null || !config.baseURL) return false;
|
|
@@ -1377,6 +1388,7 @@ async function agentHttpPost(path, body) {
|
|
|
1377
1388
|
if (typeof fetchFn !== "function") {
|
|
1378
1389
|
throw new Error("Agent Chat (HTTP): fetch indispon\xEDvel. Use Node 18+ ou um browser.");
|
|
1379
1390
|
}
|
|
1391
|
+
if (isTokenExpiring()) await tryRefreshToken();
|
|
1380
1392
|
const resp = await fetchFn(`${getAgentHttpBase()}${path}`, {
|
|
1381
1393
|
method: "POST",
|
|
1382
1394
|
headers: {
|
|
@@ -1406,16 +1418,16 @@ async function httpSendPrompt(payload, taskId) {
|
|
|
1406
1418
|
routeMessage({ type: "stream_end", taskId: resolvedTaskId });
|
|
1407
1419
|
}
|
|
1408
1420
|
}
|
|
1409
|
-
function
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1421
|
+
function isChannelError(err) {
|
|
1422
|
+
const msg = err instanceof Error ? err.message : String(err != null ? err : "");
|
|
1423
|
+
return /conexão fechada|timeout ao conectar|erro ao conectar/i.test(msg);
|
|
1424
|
+
}
|
|
1425
|
+
function openSocket() {
|
|
1414
1426
|
const baseUrl = getWsUrl();
|
|
1415
1427
|
const token = getRawToken();
|
|
1416
1428
|
const separator = baseUrl.includes("?") ? "&" : "?";
|
|
1417
1429
|
const url = `${baseUrl}${separator}token=${encodeURIComponent(token)}`;
|
|
1418
|
-
|
|
1430
|
+
return new Promise((resolve, reject) => {
|
|
1419
1431
|
const socket = new WebSocket(url);
|
|
1420
1432
|
let opened = false;
|
|
1421
1433
|
const timer = setTimeout(() => {
|
|
@@ -1424,7 +1436,6 @@ function connect() {
|
|
|
1424
1436
|
socket.close();
|
|
1425
1437
|
} catch (e) {
|
|
1426
1438
|
}
|
|
1427
|
-
connectPromise = null;
|
|
1428
1439
|
reject(new Error("Agent Chat: timeout ao conectar no WebSocket"));
|
|
1429
1440
|
}
|
|
1430
1441
|
}, 15e3);
|
|
@@ -1432,18 +1443,20 @@ function connect() {
|
|
|
1432
1443
|
opened = true;
|
|
1433
1444
|
clearTimeout(timer);
|
|
1434
1445
|
ws = socket;
|
|
1435
|
-
connectPromise = null;
|
|
1436
1446
|
resolve(socket);
|
|
1437
1447
|
};
|
|
1438
1448
|
socket.onerror = () => {
|
|
1439
1449
|
if (!opened) {
|
|
1440
1450
|
clearTimeout(timer);
|
|
1441
|
-
connectPromise = null;
|
|
1442
1451
|
reject(new Error("Agent Chat: erro ao conectar no WebSocket"));
|
|
1443
1452
|
}
|
|
1444
1453
|
};
|
|
1445
1454
|
socket.onclose = () => {
|
|
1446
1455
|
if (ws === socket) ws = null;
|
|
1456
|
+
if (!opened) {
|
|
1457
|
+
clearTimeout(timer);
|
|
1458
|
+
reject(new Error("Agent Chat: conex\xE3o fechada"));
|
|
1459
|
+
}
|
|
1447
1460
|
for (const [id, pending] of pendingRequests) {
|
|
1448
1461
|
pending.reject(new Error("Agent Chat: conex\xE3o fechada"));
|
|
1449
1462
|
pendingRequests.delete(id);
|
|
@@ -1452,7 +1465,29 @@ function connect() {
|
|
|
1452
1465
|
};
|
|
1453
1466
|
socket.onmessage = (event) => routeMessage(event.data);
|
|
1454
1467
|
});
|
|
1455
|
-
|
|
1468
|
+
}
|
|
1469
|
+
function connect() {
|
|
1470
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
1471
|
+
return Promise.resolve(ws);
|
|
1472
|
+
}
|
|
1473
|
+
if (connectPromise) return connectPromise;
|
|
1474
|
+
const attempt = (async () => {
|
|
1475
|
+
if (isTokenExpiring()) await tryRefreshToken();
|
|
1476
|
+
try {
|
|
1477
|
+
return await openSocket();
|
|
1478
|
+
} catch (err) {
|
|
1479
|
+
if (!isChannelError(err)) throw err;
|
|
1480
|
+
const refreshed = await tryRefreshToken();
|
|
1481
|
+
if (!refreshed) throw err;
|
|
1482
|
+
return openSocket();
|
|
1483
|
+
}
|
|
1484
|
+
})();
|
|
1485
|
+
connectPromise = attempt;
|
|
1486
|
+
const clear = () => {
|
|
1487
|
+
if (connectPromise === attempt) connectPromise = null;
|
|
1488
|
+
};
|
|
1489
|
+
attempt.then(clear, clear);
|
|
1490
|
+
return attempt;
|
|
1456
1491
|
}
|
|
1457
1492
|
function routeMessage(raw) {
|
|
1458
1493
|
var _a, _b;
|
|
@@ -1492,6 +1527,21 @@ function routeMessage(raw) {
|
|
|
1492
1527
|
for (const handler of pendingHandlers.values()) handler(msg);
|
|
1493
1528
|
}
|
|
1494
1529
|
}
|
|
1530
|
+
function requestOverSocket(type, payload) {
|
|
1531
|
+
return connect().then((socket) => new Promise((resolve, reject) => {
|
|
1532
|
+
const requestId = nextRequestId();
|
|
1533
|
+
pendingRequests.set(requestId, {
|
|
1534
|
+
resolve: (data) => resolve(data),
|
|
1535
|
+
reject
|
|
1536
|
+
});
|
|
1537
|
+
try {
|
|
1538
|
+
socket.send(JSON.stringify({ type, requestId, payload }));
|
|
1539
|
+
} catch (err) {
|
|
1540
|
+
pendingRequests.delete(requestId);
|
|
1541
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
1542
|
+
}
|
|
1543
|
+
}));
|
|
1544
|
+
}
|
|
1495
1545
|
var transport = {
|
|
1496
1546
|
async ensureConnected() {
|
|
1497
1547
|
if (isHttpEnabled()) return;
|
|
@@ -1504,20 +1554,14 @@ var transport = {
|
|
|
1504
1554
|
if (data && data.ok === false) throw new Error(data.error || "Erro desconhecido");
|
|
1505
1555
|
return (_a = data == null ? void 0 : data.data) != null ? _a : data;
|
|
1506
1556
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
socket.send(JSON.stringify({ type, requestId, payload }));
|
|
1516
|
-
} catch (err) {
|
|
1517
|
-
pendingRequests.delete(requestId);
|
|
1518
|
-
reject(err instanceof Error ? err : new Error(String(err)));
|
|
1519
|
-
}
|
|
1520
|
-
});
|
|
1557
|
+
try {
|
|
1558
|
+
return await requestOverSocket(type, payload);
|
|
1559
|
+
} catch (err) {
|
|
1560
|
+
if (!isChannelError(err)) throw err;
|
|
1561
|
+
const refreshed = await tryRefreshToken();
|
|
1562
|
+
if (!refreshed) throw err;
|
|
1563
|
+
return requestOverSocket(type, payload);
|
|
1564
|
+
}
|
|
1521
1565
|
},
|
|
1522
1566
|
send(type, payload, taskId) {
|
|
1523
1567
|
if (isHttpEnabled()) {
|
|
@@ -1752,7 +1796,18 @@ function createMitraInstance(initialConfig) {
|
|
|
1752
1796
|
}
|
|
1753
1797
|
return data;
|
|
1754
1798
|
}
|
|
1755
|
-
|
|
1799
|
+
let refreshInFlight2 = null;
|
|
1800
|
+
function tryRefreshToken2() {
|
|
1801
|
+
if (refreshInFlight2) return refreshInFlight2;
|
|
1802
|
+
const attempt = doRefreshToken2();
|
|
1803
|
+
refreshInFlight2 = attempt;
|
|
1804
|
+
const clear = () => {
|
|
1805
|
+
if (refreshInFlight2 === attempt) refreshInFlight2 = null;
|
|
1806
|
+
};
|
|
1807
|
+
attempt.then(clear, clear);
|
|
1808
|
+
return attempt;
|
|
1809
|
+
}
|
|
1810
|
+
async function doRefreshToken2() {
|
|
1756
1811
|
var _a2, _b;
|
|
1757
1812
|
if (!_config.token || _config.projectId == null || !_config.baseURL) return false;
|
|
1758
1813
|
try {
|
|
@@ -1771,6 +1826,7 @@ function createMitraInstance(initialConfig) {
|
|
|
1771
1826
|
...((_b = data.merge) == null ? void 0 : _b.integrationURL) ? { integrationURL: data.merge.integrationURL } : {}
|
|
1772
1827
|
};
|
|
1773
1828
|
_config = { ..._config, token: stripBearer(session.token) };
|
|
1829
|
+
updateGlobalToken(session.token);
|
|
1774
1830
|
if (_config.onTokenRefresh) _config.onTokenRefresh(session);
|
|
1775
1831
|
return true;
|
|
1776
1832
|
}
|
|
@@ -1781,6 +1837,7 @@ function createMitraInstance(initialConfig) {
|
|
|
1781
1837
|
try {
|
|
1782
1838
|
const session = await refreshTokenSilently(_config.authUrl, _config.projectId);
|
|
1783
1839
|
_config = { ..._config, token: stripBearer(session.token) };
|
|
1840
|
+
updateGlobalToken(session.token);
|
|
1784
1841
|
if (_config.onTokenRefresh) _config.onTokenRefresh(session);
|
|
1785
1842
|
return true;
|
|
1786
1843
|
} catch (e) {
|
|
@@ -2089,6 +2146,26 @@ function stripBearer(token) {
|
|
|
2089
2146
|
}
|
|
2090
2147
|
return t;
|
|
2091
2148
|
}
|
|
2149
|
+
function decodeJwtPayload(token) {
|
|
2150
|
+
try {
|
|
2151
|
+
const part = stripBearer(token).split(".")[1];
|
|
2152
|
+
if (!part) return null;
|
|
2153
|
+
const b64 = part.replace(/-/g, "+").replace(/_/g, "/");
|
|
2154
|
+
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
2155
|
+
const json = typeof atob === "function" ? atob(padded) : Buffer.from(padded, "base64").toString("utf8");
|
|
2156
|
+
return JSON.parse(json);
|
|
2157
|
+
} catch (e) {
|
|
2158
|
+
return null;
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
function isTokenExpiring(token, skewMs = 6e4) {
|
|
2162
|
+
const t = globalConfig == null ? void 0 : globalConfig.token;
|
|
2163
|
+
if (!t) return false;
|
|
2164
|
+
const payload = decodeJwtPayload(t);
|
|
2165
|
+
const exp = payload == null ? void 0 : payload.exp;
|
|
2166
|
+
if (typeof exp !== "number") return false;
|
|
2167
|
+
return exp * 1e3 - Date.now() < skewMs;
|
|
2168
|
+
}
|
|
2092
2169
|
function readInjectedEnv() {
|
|
2093
2170
|
if (typeof window === "undefined") return {};
|
|
2094
2171
|
const env = window.__mitraEnv;
|