@hef2024/llmasaservice-ui 0.24.4 → 0.24.5
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 +68 -39
- package/dist/index.mjs +68 -39
- package/package.json +1 -1
- package/src/AIChatPanel.tsx +37 -4
- package/src/ChatPanel.tsx +45 -38
package/dist/index.js
CHANGED
|
@@ -1414,46 +1414,51 @@ var ChatPanel = ({
|
|
|
1414
1414
|
const urlToFetch = `${publicAPIUrl}/tools/${encodeURIComponent(
|
|
1415
1415
|
m.url
|
|
1416
1416
|
)}`;
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
if (!response2.ok) {
|
|
1426
|
-
console.error(
|
|
1427
|
-
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1428
|
-
);
|
|
1429
|
-
const errorBody = yield response2.text();
|
|
1430
|
-
console.error(`Error body: ${errorBody}`);
|
|
1431
|
-
throw new Error(
|
|
1432
|
-
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1433
|
-
);
|
|
1434
|
-
}
|
|
1435
|
-
const toolsFromServer = yield response2.json();
|
|
1436
|
-
if (Array.isArray(toolsFromServer)) {
|
|
1437
|
-
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1438
|
-
url: m.url,
|
|
1439
|
-
accessToken: m.accessToken || "",
|
|
1440
|
-
headers: requestHeaders
|
|
1441
|
-
}));
|
|
1442
|
-
} else {
|
|
1443
|
-
return [];
|
|
1444
|
-
}
|
|
1445
|
-
} catch (fetchError) {
|
|
1417
|
+
const requestHeaders = yield buildMcpRequestHeaders({
|
|
1418
|
+
phase: "list",
|
|
1419
|
+
mcpServer: m
|
|
1420
|
+
});
|
|
1421
|
+
const response2 = yield fetch(urlToFetch, {
|
|
1422
|
+
headers: requestHeaders
|
|
1423
|
+
});
|
|
1424
|
+
if (!response2.ok) {
|
|
1446
1425
|
console.error(
|
|
1447
|
-
`
|
|
1448
|
-
fetchError
|
|
1426
|
+
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1449
1427
|
);
|
|
1450
|
-
|
|
1428
|
+
const errorBody = yield response2.text();
|
|
1429
|
+
console.error(`Error body: ${errorBody}`);
|
|
1430
|
+
throw new Error(
|
|
1431
|
+
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1432
|
+
);
|
|
1433
|
+
}
|
|
1434
|
+
const toolsFromServer = yield response2.json();
|
|
1435
|
+
if (Array.isArray(toolsFromServer)) {
|
|
1436
|
+
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1437
|
+
url: m.url,
|
|
1438
|
+
accessToken: m.accessToken || "",
|
|
1439
|
+
headers: requestHeaders
|
|
1440
|
+
}));
|
|
1451
1441
|
}
|
|
1442
|
+
return [];
|
|
1452
1443
|
}));
|
|
1453
|
-
const
|
|
1454
|
-
const allTools =
|
|
1444
|
+
const settledResults = yield Promise.allSettled(fetchPromises);
|
|
1445
|
+
const allTools = settledResults.flatMap((result, index) => {
|
|
1446
|
+
if (result.status === "fulfilled") {
|
|
1447
|
+
return result.value;
|
|
1448
|
+
}
|
|
1449
|
+
const server = mcpServers == null ? void 0 : mcpServers[index];
|
|
1450
|
+
const failingUrl = typeof (server == null ? void 0 : server.url) === "string" ? server.url : `mcp[${index}]`;
|
|
1451
|
+
console.error(
|
|
1452
|
+
`Network or parsing error fetching tools from ${failingUrl}:`,
|
|
1453
|
+
result.reason
|
|
1454
|
+
);
|
|
1455
|
+
return [];
|
|
1456
|
+
});
|
|
1457
|
+
const failedCount = settledResults.filter(
|
|
1458
|
+
(result) => result.status === "rejected"
|
|
1459
|
+
).length;
|
|
1455
1460
|
setToolList(allTools);
|
|
1456
|
-
setToolsFetchError(
|
|
1461
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
1457
1462
|
} catch (error2) {
|
|
1458
1463
|
console.error(
|
|
1459
1464
|
"An error occurred while processing tool fetches:",
|
|
@@ -5418,7 +5423,7 @@ var AIChatPanel = ({
|
|
|
5418
5423
|
return;
|
|
5419
5424
|
}
|
|
5420
5425
|
try {
|
|
5421
|
-
const
|
|
5426
|
+
const settled = yield Promise.allSettled(
|
|
5422
5427
|
mcpServers.map((server) => __async(void 0, null, function* () {
|
|
5423
5428
|
const resolved = yield resolveMcpAuthHeaders({
|
|
5424
5429
|
phase: "list",
|
|
@@ -5433,6 +5438,18 @@ var AIChatPanel = ({
|
|
|
5433
5438
|
});
|
|
5434
5439
|
}))
|
|
5435
5440
|
);
|
|
5441
|
+
const enriched = settled.map((result, index) => {
|
|
5442
|
+
var _a2;
|
|
5443
|
+
if (result.status === "fulfilled") {
|
|
5444
|
+
return result.value;
|
|
5445
|
+
}
|
|
5446
|
+
const failingUrl = typeof ((_a2 = mcpServers == null ? void 0 : mcpServers[index]) == null ? void 0 : _a2.url) === "string" ? mcpServers[index].url : `mcp[${index}]`;
|
|
5447
|
+
console.error(
|
|
5448
|
+
`[AIChatPanel] Failed to resolve MCP auth headers for ${failingUrl}:`,
|
|
5449
|
+
result.reason
|
|
5450
|
+
);
|
|
5451
|
+
return mcpServers[index];
|
|
5452
|
+
});
|
|
5436
5453
|
if (!cancelled) setResolvedMcpServers(enriched);
|
|
5437
5454
|
} catch (error2) {
|
|
5438
5455
|
console.error("[AIChatPanel] Failed to resolve MCP auth headers:", error2);
|
|
@@ -5524,10 +5541,22 @@ var AIChatPanel = ({
|
|
|
5524
5541
|
headers: requestHeaders
|
|
5525
5542
|
}));
|
|
5526
5543
|
}));
|
|
5527
|
-
const
|
|
5528
|
-
const allTools =
|
|
5544
|
+
const settled = yield Promise.allSettled(fetchPromises);
|
|
5545
|
+
const allTools = settled.flatMap((result, index) => {
|
|
5546
|
+
var _a2;
|
|
5547
|
+
if (result.status === "fulfilled") {
|
|
5548
|
+
return result.value;
|
|
5549
|
+
}
|
|
5550
|
+
const failingUrl = typeof ((_a2 = resolvedMcpServers == null ? void 0 : resolvedMcpServers[index]) == null ? void 0 : _a2.url) === "string" ? resolvedMcpServers[index].url : `mcp[${index}]`;
|
|
5551
|
+
console.error(
|
|
5552
|
+
`[AIChatPanel] Failed to load MCP tools from ${failingUrl}:`,
|
|
5553
|
+
result.reason
|
|
5554
|
+
);
|
|
5555
|
+
return [];
|
|
5556
|
+
});
|
|
5557
|
+
const failedCount = settled.filter((result) => result.status === "rejected").length;
|
|
5529
5558
|
setToolList(allTools);
|
|
5530
|
-
setToolsFetchError(
|
|
5559
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
5531
5560
|
} catch (error2) {
|
|
5532
5561
|
console.error("[AIChatPanel] Failed to load MCP tools:", error2);
|
|
5533
5562
|
setToolList([]);
|
package/dist/index.mjs
CHANGED
|
@@ -1373,46 +1373,51 @@ var ChatPanel = ({
|
|
|
1373
1373
|
const urlToFetch = `${publicAPIUrl}/tools/${encodeURIComponent(
|
|
1374
1374
|
m.url
|
|
1375
1375
|
)}`;
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
if (!response2.ok) {
|
|
1385
|
-
console.error(
|
|
1386
|
-
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1387
|
-
);
|
|
1388
|
-
const errorBody = yield response2.text();
|
|
1389
|
-
console.error(`Error body: ${errorBody}`);
|
|
1390
|
-
throw new Error(
|
|
1391
|
-
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1392
|
-
);
|
|
1393
|
-
}
|
|
1394
|
-
const toolsFromServer = yield response2.json();
|
|
1395
|
-
if (Array.isArray(toolsFromServer)) {
|
|
1396
|
-
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1397
|
-
url: m.url,
|
|
1398
|
-
accessToken: m.accessToken || "",
|
|
1399
|
-
headers: requestHeaders
|
|
1400
|
-
}));
|
|
1401
|
-
} else {
|
|
1402
|
-
return [];
|
|
1403
|
-
}
|
|
1404
|
-
} catch (fetchError) {
|
|
1376
|
+
const requestHeaders = yield buildMcpRequestHeaders({
|
|
1377
|
+
phase: "list",
|
|
1378
|
+
mcpServer: m
|
|
1379
|
+
});
|
|
1380
|
+
const response2 = yield fetch(urlToFetch, {
|
|
1381
|
+
headers: requestHeaders
|
|
1382
|
+
});
|
|
1383
|
+
if (!response2.ok) {
|
|
1405
1384
|
console.error(
|
|
1406
|
-
`
|
|
1407
|
-
fetchError
|
|
1385
|
+
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1408
1386
|
);
|
|
1409
|
-
|
|
1387
|
+
const errorBody = yield response2.text();
|
|
1388
|
+
console.error(`Error body: ${errorBody}`);
|
|
1389
|
+
throw new Error(
|
|
1390
|
+
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
const toolsFromServer = yield response2.json();
|
|
1394
|
+
if (Array.isArray(toolsFromServer)) {
|
|
1395
|
+
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1396
|
+
url: m.url,
|
|
1397
|
+
accessToken: m.accessToken || "",
|
|
1398
|
+
headers: requestHeaders
|
|
1399
|
+
}));
|
|
1410
1400
|
}
|
|
1401
|
+
return [];
|
|
1411
1402
|
}));
|
|
1412
|
-
const
|
|
1413
|
-
const allTools =
|
|
1403
|
+
const settledResults = yield Promise.allSettled(fetchPromises);
|
|
1404
|
+
const allTools = settledResults.flatMap((result, index) => {
|
|
1405
|
+
if (result.status === "fulfilled") {
|
|
1406
|
+
return result.value;
|
|
1407
|
+
}
|
|
1408
|
+
const server = mcpServers == null ? void 0 : mcpServers[index];
|
|
1409
|
+
const failingUrl = typeof (server == null ? void 0 : server.url) === "string" ? server.url : `mcp[${index}]`;
|
|
1410
|
+
console.error(
|
|
1411
|
+
`Network or parsing error fetching tools from ${failingUrl}:`,
|
|
1412
|
+
result.reason
|
|
1413
|
+
);
|
|
1414
|
+
return [];
|
|
1415
|
+
});
|
|
1416
|
+
const failedCount = settledResults.filter(
|
|
1417
|
+
(result) => result.status === "rejected"
|
|
1418
|
+
).length;
|
|
1414
1419
|
setToolList(allTools);
|
|
1415
|
-
setToolsFetchError(
|
|
1420
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
1416
1421
|
} catch (error2) {
|
|
1417
1422
|
console.error(
|
|
1418
1423
|
"An error occurred while processing tool fetches:",
|
|
@@ -5383,7 +5388,7 @@ var AIChatPanel = ({
|
|
|
5383
5388
|
return;
|
|
5384
5389
|
}
|
|
5385
5390
|
try {
|
|
5386
|
-
const
|
|
5391
|
+
const settled = yield Promise.allSettled(
|
|
5387
5392
|
mcpServers.map((server) => __async(void 0, null, function* () {
|
|
5388
5393
|
const resolved = yield resolveMcpAuthHeaders({
|
|
5389
5394
|
phase: "list",
|
|
@@ -5398,6 +5403,18 @@ var AIChatPanel = ({
|
|
|
5398
5403
|
});
|
|
5399
5404
|
}))
|
|
5400
5405
|
);
|
|
5406
|
+
const enriched = settled.map((result, index) => {
|
|
5407
|
+
var _a2;
|
|
5408
|
+
if (result.status === "fulfilled") {
|
|
5409
|
+
return result.value;
|
|
5410
|
+
}
|
|
5411
|
+
const failingUrl = typeof ((_a2 = mcpServers == null ? void 0 : mcpServers[index]) == null ? void 0 : _a2.url) === "string" ? mcpServers[index].url : `mcp[${index}]`;
|
|
5412
|
+
console.error(
|
|
5413
|
+
`[AIChatPanel] Failed to resolve MCP auth headers for ${failingUrl}:`,
|
|
5414
|
+
result.reason
|
|
5415
|
+
);
|
|
5416
|
+
return mcpServers[index];
|
|
5417
|
+
});
|
|
5401
5418
|
if (!cancelled) setResolvedMcpServers(enriched);
|
|
5402
5419
|
} catch (error2) {
|
|
5403
5420
|
console.error("[AIChatPanel] Failed to resolve MCP auth headers:", error2);
|
|
@@ -5489,10 +5506,22 @@ var AIChatPanel = ({
|
|
|
5489
5506
|
headers: requestHeaders
|
|
5490
5507
|
}));
|
|
5491
5508
|
}));
|
|
5492
|
-
const
|
|
5493
|
-
const allTools =
|
|
5509
|
+
const settled = yield Promise.allSettled(fetchPromises);
|
|
5510
|
+
const allTools = settled.flatMap((result, index) => {
|
|
5511
|
+
var _a2;
|
|
5512
|
+
if (result.status === "fulfilled") {
|
|
5513
|
+
return result.value;
|
|
5514
|
+
}
|
|
5515
|
+
const failingUrl = typeof ((_a2 = resolvedMcpServers == null ? void 0 : resolvedMcpServers[index]) == null ? void 0 : _a2.url) === "string" ? resolvedMcpServers[index].url : `mcp[${index}]`;
|
|
5516
|
+
console.error(
|
|
5517
|
+
`[AIChatPanel] Failed to load MCP tools from ${failingUrl}:`,
|
|
5518
|
+
result.reason
|
|
5519
|
+
);
|
|
5520
|
+
return [];
|
|
5521
|
+
});
|
|
5522
|
+
const failedCount = settled.filter((result) => result.status === "rejected").length;
|
|
5494
5523
|
setToolList(allTools);
|
|
5495
|
-
setToolsFetchError(
|
|
5524
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
5496
5525
|
} catch (error2) {
|
|
5497
5526
|
console.error("[AIChatPanel] Failed to load MCP tools:", error2);
|
|
5498
5527
|
setToolList([]);
|
package/package.json
CHANGED
package/src/AIChatPanel.tsx
CHANGED
|
@@ -2006,7 +2006,7 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
2006
2006
|
}
|
|
2007
2007
|
|
|
2008
2008
|
try {
|
|
2009
|
-
const
|
|
2009
|
+
const settled = await Promise.allSettled(
|
|
2010
2010
|
mcpServers.map(async (server) => {
|
|
2011
2011
|
const resolved = await resolveMcpAuthHeaders({
|
|
2012
2012
|
phase: 'list',
|
|
@@ -2025,6 +2025,23 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
2025
2025
|
};
|
|
2026
2026
|
})
|
|
2027
2027
|
);
|
|
2028
|
+
|
|
2029
|
+
const enriched = settled.map((result, index) => {
|
|
2030
|
+
if (result.status === 'fulfilled') {
|
|
2031
|
+
return result.value;
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
const failingUrl =
|
|
2035
|
+
typeof mcpServers?.[index]?.url === 'string'
|
|
2036
|
+
? mcpServers[index].url
|
|
2037
|
+
: `mcp[${index}]`;
|
|
2038
|
+
console.error(
|
|
2039
|
+
`[AIChatPanel] Failed to resolve MCP auth headers for ${failingUrl}:`,
|
|
2040
|
+
result.reason
|
|
2041
|
+
);
|
|
2042
|
+
return mcpServers[index];
|
|
2043
|
+
});
|
|
2044
|
+
|
|
2028
2045
|
if (!cancelled) setResolvedMcpServers(enriched);
|
|
2029
2046
|
} catch (error) {
|
|
2030
2047
|
console.error('[AIChatPanel] Failed to resolve MCP auth headers:', error);
|
|
@@ -2142,10 +2159,26 @@ const AIChatPanel: React.FC<AIChatPanelProps> = ({
|
|
|
2142
2159
|
}));
|
|
2143
2160
|
});
|
|
2144
2161
|
|
|
2145
|
-
const
|
|
2146
|
-
const allTools =
|
|
2162
|
+
const settled = await Promise.allSettled(fetchPromises);
|
|
2163
|
+
const allTools = settled.flatMap((result, index) => {
|
|
2164
|
+
if (result.status === 'fulfilled') {
|
|
2165
|
+
return result.value;
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
const failingUrl =
|
|
2169
|
+
typeof resolvedMcpServers?.[index]?.url === 'string'
|
|
2170
|
+
? resolvedMcpServers[index].url
|
|
2171
|
+
: `mcp[${index}]`;
|
|
2172
|
+
console.error(
|
|
2173
|
+
`[AIChatPanel] Failed to load MCP tools from ${failingUrl}:`,
|
|
2174
|
+
result.reason
|
|
2175
|
+
);
|
|
2176
|
+
return [];
|
|
2177
|
+
});
|
|
2178
|
+
|
|
2179
|
+
const failedCount = settled.filter((result) => result.status === 'rejected').length;
|
|
2147
2180
|
setToolList(allTools);
|
|
2148
|
-
setToolsFetchError(
|
|
2181
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
2149
2182
|
} catch (error) {
|
|
2150
2183
|
console.error('[AIChatPanel] Failed to load MCP tools:', error);
|
|
2151
2184
|
setToolList([]);
|
package/src/ChatPanel.tsx
CHANGED
|
@@ -701,58 +701,65 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
701
701
|
setToolsFetchError(false);
|
|
702
702
|
|
|
703
703
|
try {
|
|
704
|
-
// Create an array of promises, one for each fetch call
|
|
705
704
|
const fetchPromises = (mcpServers ?? []).map(async (m: any) => {
|
|
706
705
|
const urlToFetch = `${publicAPIUrl}/tools/${encodeURIComponent(
|
|
707
706
|
m.url
|
|
708
707
|
)}`;
|
|
709
708
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
if (!response.ok) {
|
|
719
|
-
console.error(
|
|
720
|
-
`Error fetching tools from ${m.url}: ${response.status} ${response.statusText}`
|
|
721
|
-
);
|
|
722
|
-
const errorBody = await response.text();
|
|
723
|
-
console.error(`Error body: ${errorBody}`);
|
|
724
|
-
throw new Error(
|
|
725
|
-
`HTTP ${response.status}: ${response.statusText}`
|
|
726
|
-
);
|
|
727
|
-
}
|
|
728
|
-
const toolsFromServer = await response.json();
|
|
729
|
-
if (Array.isArray(toolsFromServer)) {
|
|
730
|
-
return toolsFromServer.map((tool) => ({
|
|
731
|
-
...tool,
|
|
732
|
-
url: m.url,
|
|
733
|
-
accessToken: m.accessToken || "",
|
|
734
|
-
headers: requestHeaders,
|
|
735
|
-
}));
|
|
736
|
-
} else {
|
|
737
|
-
return [];
|
|
738
|
-
}
|
|
739
|
-
} catch (fetchError) {
|
|
709
|
+
const requestHeaders = await buildMcpRequestHeaders({
|
|
710
|
+
phase: "list",
|
|
711
|
+
mcpServer: m,
|
|
712
|
+
});
|
|
713
|
+
const response = await fetch(urlToFetch, {
|
|
714
|
+
headers: requestHeaders,
|
|
715
|
+
});
|
|
716
|
+
if (!response.ok) {
|
|
740
717
|
console.error(
|
|
741
|
-
`
|
|
742
|
-
fetchError
|
|
718
|
+
`Error fetching tools from ${m.url}: ${response.status} ${response.statusText}`
|
|
743
719
|
);
|
|
744
|
-
|
|
720
|
+
const errorBody = await response.text();
|
|
721
|
+
console.error(`Error body: ${errorBody}`);
|
|
722
|
+
throw new Error(
|
|
723
|
+
`HTTP ${response.status}: ${response.statusText}`
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
const toolsFromServer = await response.json();
|
|
727
|
+
if (Array.isArray(toolsFromServer)) {
|
|
728
|
+
return toolsFromServer.map((tool) => ({
|
|
729
|
+
...tool,
|
|
730
|
+
url: m.url,
|
|
731
|
+
accessToken: m.accessToken || "",
|
|
732
|
+
headers: requestHeaders,
|
|
733
|
+
}));
|
|
745
734
|
}
|
|
735
|
+
return [];
|
|
746
736
|
});
|
|
747
737
|
|
|
748
|
-
|
|
749
|
-
const
|
|
738
|
+
const settledResults = await Promise.allSettled(fetchPromises);
|
|
739
|
+
const allTools = settledResults.flatMap((result, index) => {
|
|
740
|
+
if (result.status === "fulfilled") {
|
|
741
|
+
return result.value;
|
|
742
|
+
}
|
|
750
743
|
|
|
751
|
-
|
|
744
|
+
const server = (mcpServers as Array<{ url?: string }> | undefined)?.[
|
|
745
|
+
index
|
|
746
|
+
];
|
|
747
|
+
const failingUrl =
|
|
748
|
+
typeof server?.url === "string" ? server.url : `mcp[${index}]`;
|
|
749
|
+
console.error(
|
|
750
|
+
`Network or parsing error fetching tools from ${failingUrl}:`,
|
|
751
|
+
result.reason
|
|
752
|
+
);
|
|
753
|
+
return [];
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
const failedCount = settledResults.filter(
|
|
757
|
+
(result) => result.status === "rejected"
|
|
758
|
+
).length;
|
|
752
759
|
|
|
753
760
|
//console.log("Merged tools from all servers:", allTools);
|
|
754
761
|
setToolList(allTools);
|
|
755
|
-
setToolsFetchError(
|
|
762
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
756
763
|
} catch (error) {
|
|
757
764
|
console.error(
|
|
758
765
|
"An error occurred while processing tool fetches:",
|