@anuma/sdk 6.31.2 → 6.31.4
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/index.cjs +170 -107
- package/dist/expo/index.d.mts +22 -1
- package/dist/expo/index.d.ts +22 -1
- package/dist/expo/index.mjs +169 -107
- package/dist/react/index.cjs +340 -153
- package/dist/react/index.d.mts +22 -1
- package/dist/react/index.d.ts +22 -1
- package/dist/react/index.mjs +339 -153
- package/dist/server/index.cjs +236 -171
- package/dist/server/index.d.mts +22 -1
- package/dist/server/index.d.ts +22 -1
- package/dist/server/index.mjs +235 -171
- package/dist/tools/index.cjs +72 -72
- package/dist/tools/index.d.mts +3 -4
- package/dist/tools/index.d.ts +3 -4
- package/dist/tools/index.mjs +72 -72
- package/package.json +2 -2
package/dist/tools/index.cjs
CHANGED
|
@@ -277,12 +277,16 @@ function buildUpdateEventBody(args) {
|
|
|
277
277
|
}
|
|
278
278
|
return eventBody;
|
|
279
279
|
}
|
|
280
|
+
var CALENDAR_EVENT_ID = /^[A-Za-z0-9_]+$/;
|
|
280
281
|
async function updateCalendarEvent(accessToken, args) {
|
|
281
282
|
const { eventId } = args;
|
|
283
|
+
if (typeof eventId !== "string" || !CALENDAR_EVENT_ID.test(eventId)) {
|
|
284
|
+
return `Error: Invalid event ID: ${String(eventId)}`;
|
|
285
|
+
}
|
|
282
286
|
const eventBody = buildUpdateEventBody(args);
|
|
283
287
|
try {
|
|
284
288
|
const response = await fetch(
|
|
285
|
-
`https://www.googleapis.com/calendar/v3/calendars/primary/events/${eventId}`,
|
|
289
|
+
`https://www.googleapis.com/calendar/v3/calendars/primary/events/${encodeURIComponent(eventId)}`,
|
|
286
290
|
{
|
|
287
291
|
method: "PATCH",
|
|
288
292
|
headers: {
|
|
@@ -1151,55 +1155,40 @@ function createWeatherTool(options, weatherOptions) {
|
|
|
1151
1155
|
|
|
1152
1156
|
// src/lib/connectors/errors.ts
|
|
1153
1157
|
var CONNECTOR_ERROR_MARKER = "__anuma_connector_error_v1";
|
|
1154
|
-
function buildConnectorErrorResult(code, provider,
|
|
1158
|
+
function buildConnectorErrorResult(code, provider, extras) {
|
|
1155
1159
|
const payload = {
|
|
1156
1160
|
__anuma_connector_error_v1: true,
|
|
1157
1161
|
code,
|
|
1158
1162
|
provider,
|
|
1159
|
-
connect_url: connectUrl,
|
|
1160
1163
|
missing_scopes: extras?.missingScopes,
|
|
1161
1164
|
required: extras?.required
|
|
1162
1165
|
};
|
|
1163
1166
|
return JSON.stringify(payload);
|
|
1164
1167
|
}
|
|
1165
1168
|
|
|
1166
|
-
// src/lib/logger.ts
|
|
1167
|
-
var consoleLogger = {
|
|
1168
|
-
debug: console.log.bind(console),
|
|
1169
|
-
info: console.info.bind(console),
|
|
1170
|
-
warn: console.warn.bind(console),
|
|
1171
|
-
error: console.error.bind(console)
|
|
1172
|
-
};
|
|
1173
|
-
var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
|
|
1174
|
-
var loggerGlobal = globalThis;
|
|
1175
|
-
var fallbackLoggerState = { logger: consoleLogger };
|
|
1176
|
-
var fallbackWarned = false;
|
|
1177
|
-
function getLoggerState() {
|
|
1178
|
-
try {
|
|
1179
|
-
return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
|
|
1180
|
-
} catch {
|
|
1181
|
-
if (!fallbackWarned) {
|
|
1182
|
-
fallbackWarned = true;
|
|
1183
|
-
fallbackLoggerState.logger.warn(
|
|
1184
|
-
"@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
|
|
1185
|
-
);
|
|
1186
|
-
}
|
|
1187
|
-
return fallbackLoggerState;
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
function getLogger() {
|
|
1191
|
-
return getLoggerState().logger;
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
1169
|
// src/tools/googleDrive.ts
|
|
1195
1170
|
var DRIVE_PROVIDER = "gdrive";
|
|
1171
|
+
var DRIVE_FILE_ID = /^[A-Za-z0-9_-]+$/;
|
|
1172
|
+
var DRIVE_MIME_TYPE = /^[\w.+-]+\/[\w.+-]+$/;
|
|
1173
|
+
function invalidFileIdError(fileId) {
|
|
1174
|
+
return `Error: Invalid file ID: ${String(fileId)}`;
|
|
1175
|
+
}
|
|
1176
|
+
function escapeDriveQueryValue(value) {
|
|
1177
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
1178
|
+
}
|
|
1179
|
+
function withMimeTypeFilter(driveQuery, mimeType) {
|
|
1180
|
+
if (!mimeType) return driveQuery;
|
|
1181
|
+
if (!DRIVE_MIME_TYPE.test(mimeType)) return { error: `Error: Invalid mimeType: ${mimeType}` };
|
|
1182
|
+
return `${driveQuery} and mimeType = '${escapeDriveQueryValue(mimeType)}'`;
|
|
1183
|
+
}
|
|
1196
1184
|
async function searchDriveFiles(accessToken, args) {
|
|
1197
1185
|
const { query, maxResults = 10, mimeType } = args;
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1186
|
+
const filtered = withMimeTypeFilter(
|
|
1187
|
+
`fullText contains '${escapeDriveQueryValue(query)}'`,
|
|
1188
|
+
mimeType
|
|
1189
|
+
);
|
|
1190
|
+
if (typeof filtered !== "string") return filtered.error;
|
|
1191
|
+
const driveQuery = `${filtered} and trashed = false`;
|
|
1203
1192
|
const params = new URLSearchParams({
|
|
1204
1193
|
q: driveQuery,
|
|
1205
1194
|
pageSize: String(maxResults),
|
|
@@ -1292,10 +1281,8 @@ function createGoogleDriveSearchTool(getAccessToken, requestDriveAccess) {
|
|
|
1292
1281
|
}
|
|
1293
1282
|
async function listRecentDriveFiles(accessToken, args) {
|
|
1294
1283
|
const { maxResults = 10, mimeType } = args;
|
|
1295
|
-
|
|
1296
|
-
if (
|
|
1297
|
-
driveQuery += ` and mimeType = '${mimeType}'`;
|
|
1298
|
-
}
|
|
1284
|
+
const driveQuery = withMimeTypeFilter("trashed = false", mimeType);
|
|
1285
|
+
if (typeof driveQuery !== "string") return driveQuery.error;
|
|
1299
1286
|
const params = new URLSearchParams({
|
|
1300
1287
|
q: driveQuery,
|
|
1301
1288
|
pageSize: String(maxResults),
|
|
@@ -1382,7 +1369,7 @@ function createGoogleDriveListRecentTool(getAccessToken, requestDriveAccess) {
|
|
|
1382
1369
|
};
|
|
1383
1370
|
}
|
|
1384
1371
|
async function findFileByName(accessToken, fileName) {
|
|
1385
|
-
const driveQuery = `name contains '${fileName
|
|
1372
|
+
const driveQuery = `name contains '${escapeDriveQueryValue(fileName)}' and trashed = false`;
|
|
1386
1373
|
const params = new URLSearchParams({
|
|
1387
1374
|
q: driveQuery,
|
|
1388
1375
|
pageSize: "1",
|
|
@@ -1412,24 +1399,22 @@ var GOOGLE_DOCS_EXPORT_TYPES = {
|
|
|
1412
1399
|
var MAX_CONTENT_LENGTH = 5e4;
|
|
1413
1400
|
async function resolveFileId(accessToken, fileId, fileName) {
|
|
1414
1401
|
if (fileId) {
|
|
1415
|
-
return { fileId };
|
|
1402
|
+
return DRIVE_FILE_ID.test(fileId) ? { fileId } : { error: invalidFileIdError(fileId) };
|
|
1416
1403
|
}
|
|
1417
1404
|
if (fileName) {
|
|
1418
|
-
getLogger().debug("[google_drive_get_content] Searching for file by name:", fileName);
|
|
1419
1405
|
const foundId = await findFileByName(accessToken, fileName);
|
|
1420
1406
|
if (!foundId) {
|
|
1421
1407
|
return {
|
|
1422
1408
|
error: `Error: Could not find a file matching "${fileName}". Please check the file name and try again.`
|
|
1423
1409
|
};
|
|
1424
1410
|
}
|
|
1425
|
-
|
|
1426
|
-
return { fileId: foundId };
|
|
1411
|
+
return DRIVE_FILE_ID.test(foundId) ? { fileId: foundId } : { error: invalidFileIdError(foundId) };
|
|
1427
1412
|
}
|
|
1428
1413
|
return { error: "Error: Please provide either a fileId or fileName to get file content." };
|
|
1429
1414
|
}
|
|
1430
1415
|
async function fetchFileMetadata(accessToken, fileId) {
|
|
1431
1416
|
const response = await fetch(
|
|
1432
|
-
`https://www.googleapis.com/drive/v3/files/${fileId}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
|
|
1417
|
+
`https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
|
|
1433
1418
|
{ headers: { Authorization: `Bearer ${accessToken}` } }
|
|
1434
1419
|
);
|
|
1435
1420
|
if (!response.ok) {
|
|
@@ -1447,13 +1432,13 @@ function getContentUrl(fileId, mimeType) {
|
|
|
1447
1432
|
if (GOOGLE_DOCS_EXPORT_TYPES[mimeType]) {
|
|
1448
1433
|
const exportMimeType = GOOGLE_DOCS_EXPORT_TYPES[mimeType];
|
|
1449
1434
|
return {
|
|
1450
|
-
url: `https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
|
|
1435
|
+
url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
|
|
1451
1436
|
isExport: true
|
|
1452
1437
|
};
|
|
1453
1438
|
}
|
|
1454
1439
|
if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/xml") {
|
|
1455
1440
|
return {
|
|
1456
|
-
url: `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media&supportsAllDrives=true`,
|
|
1441
|
+
url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?alt=media&supportsAllDrives=true`,
|
|
1457
1442
|
isExport: false
|
|
1458
1443
|
};
|
|
1459
1444
|
}
|
|
@@ -1470,7 +1455,7 @@ Type: PDF${linkInfo}
|
|
|
1470
1455
|
Note: PDF content cannot be extracted directly in the browser. The user can click the link above to view the PDF in Google Drive.`;
|
|
1471
1456
|
}
|
|
1472
1457
|
if (mimeType.startsWith("image/")) {
|
|
1473
|
-
const directUrl = `https://drive.google.com/uc?export=view&id=${fileId}`;
|
|
1458
|
+
const directUrl = `https://drive.google.com/uc?export=view&id=${encodeURIComponent(fileId)}`;
|
|
1474
1459
|
return `File: ${name}
|
|
1475
1460
|
Type: ${mimeType}${linkInfo}
|
|
1476
1461
|
Direct image URL: ${directUrl}
|
|
@@ -1505,7 +1490,6 @@ Type: ${metadata.mimeType}${isExport ? " (exported as text)" : ""}
|
|
|
1505
1490
|
return header + displayContent + footer;
|
|
1506
1491
|
}
|
|
1507
1492
|
async function getDriveFileContent(accessToken, args) {
|
|
1508
|
-
getLogger().debug("[google_drive_get_content] Starting with:", args);
|
|
1509
1493
|
const fileIdResult = await resolveFileId(accessToken, args.fileId, args.fileName);
|
|
1510
1494
|
if ("error" in fileIdResult) {
|
|
1511
1495
|
return fileIdResult.error;
|
|
@@ -1517,7 +1501,6 @@ async function getDriveFileContent(accessToken, args) {
|
|
|
1517
1501
|
return metadataResult.error;
|
|
1518
1502
|
}
|
|
1519
1503
|
const { metadata } = metadataResult;
|
|
1520
|
-
getLogger().debug("[google_drive_get_content] File metadata:", metadata);
|
|
1521
1504
|
const contentUrlResult = getContentUrl(fileId, metadata.mimeType);
|
|
1522
1505
|
if (!contentUrlResult) {
|
|
1523
1506
|
return formatNonTextFileResponse(fileId, metadata);
|
|
@@ -1554,10 +1537,8 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
|
|
|
1554
1537
|
}
|
|
1555
1538
|
},
|
|
1556
1539
|
executor: async (args) => {
|
|
1557
|
-
getLogger().debug("[google_drive_get_content] Executor called with args:", args);
|
|
1558
1540
|
let token = getAccessToken();
|
|
1559
1541
|
if (!token) {
|
|
1560
|
-
getLogger().debug("[google_drive_get_content] No token, requesting access...");
|
|
1561
1542
|
try {
|
|
1562
1543
|
token = await requestDriveAccess();
|
|
1563
1544
|
} catch {
|
|
@@ -1571,14 +1552,7 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
|
|
|
1571
1552
|
fileId: args.fileId,
|
|
1572
1553
|
fileName: args.fileName
|
|
1573
1554
|
};
|
|
1574
|
-
|
|
1575
|
-
getLogger().debug(
|
|
1576
|
-
"[google_drive_get_content] Result length:",
|
|
1577
|
-
result.length,
|
|
1578
|
-
"First 200 chars:",
|
|
1579
|
-
result.slice(0, 200)
|
|
1580
|
-
);
|
|
1581
|
-
return result;
|
|
1555
|
+
return getDriveFileContent(token, typedArgs);
|
|
1582
1556
|
}
|
|
1583
1557
|
};
|
|
1584
1558
|
}
|
|
@@ -1679,6 +1653,9 @@ function createGoogleDriveCreateFileTool(getAccessToken, requestDriveAccess) {
|
|
|
1679
1653
|
};
|
|
1680
1654
|
}
|
|
1681
1655
|
async function updateDriveFile(accessToken, args) {
|
|
1656
|
+
if (typeof args.fileId !== "string" || !DRIVE_FILE_ID.test(args.fileId)) {
|
|
1657
|
+
return invalidFileIdError(args.fileId);
|
|
1658
|
+
}
|
|
1682
1659
|
const mimeType = (args.mimeType || "text/plain").replace(/[\r\n]/g, "");
|
|
1683
1660
|
if (NATIVE_GOOGLE_MIME_TYPE.test(mimeType)) {
|
|
1684
1661
|
return NATIVE_GOOGLE_MIME_ERROR;
|
|
@@ -2357,22 +2334,17 @@ function notionConnectorError(status, json) {
|
|
|
2357
2334
|
return buildConnectorErrorResult(
|
|
2358
2335
|
"scope_not_covered",
|
|
2359
2336
|
NOTION_PROVIDER,
|
|
2360
|
-
readString(json, "connect_url"),
|
|
2361
2337
|
Array.isArray(missingScopes) ? { missingScopes } : void 0
|
|
2362
2338
|
);
|
|
2363
2339
|
}
|
|
2364
2340
|
case "insufficient_scope":
|
|
2365
|
-
return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER,
|
|
2341
|
+
return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER, {
|
|
2366
2342
|
required: readString(json, "required")
|
|
2367
2343
|
});
|
|
2368
2344
|
case "upstream_unavailable":
|
|
2369
2345
|
return buildConnectorErrorResult("upstream_unavailable", NOTION_PROVIDER);
|
|
2370
2346
|
default:
|
|
2371
|
-
return buildConnectorErrorResult(
|
|
2372
|
-
"connector_not_connected",
|
|
2373
|
-
NOTION_PROVIDER,
|
|
2374
|
-
readString(json, "connect_url")
|
|
2375
|
-
);
|
|
2347
|
+
return buildConnectorErrorResult("connector_not_connected", NOTION_PROVIDER);
|
|
2376
2348
|
}
|
|
2377
2349
|
}
|
|
2378
2350
|
function proxyRunner(callMcp) {
|
|
@@ -2888,6 +2860,34 @@ async function callNotionMCPTool(accessToken, toolName, args) {
|
|
|
2888
2860
|
return callMCPTool(accessToken, toolName, args);
|
|
2889
2861
|
}
|
|
2890
2862
|
|
|
2863
|
+
// src/lib/logger.ts
|
|
2864
|
+
var consoleLogger = {
|
|
2865
|
+
debug: console.log.bind(console),
|
|
2866
|
+
info: console.info.bind(console),
|
|
2867
|
+
warn: console.warn.bind(console),
|
|
2868
|
+
error: console.error.bind(console)
|
|
2869
|
+
};
|
|
2870
|
+
var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
|
|
2871
|
+
var loggerGlobal = globalThis;
|
|
2872
|
+
var fallbackLoggerState = { logger: consoleLogger };
|
|
2873
|
+
var fallbackWarned = false;
|
|
2874
|
+
function getLoggerState() {
|
|
2875
|
+
try {
|
|
2876
|
+
return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
|
|
2877
|
+
} catch {
|
|
2878
|
+
if (!fallbackWarned) {
|
|
2879
|
+
fallbackWarned = true;
|
|
2880
|
+
fallbackLoggerState.logger.warn(
|
|
2881
|
+
"@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
|
|
2882
|
+
);
|
|
2883
|
+
}
|
|
2884
|
+
return fallbackLoggerState;
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
function getLogger() {
|
|
2888
|
+
return getLoggerState().logger;
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
2891
|
// src/tools/github.ts
|
|
2892
2892
|
var GITHUB_API = "https://api.github.com";
|
|
2893
2893
|
var FETCH_TIMEOUT_MS = 3e4;
|
|
@@ -3131,13 +3131,13 @@ function maybeConnectorError(status) {
|
|
|
3131
3131
|
function connectorMintErrorToToolResult(err, provider) {
|
|
3132
3132
|
switch (err.code) {
|
|
3133
3133
|
case "connector_not_connected":
|
|
3134
|
-
return buildConnectorErrorResult("connector_not_connected", err.provider
|
|
3134
|
+
return buildConnectorErrorResult("connector_not_connected", err.provider);
|
|
3135
3135
|
case "scope_not_covered":
|
|
3136
|
-
return buildConnectorErrorResult("scope_not_covered", err.provider,
|
|
3136
|
+
return buildConnectorErrorResult("scope_not_covered", err.provider, {
|
|
3137
3137
|
missingScopes: err.missingScopes
|
|
3138
3138
|
});
|
|
3139
3139
|
case "insufficient_scope":
|
|
3140
|
-
return buildConnectorErrorResult("insufficient_scope", provider,
|
|
3140
|
+
return buildConnectorErrorResult("insufficient_scope", provider, {
|
|
3141
3141
|
required: err.required
|
|
3142
3142
|
});
|
|
3143
3143
|
case "upstream_unavailable":
|
|
@@ -3880,7 +3880,7 @@ function maybeConnectorError4(status, body) {
|
|
|
3880
3880
|
return buildConnectorErrorResult("connector_not_connected", SLACK_PROVIDER);
|
|
3881
3881
|
}
|
|
3882
3882
|
if (body && body.ok === false && body.error === "missing_scope") {
|
|
3883
|
-
return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER,
|
|
3883
|
+
return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER, {
|
|
3884
3884
|
required: body.needed
|
|
3885
3885
|
});
|
|
3886
3886
|
}
|
package/dist/tools/index.d.mts
CHANGED
|
@@ -1015,12 +1015,12 @@ type ConnectorMintResult = {
|
|
|
1015
1015
|
type ConnectorMintError = {
|
|
1016
1016
|
code: "connector_not_connected";
|
|
1017
1017
|
provider: string;
|
|
1018
|
-
connectUrl
|
|
1018
|
+
connectUrl?: string;
|
|
1019
1019
|
} | {
|
|
1020
1020
|
code: "scope_not_covered";
|
|
1021
1021
|
provider: string;
|
|
1022
1022
|
missingScopes: string[];
|
|
1023
|
-
connectUrl
|
|
1023
|
+
connectUrl?: string;
|
|
1024
1024
|
} | {
|
|
1025
1025
|
code: "insufficient_scope";
|
|
1026
1026
|
required: string;
|
|
@@ -1106,11 +1106,10 @@ interface ConnectorErrorExtras {
|
|
|
1106
1106
|
*
|
|
1107
1107
|
* @param code One of the recognized {@link ConnectorErrorCode} values.
|
|
1108
1108
|
* @param provider Logical provider name (`"gmail"`, `"gdrive"`, etc.).
|
|
1109
|
-
* @param connectUrl Optional connect URL surfaced to the user via the LLM reply.
|
|
1110
1109
|
* @param extras Optional `missingScopes` / `required` fields lifted by the
|
|
1111
1110
|
* runtime parser into `ToolErrorInfo`.
|
|
1112
1111
|
*/
|
|
1113
|
-
declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string,
|
|
1112
|
+
declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string, extras?: ConnectorErrorExtras): string;
|
|
1114
1113
|
|
|
1115
1114
|
/**
|
|
1116
1115
|
* Gmail tool factory for the chat system.
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1015,12 +1015,12 @@ type ConnectorMintResult = {
|
|
|
1015
1015
|
type ConnectorMintError = {
|
|
1016
1016
|
code: "connector_not_connected";
|
|
1017
1017
|
provider: string;
|
|
1018
|
-
connectUrl
|
|
1018
|
+
connectUrl?: string;
|
|
1019
1019
|
} | {
|
|
1020
1020
|
code: "scope_not_covered";
|
|
1021
1021
|
provider: string;
|
|
1022
1022
|
missingScopes: string[];
|
|
1023
|
-
connectUrl
|
|
1023
|
+
connectUrl?: string;
|
|
1024
1024
|
} | {
|
|
1025
1025
|
code: "insufficient_scope";
|
|
1026
1026
|
required: string;
|
|
@@ -1106,11 +1106,10 @@ interface ConnectorErrorExtras {
|
|
|
1106
1106
|
*
|
|
1107
1107
|
* @param code One of the recognized {@link ConnectorErrorCode} values.
|
|
1108
1108
|
* @param provider Logical provider name (`"gmail"`, `"gdrive"`, etc.).
|
|
1109
|
-
* @param connectUrl Optional connect URL surfaced to the user via the LLM reply.
|
|
1110
1109
|
* @param extras Optional `missingScopes` / `required` fields lifted by the
|
|
1111
1110
|
* runtime parser into `ToolErrorInfo`.
|
|
1112
1111
|
*/
|
|
1113
|
-
declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string,
|
|
1112
|
+
declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string, extras?: ConnectorErrorExtras): string;
|
|
1114
1113
|
|
|
1115
1114
|
/**
|
|
1116
1115
|
* Gmail tool factory for the chat system.
|
package/dist/tools/index.mjs
CHANGED
|
@@ -121,12 +121,16 @@ function buildUpdateEventBody(args) {
|
|
|
121
121
|
}
|
|
122
122
|
return eventBody;
|
|
123
123
|
}
|
|
124
|
+
var CALENDAR_EVENT_ID = /^[A-Za-z0-9_]+$/;
|
|
124
125
|
async function updateCalendarEvent(accessToken, args) {
|
|
125
126
|
const { eventId } = args;
|
|
127
|
+
if (typeof eventId !== "string" || !CALENDAR_EVENT_ID.test(eventId)) {
|
|
128
|
+
return `Error: Invalid event ID: ${String(eventId)}`;
|
|
129
|
+
}
|
|
126
130
|
const eventBody = buildUpdateEventBody(args);
|
|
127
131
|
try {
|
|
128
132
|
const response = await fetch(
|
|
129
|
-
`https://www.googleapis.com/calendar/v3/calendars/primary/events/${eventId}`,
|
|
133
|
+
`https://www.googleapis.com/calendar/v3/calendars/primary/events/${encodeURIComponent(eventId)}`,
|
|
130
134
|
{
|
|
131
135
|
method: "PATCH",
|
|
132
136
|
headers: {
|
|
@@ -995,55 +999,40 @@ function createWeatherTool(options, weatherOptions) {
|
|
|
995
999
|
|
|
996
1000
|
// src/lib/connectors/errors.ts
|
|
997
1001
|
var CONNECTOR_ERROR_MARKER = "__anuma_connector_error_v1";
|
|
998
|
-
function buildConnectorErrorResult(code, provider,
|
|
1002
|
+
function buildConnectorErrorResult(code, provider, extras) {
|
|
999
1003
|
const payload = {
|
|
1000
1004
|
__anuma_connector_error_v1: true,
|
|
1001
1005
|
code,
|
|
1002
1006
|
provider,
|
|
1003
|
-
connect_url: connectUrl,
|
|
1004
1007
|
missing_scopes: extras?.missingScopes,
|
|
1005
1008
|
required: extras?.required
|
|
1006
1009
|
};
|
|
1007
1010
|
return JSON.stringify(payload);
|
|
1008
1011
|
}
|
|
1009
1012
|
|
|
1010
|
-
// src/lib/logger.ts
|
|
1011
|
-
var consoleLogger = {
|
|
1012
|
-
debug: console.log.bind(console),
|
|
1013
|
-
info: console.info.bind(console),
|
|
1014
|
-
warn: console.warn.bind(console),
|
|
1015
|
-
error: console.error.bind(console)
|
|
1016
|
-
};
|
|
1017
|
-
var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
|
|
1018
|
-
var loggerGlobal = globalThis;
|
|
1019
|
-
var fallbackLoggerState = { logger: consoleLogger };
|
|
1020
|
-
var fallbackWarned = false;
|
|
1021
|
-
function getLoggerState() {
|
|
1022
|
-
try {
|
|
1023
|
-
return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
|
|
1024
|
-
} catch {
|
|
1025
|
-
if (!fallbackWarned) {
|
|
1026
|
-
fallbackWarned = true;
|
|
1027
|
-
fallbackLoggerState.logger.warn(
|
|
1028
|
-
"@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
|
|
1029
|
-
);
|
|
1030
|
-
}
|
|
1031
|
-
return fallbackLoggerState;
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
function getLogger() {
|
|
1035
|
-
return getLoggerState().logger;
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
1013
|
// src/tools/googleDrive.ts
|
|
1039
1014
|
var DRIVE_PROVIDER = "gdrive";
|
|
1015
|
+
var DRIVE_FILE_ID = /^[A-Za-z0-9_-]+$/;
|
|
1016
|
+
var DRIVE_MIME_TYPE = /^[\w.+-]+\/[\w.+-]+$/;
|
|
1017
|
+
function invalidFileIdError(fileId) {
|
|
1018
|
+
return `Error: Invalid file ID: ${String(fileId)}`;
|
|
1019
|
+
}
|
|
1020
|
+
function escapeDriveQueryValue(value) {
|
|
1021
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
1022
|
+
}
|
|
1023
|
+
function withMimeTypeFilter(driveQuery, mimeType) {
|
|
1024
|
+
if (!mimeType) return driveQuery;
|
|
1025
|
+
if (!DRIVE_MIME_TYPE.test(mimeType)) return { error: `Error: Invalid mimeType: ${mimeType}` };
|
|
1026
|
+
return `${driveQuery} and mimeType = '${escapeDriveQueryValue(mimeType)}'`;
|
|
1027
|
+
}
|
|
1040
1028
|
async function searchDriveFiles(accessToken, args) {
|
|
1041
1029
|
const { query, maxResults = 10, mimeType } = args;
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1030
|
+
const filtered = withMimeTypeFilter(
|
|
1031
|
+
`fullText contains '${escapeDriveQueryValue(query)}'`,
|
|
1032
|
+
mimeType
|
|
1033
|
+
);
|
|
1034
|
+
if (typeof filtered !== "string") return filtered.error;
|
|
1035
|
+
const driveQuery = `${filtered} and trashed = false`;
|
|
1047
1036
|
const params = new URLSearchParams({
|
|
1048
1037
|
q: driveQuery,
|
|
1049
1038
|
pageSize: String(maxResults),
|
|
@@ -1136,10 +1125,8 @@ function createGoogleDriveSearchTool(getAccessToken, requestDriveAccess) {
|
|
|
1136
1125
|
}
|
|
1137
1126
|
async function listRecentDriveFiles(accessToken, args) {
|
|
1138
1127
|
const { maxResults = 10, mimeType } = args;
|
|
1139
|
-
|
|
1140
|
-
if (
|
|
1141
|
-
driveQuery += ` and mimeType = '${mimeType}'`;
|
|
1142
|
-
}
|
|
1128
|
+
const driveQuery = withMimeTypeFilter("trashed = false", mimeType);
|
|
1129
|
+
if (typeof driveQuery !== "string") return driveQuery.error;
|
|
1143
1130
|
const params = new URLSearchParams({
|
|
1144
1131
|
q: driveQuery,
|
|
1145
1132
|
pageSize: String(maxResults),
|
|
@@ -1226,7 +1213,7 @@ function createGoogleDriveListRecentTool(getAccessToken, requestDriveAccess) {
|
|
|
1226
1213
|
};
|
|
1227
1214
|
}
|
|
1228
1215
|
async function findFileByName(accessToken, fileName) {
|
|
1229
|
-
const driveQuery = `name contains '${fileName
|
|
1216
|
+
const driveQuery = `name contains '${escapeDriveQueryValue(fileName)}' and trashed = false`;
|
|
1230
1217
|
const params = new URLSearchParams({
|
|
1231
1218
|
q: driveQuery,
|
|
1232
1219
|
pageSize: "1",
|
|
@@ -1256,24 +1243,22 @@ var GOOGLE_DOCS_EXPORT_TYPES = {
|
|
|
1256
1243
|
var MAX_CONTENT_LENGTH = 5e4;
|
|
1257
1244
|
async function resolveFileId(accessToken, fileId, fileName) {
|
|
1258
1245
|
if (fileId) {
|
|
1259
|
-
return { fileId };
|
|
1246
|
+
return DRIVE_FILE_ID.test(fileId) ? { fileId } : { error: invalidFileIdError(fileId) };
|
|
1260
1247
|
}
|
|
1261
1248
|
if (fileName) {
|
|
1262
|
-
getLogger().debug("[google_drive_get_content] Searching for file by name:", fileName);
|
|
1263
1249
|
const foundId = await findFileByName(accessToken, fileName);
|
|
1264
1250
|
if (!foundId) {
|
|
1265
1251
|
return {
|
|
1266
1252
|
error: `Error: Could not find a file matching "${fileName}". Please check the file name and try again.`
|
|
1267
1253
|
};
|
|
1268
1254
|
}
|
|
1269
|
-
|
|
1270
|
-
return { fileId: foundId };
|
|
1255
|
+
return DRIVE_FILE_ID.test(foundId) ? { fileId: foundId } : { error: invalidFileIdError(foundId) };
|
|
1271
1256
|
}
|
|
1272
1257
|
return { error: "Error: Please provide either a fileId or fileName to get file content." };
|
|
1273
1258
|
}
|
|
1274
1259
|
async function fetchFileMetadata(accessToken, fileId) {
|
|
1275
1260
|
const response = await fetch(
|
|
1276
|
-
`https://www.googleapis.com/drive/v3/files/${fileId}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
|
|
1261
|
+
`https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
|
|
1277
1262
|
{ headers: { Authorization: `Bearer ${accessToken}` } }
|
|
1278
1263
|
);
|
|
1279
1264
|
if (!response.ok) {
|
|
@@ -1291,13 +1276,13 @@ function getContentUrl(fileId, mimeType) {
|
|
|
1291
1276
|
if (GOOGLE_DOCS_EXPORT_TYPES[mimeType]) {
|
|
1292
1277
|
const exportMimeType = GOOGLE_DOCS_EXPORT_TYPES[mimeType];
|
|
1293
1278
|
return {
|
|
1294
|
-
url: `https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
|
|
1279
|
+
url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
|
|
1295
1280
|
isExport: true
|
|
1296
1281
|
};
|
|
1297
1282
|
}
|
|
1298
1283
|
if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/xml") {
|
|
1299
1284
|
return {
|
|
1300
|
-
url: `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media&supportsAllDrives=true`,
|
|
1285
|
+
url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?alt=media&supportsAllDrives=true`,
|
|
1301
1286
|
isExport: false
|
|
1302
1287
|
};
|
|
1303
1288
|
}
|
|
@@ -1314,7 +1299,7 @@ Type: PDF${linkInfo}
|
|
|
1314
1299
|
Note: PDF content cannot be extracted directly in the browser. The user can click the link above to view the PDF in Google Drive.`;
|
|
1315
1300
|
}
|
|
1316
1301
|
if (mimeType.startsWith("image/")) {
|
|
1317
|
-
const directUrl = `https://drive.google.com/uc?export=view&id=${fileId}`;
|
|
1302
|
+
const directUrl = `https://drive.google.com/uc?export=view&id=${encodeURIComponent(fileId)}`;
|
|
1318
1303
|
return `File: ${name}
|
|
1319
1304
|
Type: ${mimeType}${linkInfo}
|
|
1320
1305
|
Direct image URL: ${directUrl}
|
|
@@ -1349,7 +1334,6 @@ Type: ${metadata.mimeType}${isExport ? " (exported as text)" : ""}
|
|
|
1349
1334
|
return header + displayContent + footer;
|
|
1350
1335
|
}
|
|
1351
1336
|
async function getDriveFileContent(accessToken, args) {
|
|
1352
|
-
getLogger().debug("[google_drive_get_content] Starting with:", args);
|
|
1353
1337
|
const fileIdResult = await resolveFileId(accessToken, args.fileId, args.fileName);
|
|
1354
1338
|
if ("error" in fileIdResult) {
|
|
1355
1339
|
return fileIdResult.error;
|
|
@@ -1361,7 +1345,6 @@ async function getDriveFileContent(accessToken, args) {
|
|
|
1361
1345
|
return metadataResult.error;
|
|
1362
1346
|
}
|
|
1363
1347
|
const { metadata } = metadataResult;
|
|
1364
|
-
getLogger().debug("[google_drive_get_content] File metadata:", metadata);
|
|
1365
1348
|
const contentUrlResult = getContentUrl(fileId, metadata.mimeType);
|
|
1366
1349
|
if (!contentUrlResult) {
|
|
1367
1350
|
return formatNonTextFileResponse(fileId, metadata);
|
|
@@ -1398,10 +1381,8 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
|
|
|
1398
1381
|
}
|
|
1399
1382
|
},
|
|
1400
1383
|
executor: async (args) => {
|
|
1401
|
-
getLogger().debug("[google_drive_get_content] Executor called with args:", args);
|
|
1402
1384
|
let token = getAccessToken();
|
|
1403
1385
|
if (!token) {
|
|
1404
|
-
getLogger().debug("[google_drive_get_content] No token, requesting access...");
|
|
1405
1386
|
try {
|
|
1406
1387
|
token = await requestDriveAccess();
|
|
1407
1388
|
} catch {
|
|
@@ -1415,14 +1396,7 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
|
|
|
1415
1396
|
fileId: args.fileId,
|
|
1416
1397
|
fileName: args.fileName
|
|
1417
1398
|
};
|
|
1418
|
-
|
|
1419
|
-
getLogger().debug(
|
|
1420
|
-
"[google_drive_get_content] Result length:",
|
|
1421
|
-
result.length,
|
|
1422
|
-
"First 200 chars:",
|
|
1423
|
-
result.slice(0, 200)
|
|
1424
|
-
);
|
|
1425
|
-
return result;
|
|
1399
|
+
return getDriveFileContent(token, typedArgs);
|
|
1426
1400
|
}
|
|
1427
1401
|
};
|
|
1428
1402
|
}
|
|
@@ -1523,6 +1497,9 @@ function createGoogleDriveCreateFileTool(getAccessToken, requestDriveAccess) {
|
|
|
1523
1497
|
};
|
|
1524
1498
|
}
|
|
1525
1499
|
async function updateDriveFile(accessToken, args) {
|
|
1500
|
+
if (typeof args.fileId !== "string" || !DRIVE_FILE_ID.test(args.fileId)) {
|
|
1501
|
+
return invalidFileIdError(args.fileId);
|
|
1502
|
+
}
|
|
1526
1503
|
const mimeType = (args.mimeType || "text/plain").replace(/[\r\n]/g, "");
|
|
1527
1504
|
if (NATIVE_GOOGLE_MIME_TYPE.test(mimeType)) {
|
|
1528
1505
|
return NATIVE_GOOGLE_MIME_ERROR;
|
|
@@ -2201,22 +2178,17 @@ function notionConnectorError(status, json) {
|
|
|
2201
2178
|
return buildConnectorErrorResult(
|
|
2202
2179
|
"scope_not_covered",
|
|
2203
2180
|
NOTION_PROVIDER,
|
|
2204
|
-
readString(json, "connect_url"),
|
|
2205
2181
|
Array.isArray(missingScopes) ? { missingScopes } : void 0
|
|
2206
2182
|
);
|
|
2207
2183
|
}
|
|
2208
2184
|
case "insufficient_scope":
|
|
2209
|
-
return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER,
|
|
2185
|
+
return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER, {
|
|
2210
2186
|
required: readString(json, "required")
|
|
2211
2187
|
});
|
|
2212
2188
|
case "upstream_unavailable":
|
|
2213
2189
|
return buildConnectorErrorResult("upstream_unavailable", NOTION_PROVIDER);
|
|
2214
2190
|
default:
|
|
2215
|
-
return buildConnectorErrorResult(
|
|
2216
|
-
"connector_not_connected",
|
|
2217
|
-
NOTION_PROVIDER,
|
|
2218
|
-
readString(json, "connect_url")
|
|
2219
|
-
);
|
|
2191
|
+
return buildConnectorErrorResult("connector_not_connected", NOTION_PROVIDER);
|
|
2220
2192
|
}
|
|
2221
2193
|
}
|
|
2222
2194
|
function proxyRunner(callMcp) {
|
|
@@ -2732,6 +2704,34 @@ async function callNotionMCPTool(accessToken, toolName, args) {
|
|
|
2732
2704
|
return callMCPTool(accessToken, toolName, args);
|
|
2733
2705
|
}
|
|
2734
2706
|
|
|
2707
|
+
// src/lib/logger.ts
|
|
2708
|
+
var consoleLogger = {
|
|
2709
|
+
debug: console.log.bind(console),
|
|
2710
|
+
info: console.info.bind(console),
|
|
2711
|
+
warn: console.warn.bind(console),
|
|
2712
|
+
error: console.error.bind(console)
|
|
2713
|
+
};
|
|
2714
|
+
var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
|
|
2715
|
+
var loggerGlobal = globalThis;
|
|
2716
|
+
var fallbackLoggerState = { logger: consoleLogger };
|
|
2717
|
+
var fallbackWarned = false;
|
|
2718
|
+
function getLoggerState() {
|
|
2719
|
+
try {
|
|
2720
|
+
return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
|
|
2721
|
+
} catch {
|
|
2722
|
+
if (!fallbackWarned) {
|
|
2723
|
+
fallbackWarned = true;
|
|
2724
|
+
fallbackLoggerState.logger.warn(
|
|
2725
|
+
"@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
|
|
2726
|
+
);
|
|
2727
|
+
}
|
|
2728
|
+
return fallbackLoggerState;
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
function getLogger() {
|
|
2732
|
+
return getLoggerState().logger;
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
2735
|
// src/tools/github.ts
|
|
2736
2736
|
var GITHUB_API = "https://api.github.com";
|
|
2737
2737
|
var FETCH_TIMEOUT_MS = 3e4;
|
|
@@ -2975,13 +2975,13 @@ function maybeConnectorError(status) {
|
|
|
2975
2975
|
function connectorMintErrorToToolResult(err, provider) {
|
|
2976
2976
|
switch (err.code) {
|
|
2977
2977
|
case "connector_not_connected":
|
|
2978
|
-
return buildConnectorErrorResult("connector_not_connected", err.provider
|
|
2978
|
+
return buildConnectorErrorResult("connector_not_connected", err.provider);
|
|
2979
2979
|
case "scope_not_covered":
|
|
2980
|
-
return buildConnectorErrorResult("scope_not_covered", err.provider,
|
|
2980
|
+
return buildConnectorErrorResult("scope_not_covered", err.provider, {
|
|
2981
2981
|
missingScopes: err.missingScopes
|
|
2982
2982
|
});
|
|
2983
2983
|
case "insufficient_scope":
|
|
2984
|
-
return buildConnectorErrorResult("insufficient_scope", provider,
|
|
2984
|
+
return buildConnectorErrorResult("insufficient_scope", provider, {
|
|
2985
2985
|
required: err.required
|
|
2986
2986
|
});
|
|
2987
2987
|
case "upstream_unavailable":
|
|
@@ -3724,7 +3724,7 @@ function maybeConnectorError4(status, body) {
|
|
|
3724
3724
|
return buildConnectorErrorResult("connector_not_connected", SLACK_PROVIDER);
|
|
3725
3725
|
}
|
|
3726
3726
|
if (body && body.ok === false && body.error === "missing_scope") {
|
|
3727
|
-
return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER,
|
|
3727
|
+
return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER, {
|
|
3728
3728
|
required: body.needed
|
|
3729
3729
|
});
|
|
3730
3730
|
}
|