@agentforge/tools 0.16.70 → 0.16.72
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.cjs +218 -209
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -37
- package/dist/index.d.ts +16 -37
- package/dist/index.js +218 -209
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -815,7 +815,7 @@ function getDefaultSlackClient() {
|
|
|
815
815
|
}
|
|
816
816
|
};
|
|
817
817
|
}
|
|
818
|
-
function createSendSlackMessageTool(getSlackClient,
|
|
818
|
+
function createSendSlackMessageTool(getSlackClient, logger19) {
|
|
819
819
|
return core.toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(core.ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
|
|
820
820
|
"Use this for general team communication. For notifications with @mentions, consider using notify-slack instead. Use get-slack-channels first if you need to find the right channel."
|
|
821
821
|
).suggests(["get-slack-channels"]).schema(
|
|
@@ -824,7 +824,7 @@ function createSendSlackMessageTool(getSlackClient, logger18) {
|
|
|
824
824
|
message: zod.z.string().describe("Message content to send")
|
|
825
825
|
})
|
|
826
826
|
).implementSafe(async ({ channel, message }) => {
|
|
827
|
-
|
|
827
|
+
logger19.info("send-slack-message called", { channel, messageLength: message.length });
|
|
828
828
|
try {
|
|
829
829
|
const { client: slack, config } = getSlackClient();
|
|
830
830
|
const result = await slack.chat.postMessage({
|
|
@@ -833,7 +833,7 @@ function createSendSlackMessageTool(getSlackClient, logger18) {
|
|
|
833
833
|
username: config.botName,
|
|
834
834
|
icon_emoji: config.botIcon
|
|
835
835
|
});
|
|
836
|
-
|
|
836
|
+
logger19.info("send-slack-message result", {
|
|
837
837
|
...result.channel ? { channel: result.channel } : {},
|
|
838
838
|
...result.ts ? { timestamp: result.ts } : {},
|
|
839
839
|
messageLength: message.length,
|
|
@@ -846,7 +846,7 @@ function createSendSlackMessageTool(getSlackClient, logger18) {
|
|
|
846
846
|
message_id: result.ts
|
|
847
847
|
};
|
|
848
848
|
} catch (error) {
|
|
849
|
-
|
|
849
|
+
logger19.error("send-slack-message failed", {
|
|
850
850
|
channel,
|
|
851
851
|
error: error.message,
|
|
852
852
|
data: error.data
|
|
@@ -855,7 +855,7 @@ function createSendSlackMessageTool(getSlackClient, logger18) {
|
|
|
855
855
|
}
|
|
856
856
|
}).build();
|
|
857
857
|
}
|
|
858
|
-
function createNotifySlackTool(getSlackClient,
|
|
858
|
+
function createNotifySlackTool(getSlackClient, logger19) {
|
|
859
859
|
return core.toolBuilder().name("notify-slack").description("Send a notification to a Slack channel with optional @mentions for urgent alerts").category(core.ToolCategory.WEB).tags(["slack", "notification", "alert"]).usageNotes(
|
|
860
860
|
"Use this for urgent notifications that require @mentions. For general messages without mentions, use send-slack-message instead."
|
|
861
861
|
).suggests(["get-slack-channels"]).schema(
|
|
@@ -865,7 +865,7 @@ function createNotifySlackTool(getSlackClient, logger18) {
|
|
|
865
865
|
mentions: zod.z.array(zod.z.string()).optional().describe("List of usernames to mention (without @)")
|
|
866
866
|
})
|
|
867
867
|
).implementSafe(async ({ channel, message, mentions = [] }) => {
|
|
868
|
-
|
|
868
|
+
logger19.info("notify-slack called", {
|
|
869
869
|
channel,
|
|
870
870
|
messageLength: message.length,
|
|
871
871
|
mentionCount: mentions.length
|
|
@@ -879,7 +879,7 @@ function createNotifySlackTool(getSlackClient, logger18) {
|
|
|
879
879
|
username: config.botName,
|
|
880
880
|
icon_emoji: config.botIcon
|
|
881
881
|
});
|
|
882
|
-
|
|
882
|
+
logger19.info("notify-slack result", {
|
|
883
883
|
...result.channel ? { channel: result.channel } : {},
|
|
884
884
|
...result.ts ? { timestamp: result.ts } : {},
|
|
885
885
|
mentions: mentions.length
|
|
@@ -893,7 +893,7 @@ function createNotifySlackTool(getSlackClient, logger18) {
|
|
|
893
893
|
};
|
|
894
894
|
}).build();
|
|
895
895
|
}
|
|
896
|
-
function createGetSlackChannelsTool(getSlackClient,
|
|
896
|
+
function createGetSlackChannelsTool(getSlackClient, logger19) {
|
|
897
897
|
return core.toolBuilder().name("get-slack-channels").description("Get a list of available Slack channels to find the right channel for messaging").category(core.ToolCategory.WEB).tags(["slack", "channels", "list"]).usageNotes(
|
|
898
898
|
"Use this first to discover available channels before sending messages. Helps ensure you are sending to the correct channel."
|
|
899
899
|
).follows(["send-slack-message", "notify-slack"]).schema(
|
|
@@ -901,7 +901,7 @@ function createGetSlackChannelsTool(getSlackClient, logger18) {
|
|
|
901
901
|
include_private: zod.z.boolean().optional().describe("Include private channels (default: false)")
|
|
902
902
|
})
|
|
903
903
|
).implementSafe(async ({ include_private = false }) => {
|
|
904
|
-
|
|
904
|
+
logger19.info("get-slack-channels called", { include_private });
|
|
905
905
|
const { client: slack } = getSlackClient();
|
|
906
906
|
const publicChannels = await slack.conversations.list({
|
|
907
907
|
types: "public_channel",
|
|
@@ -915,7 +915,7 @@ function createGetSlackChannelsTool(getSlackClient, logger18) {
|
|
|
915
915
|
});
|
|
916
916
|
allChannels = [...allChannels, ...privateChannels.channels || []];
|
|
917
917
|
}
|
|
918
|
-
|
|
918
|
+
logger19.info("get-slack-channels result", {
|
|
919
919
|
channelCount: allChannels.length,
|
|
920
920
|
includePrivate: include_private
|
|
921
921
|
});
|
|
@@ -930,7 +930,7 @@ function createGetSlackChannelsTool(getSlackClient, logger18) {
|
|
|
930
930
|
};
|
|
931
931
|
}).build();
|
|
932
932
|
}
|
|
933
|
-
function createGetSlackMessagesTool(getSlackClient,
|
|
933
|
+
function createGetSlackMessagesTool(getSlackClient, logger19) {
|
|
934
934
|
return core.toolBuilder().name("get-slack-messages").description("Retrieve message history from a Slack channel to read recent conversations").category(core.ToolCategory.WEB).tags(["slack", "messages", "history", "read"]).usageNotes(
|
|
935
935
|
"Use this to read recent messages from a channel. Use get-slack-channels first if you need to find the channel ID. Returns messages in reverse chronological order (newest first)."
|
|
936
936
|
).suggests(["get-slack-channels"]).schema(
|
|
@@ -939,7 +939,7 @@ function createGetSlackMessagesTool(getSlackClient, logger18) {
|
|
|
939
939
|
limit: zod.z.number().int().min(1).max(100).optional().describe("Number of messages to retrieve (default: 20, max: 100)")
|
|
940
940
|
})
|
|
941
941
|
).implementSafe(async ({ channel, limit = 20 }) => {
|
|
942
|
-
|
|
942
|
+
logger19.info("get-slack-messages called", { channel, limit });
|
|
943
943
|
try {
|
|
944
944
|
const { client: slack } = getSlackClient();
|
|
945
945
|
let channelId = channel;
|
|
@@ -950,7 +950,7 @@ function createGetSlackMessagesTool(getSlackClient, logger18) {
|
|
|
950
950
|
});
|
|
951
951
|
const found = channels.channels?.find((c) => c.name === channel);
|
|
952
952
|
if (!found) {
|
|
953
|
-
|
|
953
|
+
logger19.error("get-slack-messages: channel not found", { channel });
|
|
954
954
|
throw new Error(
|
|
955
955
|
`Channel '${channel}' not found. Use get-slack-channels to see available channels.`
|
|
956
956
|
);
|
|
@@ -962,7 +962,7 @@ function createGetSlackMessagesTool(getSlackClient, logger18) {
|
|
|
962
962
|
limit: Math.min(limit, 100)
|
|
963
963
|
// Cap at 100 for performance
|
|
964
964
|
});
|
|
965
|
-
|
|
965
|
+
logger19.info("get-slack-messages result", {
|
|
966
966
|
channel: channelId,
|
|
967
967
|
messageCount: result.messages?.length || 0,
|
|
968
968
|
limit
|
|
@@ -980,7 +980,7 @@ function createGetSlackMessagesTool(getSlackClient, logger18) {
|
|
|
980
980
|
})) || []
|
|
981
981
|
};
|
|
982
982
|
} catch (error) {
|
|
983
|
-
|
|
983
|
+
logger19.error("get-slack-messages failed", {
|
|
984
984
|
channel,
|
|
985
985
|
error: error.message,
|
|
986
986
|
data: error.data
|
|
@@ -1061,12 +1061,12 @@ function getAuthHeader() {
|
|
|
1061
1061
|
const auth2 = Buffer.from(`${ATLASSIAN_EMAIL}:${ATLASSIAN_API_KEY}`).toString("base64");
|
|
1062
1062
|
return `Basic ${auth2}`;
|
|
1063
1063
|
}
|
|
1064
|
-
function createSearchConfluenceTool(getAuth, getAuthHeader2,
|
|
1064
|
+
function createSearchConfluenceTool(getAuth, getAuthHeader2, logger19) {
|
|
1065
1065
|
return core.toolBuilder().name("search-confluence").description("Search for pages in Confluence using keywords or CQL (Confluence Query Language). Returns matching pages with titles, IDs, and excerpts.").category(core.ToolCategory.WEB).tag("confluence").tag("search").tag("knowledge-base").usageNotes("Use this to find relevant documentation, policies, or information in Confluence. You can search by keywords or use CQL for advanced queries (e.g., 'space=AI AND type=page'). Use get-confluence-page to retrieve full content of specific pages.").suggests(["get-confluence-page"]).schema(zod.z.object({
|
|
1066
1066
|
query: zod.z.string().describe("Search query or CQL expression (e.g., 'payment processing' or 'space=BL3 AND title~payment')"),
|
|
1067
1067
|
limit: zod.z.number().optional().describe("Maximum number of results to return (default: 10, max: 25)")
|
|
1068
1068
|
})).implement(async ({ query, limit = 10 }) => {
|
|
1069
|
-
|
|
1069
|
+
logger19.info("search-confluence called", { query, limit });
|
|
1070
1070
|
try {
|
|
1071
1071
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1072
1072
|
const response = await axios16__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/search`, {
|
|
@@ -1091,13 +1091,13 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1091
1091
|
lastModified: page.version?.when || ""
|
|
1092
1092
|
}));
|
|
1093
1093
|
if (results.length === 0) {
|
|
1094
|
-
|
|
1094
|
+
logger19.warn("search-confluence returned NO RESULTS - this is a valid outcome, agent should not retry", {
|
|
1095
1095
|
query,
|
|
1096
1096
|
limit,
|
|
1097
1097
|
totalSize: response.data.totalSize
|
|
1098
1098
|
});
|
|
1099
1099
|
} else {
|
|
1100
|
-
|
|
1100
|
+
logger19.info("search-confluence result", {
|
|
1101
1101
|
query,
|
|
1102
1102
|
resultCount: results.length,
|
|
1103
1103
|
totalSize: response.data.totalSize,
|
|
@@ -1112,7 +1112,7 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1112
1112
|
results
|
|
1113
1113
|
});
|
|
1114
1114
|
} catch (error) {
|
|
1115
|
-
|
|
1115
|
+
logger19.error("search-confluence error", {
|
|
1116
1116
|
query,
|
|
1117
1117
|
error: error.response?.data?.message || error.message,
|
|
1118
1118
|
status: error.response?.status
|
|
@@ -1124,11 +1124,11 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1124
1124
|
}
|
|
1125
1125
|
}).build();
|
|
1126
1126
|
}
|
|
1127
|
-
function createGetConfluencePageTool(getAuth, getAuthHeader2,
|
|
1127
|
+
function createGetConfluencePageTool(getAuth, getAuthHeader2, logger19) {
|
|
1128
1128
|
return core.toolBuilder().name("get-confluence-page").description("Get the full content of a specific Confluence page by its ID. Returns the page title, content (in storage format), space, and metadata.").category(core.ToolCategory.WEB).tag("confluence").tag("page").tag("content").usageNotes("Use this after search-confluence to retrieve the full content of a specific page. The page ID can be found in search results.").requires(["search-confluence"]).schema(zod.z.object({
|
|
1129
1129
|
page_id: zod.z.string().describe("The Confluence page ID (from search results)")
|
|
1130
1130
|
})).implement(async ({ page_id }) => {
|
|
1131
|
-
|
|
1131
|
+
logger19.info("get-confluence-page called", { page_id });
|
|
1132
1132
|
try {
|
|
1133
1133
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1134
1134
|
const response = await axios16__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`, {
|
|
@@ -1141,7 +1141,7 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1141
1141
|
}
|
|
1142
1142
|
});
|
|
1143
1143
|
const page = response.data;
|
|
1144
|
-
|
|
1144
|
+
logger19.info("get-confluence-page result", {
|
|
1145
1145
|
page_id,
|
|
1146
1146
|
title: page.title,
|
|
1147
1147
|
space: page.space?.name,
|
|
@@ -1163,7 +1163,7 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1163
1163
|
}
|
|
1164
1164
|
});
|
|
1165
1165
|
} catch (error) {
|
|
1166
|
-
|
|
1166
|
+
logger19.error("get-confluence-page error", {
|
|
1167
1167
|
page_id,
|
|
1168
1168
|
error: error.response?.data?.message || error.message,
|
|
1169
1169
|
status: error.response?.status
|
|
@@ -1175,11 +1175,11 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1175
1175
|
}
|
|
1176
1176
|
}).build();
|
|
1177
1177
|
}
|
|
1178
|
-
function createListConfluenceSpacesTool(getAuth, getAuthHeader2,
|
|
1178
|
+
function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger19) {
|
|
1179
1179
|
return core.toolBuilder().name("list-confluence-spaces").description("List all available Confluence spaces. Returns space names, keys, types, and descriptions to help identify where to search for information.").category(core.ToolCategory.WEB).tag("confluence").tag("spaces").tag("list").usageNotes("Use this first to discover available spaces before searching. Helps narrow down searches to specific areas (e.g., 'AI', 'BL3', 'Finance').").follows(["search-confluence"]).schema(zod.z.object({
|
|
1180
1180
|
limit: zod.z.number().optional().describe("Maximum number of spaces to return (default: 25)")
|
|
1181
1181
|
})).implement(async ({ limit = 25 }) => {
|
|
1182
|
-
|
|
1182
|
+
logger19.info("list-confluence-spaces called", { limit });
|
|
1183
1183
|
try {
|
|
1184
1184
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1185
1185
|
const response = await axios16__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/space`, {
|
|
@@ -1198,7 +1198,7 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1198
1198
|
description: space.description?.plain?.value || "",
|
|
1199
1199
|
url: `${ATLASSIAN_SITE_URL}/wiki${space._links.webui}`
|
|
1200
1200
|
}));
|
|
1201
|
-
|
|
1201
|
+
logger19.info("list-confluence-spaces result", {
|
|
1202
1202
|
spaceCount: spaces.length,
|
|
1203
1203
|
spaceKeys: spaces.map((s) => s.key).slice(0, 5)
|
|
1204
1204
|
// Log first 5 space keys
|
|
@@ -1209,7 +1209,7 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1209
1209
|
spaces
|
|
1210
1210
|
});
|
|
1211
1211
|
} catch (error) {
|
|
1212
|
-
|
|
1212
|
+
logger19.error("list-confluence-spaces error", {
|
|
1213
1213
|
error: error.response?.data?.message || error.message,
|
|
1214
1214
|
status: error.response?.status
|
|
1215
1215
|
});
|
|
@@ -1220,12 +1220,12 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1220
1220
|
}
|
|
1221
1221
|
}).build();
|
|
1222
1222
|
}
|
|
1223
|
-
function createGetSpacePagesTool(getAuth, getAuthHeader2,
|
|
1223
|
+
function createGetSpacePagesTool(getAuth, getAuthHeader2, logger19) {
|
|
1224
1224
|
return core.toolBuilder().name("get-space-pages").description("Get all pages from a specific Confluence space by space key. Useful for browsing content in a particular area.").category(core.ToolCategory.WEB).tag("confluence").tag("space").tag("pages").usageNotes("Use this to explore all pages in a specific space. Get the space key from list-confluence-spaces first.").requires(["list-confluence-spaces"]).schema(zod.z.object({
|
|
1225
1225
|
space_key: zod.z.string().describe("The space key (e.g., 'AI', 'BL3', 'FIN')"),
|
|
1226
1226
|
limit: zod.z.number().optional().describe("Maximum number of pages to return (default: 25)")
|
|
1227
1227
|
})).implement(async ({ space_key, limit = 25 }) => {
|
|
1228
|
-
|
|
1228
|
+
logger19.info("get-space-pages called", { space_key, limit });
|
|
1229
1229
|
try {
|
|
1230
1230
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1231
1231
|
const response = await axios16__default.default.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`, {
|
|
@@ -1247,12 +1247,12 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1247
1247
|
lastModified: page.version?.when || ""
|
|
1248
1248
|
}));
|
|
1249
1249
|
if (pages.length === 0) {
|
|
1250
|
-
|
|
1250
|
+
logger19.warn("get-space-pages returned NO PAGES - this is a valid outcome, agent should not retry", {
|
|
1251
1251
|
space_key,
|
|
1252
1252
|
limit
|
|
1253
1253
|
});
|
|
1254
1254
|
} else {
|
|
1255
|
-
|
|
1255
|
+
logger19.info("get-space-pages result", {
|
|
1256
1256
|
space_key,
|
|
1257
1257
|
pageCount: pages.length,
|
|
1258
1258
|
titles: pages.map((p) => p.title).slice(0, 3)
|
|
@@ -1266,7 +1266,7 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1266
1266
|
pages
|
|
1267
1267
|
});
|
|
1268
1268
|
} catch (error) {
|
|
1269
|
-
|
|
1269
|
+
logger19.error("get-space-pages error", {
|
|
1270
1270
|
space_key,
|
|
1271
1271
|
error: error.response?.data?.message || error.message,
|
|
1272
1272
|
status: error.response?.status
|
|
@@ -1278,14 +1278,14 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1278
1278
|
}
|
|
1279
1279
|
}).build();
|
|
1280
1280
|
}
|
|
1281
|
-
function createCreateConfluencePageTool(getAuth, getAuthHeader2,
|
|
1281
|
+
function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger19) {
|
|
1282
1282
|
return core.toolBuilder().name("create-confluence-page").description("Create a new page in a Confluence space. Requires space key, page title, and content (in HTML storage format).").category(core.ToolCategory.WEB).tag("confluence").tag("create").tag("write").usageNotes("Use this to create new documentation pages. Content should be in Confluence storage format (HTML). Get the space key from list-confluence-spaces first. Be mindful of creating duplicate pages.").requires(["list-confluence-spaces"]).schema(zod.z.object({
|
|
1283
1283
|
space_key: zod.z.string().describe("The space key where the page will be created (e.g., 'AI', 'BL3')"),
|
|
1284
1284
|
title: zod.z.string().describe("The title of the new page"),
|
|
1285
1285
|
content: zod.z.string().describe("The page content in HTML format (Confluence storage format)"),
|
|
1286
1286
|
parent_page_id: zod.z.string().optional().describe("Optional parent page ID to create this as a child page")
|
|
1287
1287
|
})).implement(async ({ space_key, title, content, parent_page_id }) => {
|
|
1288
|
-
|
|
1288
|
+
logger19.info("create-confluence-page called", { space_key, title, hasParent: !!parent_page_id });
|
|
1289
1289
|
try {
|
|
1290
1290
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1291
1291
|
const pageData = {
|
|
@@ -1312,7 +1312,7 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
}
|
|
1314
1314
|
);
|
|
1315
|
-
|
|
1315
|
+
logger19.info("create-confluence-page result", {
|
|
1316
1316
|
page_id: response.data.id,
|
|
1317
1317
|
title: response.data.title,
|
|
1318
1318
|
space: space_key
|
|
@@ -1328,7 +1328,7 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1328
1328
|
}
|
|
1329
1329
|
});
|
|
1330
1330
|
} catch (error) {
|
|
1331
|
-
|
|
1331
|
+
logger19.error("create-confluence-page error", {
|
|
1332
1332
|
space_key,
|
|
1333
1333
|
title,
|
|
1334
1334
|
error: error.response?.data?.message || error.message,
|
|
@@ -1341,13 +1341,13 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1341
1341
|
}
|
|
1342
1342
|
}).build();
|
|
1343
1343
|
}
|
|
1344
|
-
function createUpdateConfluencePageTool(getAuth, getAuthHeader2,
|
|
1344
|
+
function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger19) {
|
|
1345
1345
|
return core.toolBuilder().name("update-confluence-page").description("Update an existing Confluence page's content. Requires page ID, new title, and new content.").category(core.ToolCategory.WEB).tag("confluence").tag("update").tag("write").usageNotes("Use this to update existing documentation. You must provide the page ID (from search results). The tool will automatically handle version incrementing. Always get the current page content first to avoid overwriting important information.").requires(["get-confluence-page"]).schema(zod.z.object({
|
|
1346
1346
|
page_id: zod.z.string().describe("The ID of the page to update"),
|
|
1347
1347
|
title: zod.z.string().describe("The new title for the page"),
|
|
1348
1348
|
content: zod.z.string().describe("The new content in HTML format (Confluence storage format)")
|
|
1349
1349
|
})).implement(async ({ page_id, title, content }) => {
|
|
1350
|
-
|
|
1350
|
+
logger19.info("update-confluence-page called", { page_id, title });
|
|
1351
1351
|
try {
|
|
1352
1352
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1353
1353
|
const getResponse = await axios16__default.default.get(
|
|
@@ -1380,7 +1380,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1380
1380
|
}
|
|
1381
1381
|
}
|
|
1382
1382
|
);
|
|
1383
|
-
|
|
1383
|
+
logger19.info("update-confluence-page result", {
|
|
1384
1384
|
page_id,
|
|
1385
1385
|
title: updateResponse.data.title,
|
|
1386
1386
|
previousVersion: currentVersion,
|
|
@@ -1397,7 +1397,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1397
1397
|
}
|
|
1398
1398
|
});
|
|
1399
1399
|
} catch (error) {
|
|
1400
|
-
|
|
1400
|
+
logger19.error("update-confluence-page error", {
|
|
1401
1401
|
page_id,
|
|
1402
1402
|
title,
|
|
1403
1403
|
error: error.response?.data?.message || error.message,
|
|
@@ -1410,12 +1410,12 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1410
1410
|
}
|
|
1411
1411
|
}).build();
|
|
1412
1412
|
}
|
|
1413
|
-
function createArchiveConfluencePageTool(getAuth, getAuthHeader2,
|
|
1413
|
+
function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger19) {
|
|
1414
1414
|
return core.toolBuilder().name("archive-confluence-page").description("Archive a Confluence page by moving it to trash. The page can be restored by space admins. Note: UI may require a note explaining why the page was archived.").category(core.ToolCategory.WEB).tag("confluence").tag("archive").tag("delete").usageNotes("Use this to archive outdated or obsolete documentation. The page is moved to trash, not permanently deleted. Space admins can restore it if needed. Be very careful - only archive pages that are truly obsolete.").conflicts(["create-confluence-page"]).schema(zod.z.object({
|
|
1415
1415
|
page_id: zod.z.string().describe("The ID of the page to archive"),
|
|
1416
1416
|
reason: zod.z.string().optional().describe("Optional reason for archiving (for audit trail)")
|
|
1417
1417
|
})).implement(async ({ page_id, reason }) => {
|
|
1418
|
-
|
|
1418
|
+
logger19.info("archive-confluence-page called", {
|
|
1419
1419
|
page_id,
|
|
1420
1420
|
...reason ? { reason } : {}
|
|
1421
1421
|
});
|
|
@@ -1449,7 +1449,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1449
1449
|
}
|
|
1450
1450
|
}
|
|
1451
1451
|
);
|
|
1452
|
-
|
|
1452
|
+
logger19.info("archive-confluence-page result", {
|
|
1453
1453
|
page_id,
|
|
1454
1454
|
title: pageData.title,
|
|
1455
1455
|
previousVersion: currentVersion,
|
|
@@ -1467,7 +1467,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger18) {
|
|
|
1467
1467
|
}
|
|
1468
1468
|
});
|
|
1469
1469
|
} catch (error) {
|
|
1470
|
-
|
|
1470
|
+
logger19.error("archive-confluence-page error", {
|
|
1471
1471
|
page_id,
|
|
1472
1472
|
error: error.response?.data?.message || error.message,
|
|
1473
1473
|
status: error.response?.status
|
|
@@ -4195,19 +4195,19 @@ var ConnectionState = /* @__PURE__ */ ((ConnectionState2) => {
|
|
|
4195
4195
|
ConnectionState2["ERROR"] = "error";
|
|
4196
4196
|
return ConnectionState2;
|
|
4197
4197
|
})(ConnectionState || {});
|
|
4198
|
-
function cancelPendingReconnection(timer,
|
|
4198
|
+
function cancelPendingReconnection(timer, logger19, vendor, message) {
|
|
4199
4199
|
if (!timer) {
|
|
4200
4200
|
return null;
|
|
4201
4201
|
}
|
|
4202
|
-
|
|
4202
|
+
logger19.debug(message, { vendor });
|
|
4203
4203
|
clearTimeout(timer);
|
|
4204
4204
|
return null;
|
|
4205
4205
|
}
|
|
4206
|
-
async function waitForInFlightConnection(promise,
|
|
4206
|
+
async function waitForInFlightConnection(promise, logger19, vendor, phase) {
|
|
4207
4207
|
if (!promise) {
|
|
4208
4208
|
return null;
|
|
4209
4209
|
}
|
|
4210
|
-
|
|
4210
|
+
logger19.debug(`Waiting for in-flight connection attempt to complete before ${phase}`, {
|
|
4211
4211
|
vendor
|
|
4212
4212
|
});
|
|
4213
4213
|
try {
|
|
@@ -4224,9 +4224,9 @@ function shutdownClient(vendor, client) {
|
|
|
4224
4224
|
client.close();
|
|
4225
4225
|
}
|
|
4226
4226
|
}
|
|
4227
|
-
function scheduleReconnection(context,
|
|
4227
|
+
function scheduleReconnection(context, logger19) {
|
|
4228
4228
|
if (context.reconnectionConfig.maxAttempts > 0 && context.reconnectionAttempts >= context.reconnectionConfig.maxAttempts) {
|
|
4229
|
-
|
|
4229
|
+
logger19.error("Max reconnection attempts reached", {
|
|
4230
4230
|
vendor: context.vendor,
|
|
4231
4231
|
attempts: context.reconnectionAttempts,
|
|
4232
4232
|
maxAttempts: context.reconnectionConfig.maxAttempts
|
|
@@ -4240,7 +4240,7 @@ function scheduleReconnection(context, logger18) {
|
|
|
4240
4240
|
const nextAttempt = context.reconnectionAttempts + 1;
|
|
4241
4241
|
context.setReconnectionAttempts(nextAttempt);
|
|
4242
4242
|
context.setState("reconnecting" /* RECONNECTING */);
|
|
4243
|
-
|
|
4243
|
+
logger19.info("Scheduling reconnection attempt", {
|
|
4244
4244
|
vendor: context.vendor,
|
|
4245
4245
|
attempt: nextAttempt,
|
|
4246
4246
|
maxAttempts: context.reconnectionConfig.maxAttempts,
|
|
@@ -4254,7 +4254,7 @@ function scheduleReconnection(context, logger18) {
|
|
|
4254
4254
|
const timer = setTimeout(async () => {
|
|
4255
4255
|
context.setReconnectionTimer(null);
|
|
4256
4256
|
try {
|
|
4257
|
-
|
|
4257
|
+
logger19.info("Attempting reconnection", {
|
|
4258
4258
|
vendor: context.vendor,
|
|
4259
4259
|
attempt: nextAttempt
|
|
4260
4260
|
});
|
|
@@ -4264,7 +4264,7 @@ function scheduleReconnection(context, logger18) {
|
|
|
4264
4264
|
context.setConnectPromise(promise);
|
|
4265
4265
|
await promise;
|
|
4266
4266
|
} catch (error) {
|
|
4267
|
-
|
|
4267
|
+
logger19.error("Reconnection attempt failed", {
|
|
4268
4268
|
vendor: context.vendor,
|
|
4269
4269
|
attempt: nextAttempt,
|
|
4270
4270
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -4275,17 +4275,17 @@ function scheduleReconnection(context, logger18) {
|
|
|
4275
4275
|
}
|
|
4276
4276
|
|
|
4277
4277
|
// src/data/relational/connection/connection-cleanup.ts
|
|
4278
|
-
async function cleanupConnectionResources(vendor, client, clearConnection,
|
|
4278
|
+
async function cleanupConnectionResources(vendor, client, clearConnection, logger19) {
|
|
4279
4279
|
if (!client) {
|
|
4280
4280
|
return;
|
|
4281
4281
|
}
|
|
4282
|
-
|
|
4282
|
+
logger19.debug("Cleaning up cancelled connection", {
|
|
4283
4283
|
vendor
|
|
4284
4284
|
});
|
|
4285
4285
|
try {
|
|
4286
4286
|
await shutdownClient(vendor, client);
|
|
4287
4287
|
} catch (error) {
|
|
4288
|
-
|
|
4288
|
+
logger19.debug("Error during cancelled connection cleanup", {
|
|
4289
4289
|
vendor,
|
|
4290
4290
|
error: error instanceof Error ? error.message : String(error)
|
|
4291
4291
|
});
|
|
@@ -4293,10 +4293,10 @@ async function cleanupConnectionResources(vendor, client, clearConnection, logge
|
|
|
4293
4293
|
clearConnection();
|
|
4294
4294
|
}
|
|
4295
4295
|
}
|
|
4296
|
-
async function closeManagedConnection(runtime,
|
|
4296
|
+
async function closeManagedConnection(runtime, logger19) {
|
|
4297
4297
|
const client = runtime.getClient();
|
|
4298
4298
|
if (client) {
|
|
4299
|
-
|
|
4299
|
+
logger19.info("Closing database connection", {
|
|
4300
4300
|
vendor: runtime.vendor,
|
|
4301
4301
|
state: runtime.getState()
|
|
4302
4302
|
});
|
|
@@ -4304,12 +4304,12 @@ async function closeManagedConnection(runtime, logger18) {
|
|
|
4304
4304
|
await shutdownClient(runtime.vendor, client);
|
|
4305
4305
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4306
4306
|
runtime.emitDisconnected();
|
|
4307
|
-
|
|
4307
|
+
logger19.debug("Database connection closed successfully", {
|
|
4308
4308
|
vendor: runtime.vendor,
|
|
4309
4309
|
state: runtime.getState()
|
|
4310
4310
|
});
|
|
4311
4311
|
} catch (error) {
|
|
4312
|
-
|
|
4312
|
+
logger19.error("Error closing database connection", {
|
|
4313
4313
|
vendor: runtime.vendor,
|
|
4314
4314
|
error: error instanceof Error ? error.message : String(error),
|
|
4315
4315
|
state: runtime.getState()
|
|
@@ -4482,11 +4482,11 @@ async function initializeSQLiteConnection(connection) {
|
|
|
4482
4482
|
}
|
|
4483
4483
|
|
|
4484
4484
|
// src/data/relational/connection/connection-initialization.ts
|
|
4485
|
-
async function initializeManagedConnection(runtime,
|
|
4485
|
+
async function initializeManagedConnection(runtime, logger19) {
|
|
4486
4486
|
const startTime = Date.now();
|
|
4487
4487
|
const currentGeneration = runtime.getConnectionGeneration();
|
|
4488
4488
|
if (runtime.getState() === "connected" /* CONNECTED */ && runtime.getClient()) {
|
|
4489
|
-
|
|
4489
|
+
logger19.warn("Re-initializing an already connected manager; emitting disconnected before cleanup", {
|
|
4490
4490
|
vendor: runtime.vendor
|
|
4491
4491
|
});
|
|
4492
4492
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
@@ -4498,11 +4498,11 @@ async function initializeManagedConnection(runtime, logger18) {
|
|
|
4498
4498
|
runtime.setClient(null);
|
|
4499
4499
|
runtime.setDb(null);
|
|
4500
4500
|
},
|
|
4501
|
-
|
|
4501
|
+
logger19
|
|
4502
4502
|
);
|
|
4503
4503
|
}
|
|
4504
4504
|
runtime.setState("connecting" /* CONNECTING */);
|
|
4505
|
-
|
|
4505
|
+
logger19.info("Initializing database connection", {
|
|
4506
4506
|
vendor: runtime.vendor,
|
|
4507
4507
|
connectionType: typeof runtime.config.connection,
|
|
4508
4508
|
state: runtime.getState()
|
|
@@ -4512,7 +4512,7 @@ async function initializeManagedConnection(runtime, logger18) {
|
|
|
4512
4512
|
runtime.setClient(initialized.client);
|
|
4513
4513
|
runtime.setDb(initialized.db);
|
|
4514
4514
|
if (currentGeneration !== runtime.getConnectionGeneration()) {
|
|
4515
|
-
|
|
4515
|
+
logger19.debug("Connection cancelled during initialization", {
|
|
4516
4516
|
vendor: runtime.vendor,
|
|
4517
4517
|
currentGeneration,
|
|
4518
4518
|
newGeneration: runtime.getConnectionGeneration()
|
|
@@ -4524,18 +4524,18 @@ async function initializeManagedConnection(runtime, logger18) {
|
|
|
4524
4524
|
runtime.setClient(null);
|
|
4525
4525
|
runtime.setDb(null);
|
|
4526
4526
|
},
|
|
4527
|
-
|
|
4527
|
+
logger19
|
|
4528
4528
|
);
|
|
4529
4529
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4530
4530
|
throw new Error("Connection cancelled during initialization");
|
|
4531
4531
|
}
|
|
4532
|
-
|
|
4532
|
+
logger19.debug("Validating connection health", { vendor: runtime.vendor });
|
|
4533
4533
|
const healthy = await runtime.isHealthy();
|
|
4534
4534
|
if (!healthy) {
|
|
4535
4535
|
throw new Error(`Failed to establish healthy connection to ${runtime.vendor} database`);
|
|
4536
4536
|
}
|
|
4537
4537
|
if (currentGeneration !== runtime.getConnectionGeneration()) {
|
|
4538
|
-
|
|
4538
|
+
logger19.debug("Connection cancelled during health check", {
|
|
4539
4539
|
vendor: runtime.vendor,
|
|
4540
4540
|
currentGeneration,
|
|
4541
4541
|
newGeneration: runtime.getConnectionGeneration()
|
|
@@ -4547,7 +4547,7 @@ async function initializeManagedConnection(runtime, logger18) {
|
|
|
4547
4547
|
runtime.setClient(null);
|
|
4548
4548
|
runtime.setDb(null);
|
|
4549
4549
|
},
|
|
4550
|
-
|
|
4550
|
+
logger19
|
|
4551
4551
|
);
|
|
4552
4552
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4553
4553
|
throw new Error("Connection cancelled during health check");
|
|
@@ -4555,7 +4555,7 @@ async function initializeManagedConnection(runtime, logger18) {
|
|
|
4555
4555
|
runtime.setState("connected" /* CONNECTED */);
|
|
4556
4556
|
runtime.emitConnected();
|
|
4557
4557
|
runtime.resetReconnectionAttempts();
|
|
4558
|
-
|
|
4558
|
+
logger19.info("Database connection initialized successfully", {
|
|
4559
4559
|
vendor: runtime.vendor,
|
|
4560
4560
|
duration: Date.now() - startTime,
|
|
4561
4561
|
state: runtime.getState()
|
|
@@ -4576,7 +4576,7 @@ async function initializeManagedConnection(runtime, logger18) {
|
|
|
4576
4576
|
if (runtime.errorListenerCount() > 0) {
|
|
4577
4577
|
runtime.emitError(normalizedError);
|
|
4578
4578
|
}
|
|
4579
|
-
|
|
4579
|
+
logger19.error(errorMessage, {
|
|
4580
4580
|
vendor: runtime.vendor,
|
|
4581
4581
|
error: normalizedError.message,
|
|
4582
4582
|
duration: Date.now() - startTime,
|
|
@@ -4589,13 +4589,13 @@ async function initializeManagedConnection(runtime, logger18) {
|
|
|
4589
4589
|
runtime.setClient(null);
|
|
4590
4590
|
runtime.setDb(null);
|
|
4591
4591
|
},
|
|
4592
|
-
|
|
4592
|
+
logger19
|
|
4593
4593
|
);
|
|
4594
4594
|
if (runtime.getReconnectionConfig().enabled && currentGeneration === runtime.getConnectionGeneration()) {
|
|
4595
4595
|
runtime.scheduleReconnection();
|
|
4596
4596
|
}
|
|
4597
4597
|
} else {
|
|
4598
|
-
|
|
4598
|
+
logger19.debug("Connection initialization cancelled", {
|
|
4599
4599
|
vendor: runtime.vendor,
|
|
4600
4600
|
duration: Date.now() - startTime,
|
|
4601
4601
|
state: runtime.getState()
|
|
@@ -4613,17 +4613,17 @@ function isSqliteNonQueryError(error) {
|
|
|
4613
4613
|
const hasNonQueryMessage = error.message.includes("does not return data");
|
|
4614
4614
|
return isSqliteOrTypeError && hasNonQueryMessage;
|
|
4615
4615
|
}
|
|
4616
|
-
async function checkConnectionHealth(args,
|
|
4616
|
+
async function checkConnectionHealth(args, logger19) {
|
|
4617
4617
|
if (!args.db || !args.client) {
|
|
4618
|
-
|
|
4618
|
+
logger19.debug("Health check failed: connection not initialized", { vendor: args.vendor });
|
|
4619
4619
|
return false;
|
|
4620
4620
|
}
|
|
4621
4621
|
try {
|
|
4622
4622
|
await args.execute(drizzleOrm.sql`SELECT 1`);
|
|
4623
|
-
|
|
4623
|
+
logger19.debug("Health check passed", { vendor: args.vendor });
|
|
4624
4624
|
return true;
|
|
4625
4625
|
} catch (error) {
|
|
4626
|
-
|
|
4626
|
+
logger19.debug("Health check failed", {
|
|
4627
4627
|
vendor: args.vendor,
|
|
4628
4628
|
error: error instanceof Error ? error.message : String(error)
|
|
4629
4629
|
});
|
|
@@ -4666,8 +4666,8 @@ function getConnectionPoolMetrics(vendor, client) {
|
|
|
4666
4666
|
}
|
|
4667
4667
|
|
|
4668
4668
|
// src/data/relational/connection/query-execution.ts
|
|
4669
|
-
async function executeQuery(context, query,
|
|
4670
|
-
|
|
4669
|
+
async function executeQuery(context, query, logger19) {
|
|
4670
|
+
logger19.debug("Executing SQL query", {
|
|
4671
4671
|
vendor: context.vendor
|
|
4672
4672
|
});
|
|
4673
4673
|
if (context.vendor === "sqlite") {
|
|
@@ -6794,16 +6794,24 @@ function findTable(schema, tableName) {
|
|
|
6794
6794
|
function formatTableName(table) {
|
|
6795
6795
|
return table.schema ? `${table.schema}.${table.name}` : table.name;
|
|
6796
6796
|
}
|
|
6797
|
-
|
|
6797
|
+
|
|
6798
|
+
// src/data/relational/schema/type-mapper-normalization.ts
|
|
6799
|
+
function normaliseDbType(raw) {
|
|
6800
|
+
let type = raw.toLowerCase().trim();
|
|
6801
|
+
type = type.replace(/\[\]$/, "");
|
|
6802
|
+
type = type.replace(/\([\d,\s]+\)/, "");
|
|
6803
|
+
type = type.replace(/\s+unsigned$/, "");
|
|
6804
|
+
return type.trim();
|
|
6805
|
+
}
|
|
6806
|
+
|
|
6807
|
+
// src/data/relational/schema/type-mapper-vendor-maps.ts
|
|
6798
6808
|
var POSTGRES_TYPE_MAP = {
|
|
6799
|
-
// Numeric
|
|
6800
6809
|
smallint: "number",
|
|
6801
6810
|
integer: "number",
|
|
6802
6811
|
int: "number",
|
|
6803
6812
|
int2: "number",
|
|
6804
6813
|
int4: "number",
|
|
6805
6814
|
int8: "string",
|
|
6806
|
-
// bigint → string to avoid JS precision loss
|
|
6807
6815
|
bigint: "string",
|
|
6808
6816
|
serial: "number",
|
|
6809
6817
|
bigserial: "string",
|
|
@@ -6813,10 +6821,8 @@ var POSTGRES_TYPE_MAP = {
|
|
|
6813
6821
|
"double precision": "number",
|
|
6814
6822
|
float8: "number",
|
|
6815
6823
|
numeric: "string",
|
|
6816
|
-
// arbitrary precision → string
|
|
6817
6824
|
decimal: "string",
|
|
6818
6825
|
money: "string",
|
|
6819
|
-
// Text
|
|
6820
6826
|
text: "string",
|
|
6821
6827
|
"character varying": "string",
|
|
6822
6828
|
varchar: "string",
|
|
@@ -6824,10 +6830,8 @@ var POSTGRES_TYPE_MAP = {
|
|
|
6824
6830
|
character: "string",
|
|
6825
6831
|
name: "string",
|
|
6826
6832
|
citext: "string",
|
|
6827
|
-
// Boolean
|
|
6828
6833
|
boolean: "boolean",
|
|
6829
6834
|
bool: "boolean",
|
|
6830
|
-
// Date / time
|
|
6831
6835
|
date: "string",
|
|
6832
6836
|
timestamp: "string",
|
|
6833
6837
|
"timestamp with time zone": "string",
|
|
@@ -6838,19 +6842,14 @@ var POSTGRES_TYPE_MAP = {
|
|
|
6838
6842
|
"time without time zone": "string",
|
|
6839
6843
|
timetz: "string",
|
|
6840
6844
|
interval: "string",
|
|
6841
|
-
// JSON
|
|
6842
6845
|
json: "unknown",
|
|
6843
6846
|
jsonb: "unknown",
|
|
6844
|
-
// Binary
|
|
6845
6847
|
bytea: "Buffer",
|
|
6846
|
-
// UUID
|
|
6847
6848
|
uuid: "string",
|
|
6848
|
-
// Network
|
|
6849
6849
|
inet: "string",
|
|
6850
6850
|
cidr: "string",
|
|
6851
6851
|
macaddr: "string",
|
|
6852
6852
|
macaddr8: "string",
|
|
6853
|
-
// Geometric (represented as strings)
|
|
6854
6853
|
point: "string",
|
|
6855
6854
|
line: "string",
|
|
6856
6855
|
lseg: "string",
|
|
@@ -6858,21 +6857,18 @@ var POSTGRES_TYPE_MAP = {
|
|
|
6858
6857
|
path: "string",
|
|
6859
6858
|
polygon: "string",
|
|
6860
6859
|
circle: "string",
|
|
6861
|
-
// Other
|
|
6862
6860
|
xml: "string",
|
|
6863
6861
|
tsvector: "string",
|
|
6864
6862
|
tsquery: "string",
|
|
6865
6863
|
oid: "number"
|
|
6866
6864
|
};
|
|
6867
6865
|
var MYSQL_TYPE_MAP = {
|
|
6868
|
-
// Numeric
|
|
6869
6866
|
tinyint: "number",
|
|
6870
6867
|
smallint: "number",
|
|
6871
6868
|
mediumint: "number",
|
|
6872
6869
|
int: "number",
|
|
6873
6870
|
integer: "number",
|
|
6874
6871
|
bigint: "string",
|
|
6875
|
-
// precision
|
|
6876
6872
|
float: "number",
|
|
6877
6873
|
double: "number",
|
|
6878
6874
|
"double precision": "number",
|
|
@@ -6880,7 +6876,6 @@ var MYSQL_TYPE_MAP = {
|
|
|
6880
6876
|
dec: "string",
|
|
6881
6877
|
numeric: "string",
|
|
6882
6878
|
bit: "number",
|
|
6883
|
-
// Text
|
|
6884
6879
|
char: "string",
|
|
6885
6880
|
varchar: "string",
|
|
6886
6881
|
tinytext: "string",
|
|
@@ -6889,40 +6884,32 @@ var MYSQL_TYPE_MAP = {
|
|
|
6889
6884
|
longtext: "string",
|
|
6890
6885
|
enum: "string",
|
|
6891
6886
|
set: "string",
|
|
6892
|
-
// Boolean (MySQL uses tinyint(1))
|
|
6893
6887
|
boolean: "boolean",
|
|
6894
6888
|
bool: "boolean",
|
|
6895
|
-
// Binary
|
|
6896
6889
|
binary: "Buffer",
|
|
6897
6890
|
varbinary: "Buffer",
|
|
6898
6891
|
tinyblob: "Buffer",
|
|
6899
6892
|
blob: "Buffer",
|
|
6900
6893
|
mediumblob: "Buffer",
|
|
6901
6894
|
longblob: "Buffer",
|
|
6902
|
-
// Date / time
|
|
6903
6895
|
date: "string",
|
|
6904
6896
|
datetime: "string",
|
|
6905
6897
|
timestamp: "string",
|
|
6906
6898
|
time: "string",
|
|
6907
6899
|
year: "number",
|
|
6908
|
-
// JSON
|
|
6909
6900
|
json: "unknown",
|
|
6910
|
-
// Spatial (represented as strings)
|
|
6911
6901
|
geometry: "string",
|
|
6912
6902
|
point: "string",
|
|
6913
6903
|
linestring: "string",
|
|
6914
6904
|
polygon: "string"
|
|
6915
6905
|
};
|
|
6916
6906
|
var SQLITE_TYPE_MAP = {
|
|
6917
|
-
// SQLite has dynamic typing with 5 storage classes.
|
|
6918
|
-
// The declared type is advisory; these are the common declared types.
|
|
6919
6907
|
integer: "number",
|
|
6920
6908
|
int: "number",
|
|
6921
6909
|
tinyint: "number",
|
|
6922
6910
|
smallint: "number",
|
|
6923
6911
|
mediumint: "number",
|
|
6924
6912
|
bigint: "number",
|
|
6925
|
-
// SQLite stores as 64-bit int, JS number is safe up to 2^53
|
|
6926
6913
|
real: "number",
|
|
6927
6914
|
double: "number",
|
|
6928
6915
|
"double precision": "number",
|
|
@@ -6930,7 +6917,6 @@ var SQLITE_TYPE_MAP = {
|
|
|
6930
6917
|
numeric: "number",
|
|
6931
6918
|
decimal: "number",
|
|
6932
6919
|
boolean: "number",
|
|
6933
|
-
// SQLite stores booleans as 0/1
|
|
6934
6920
|
text: "string",
|
|
6935
6921
|
varchar: "string",
|
|
6936
6922
|
char: "string",
|
|
@@ -6945,13 +6931,16 @@ var SQLITE_TYPE_MAP = {
|
|
|
6945
6931
|
timestamp: "string",
|
|
6946
6932
|
json: "unknown"
|
|
6947
6933
|
};
|
|
6948
|
-
var
|
|
6934
|
+
var VENDOR_TYPE_MAPS = {
|
|
6949
6935
|
postgresql: POSTGRES_TYPE_MAP,
|
|
6950
6936
|
mysql: MYSQL_TYPE_MAP,
|
|
6951
6937
|
sqlite: SQLITE_TYPE_MAP
|
|
6952
6938
|
};
|
|
6939
|
+
|
|
6940
|
+
// src/data/relational/schema/type-mapper.ts
|
|
6941
|
+
var logger13 = core.createLogger("agentforge:tools:data:relational:type-mapper");
|
|
6953
6942
|
function mapColumnType(vendor, dbType, nullable = false) {
|
|
6954
|
-
const typeMap =
|
|
6943
|
+
const typeMap = VENDOR_TYPE_MAPS[vendor];
|
|
6955
6944
|
if (!typeMap) {
|
|
6956
6945
|
return { tsType: "unknown", nullable, dbType, notes: `Unsupported vendor: ${vendor}` };
|
|
6957
6946
|
}
|
|
@@ -6962,18 +6951,20 @@ function mapColumnType(vendor, dbType, nullable = false) {
|
|
|
6962
6951
|
result.notes = `No explicit mapping for "${dbType}"; defaulting to unknown`;
|
|
6963
6952
|
logger13.debug("Unmapped database type", { vendor, dbType, normalised });
|
|
6964
6953
|
}
|
|
6965
|
-
if ((
|
|
6954
|
+
if (usesStringPrecisionFallback(vendor, normalised)) {
|
|
6966
6955
|
result.notes = "Mapped to string to avoid JavaScript number precision loss for 64-bit integers";
|
|
6967
6956
|
}
|
|
6968
6957
|
return result;
|
|
6969
6958
|
}
|
|
6970
6959
|
function mapSchemaTypes(vendor, columns) {
|
|
6971
6960
|
const result = /* @__PURE__ */ new Map();
|
|
6972
|
-
for (const
|
|
6973
|
-
|
|
6974
|
-
|
|
6961
|
+
for (const column of columns) {
|
|
6962
|
+
let tableColumns = result.get(column.table);
|
|
6963
|
+
if (!tableColumns) {
|
|
6964
|
+
tableColumns = /* @__PURE__ */ new Map();
|
|
6965
|
+
result.set(column.table, tableColumns);
|
|
6975
6966
|
}
|
|
6976
|
-
|
|
6967
|
+
tableColumns.set(column.name, mapColumnType(vendor, column.type, column.nullable));
|
|
6977
6968
|
}
|
|
6978
6969
|
logger13.debug("Schema type mapping complete", {
|
|
6979
6970
|
vendor,
|
|
@@ -6983,14 +6974,10 @@ function mapSchemaTypes(vendor, columns) {
|
|
|
6983
6974
|
return result;
|
|
6984
6975
|
}
|
|
6985
6976
|
function getVendorTypeMap(vendor) {
|
|
6986
|
-
return { ...
|
|
6977
|
+
return { ...VENDOR_TYPE_MAPS[vendor] };
|
|
6987
6978
|
}
|
|
6988
|
-
function
|
|
6989
|
-
|
|
6990
|
-
type = type.replace(/\[\]$/, "");
|
|
6991
|
-
type = type.replace(/\([\d,\s]+\)/, "");
|
|
6992
|
-
type = type.replace(/\s+unsigned$/, "");
|
|
6993
|
-
return type.trim();
|
|
6979
|
+
function usesStringPrecisionFallback(vendor, normalised) {
|
|
6980
|
+
return (normalised === "bigint" || normalised === "int8" || normalised === "bigserial") && (vendor === "postgresql" || vendor === "mysql");
|
|
6994
6981
|
}
|
|
6995
6982
|
var logger14 = core.createLogger("agentforge:tools:data:relational:schema-diff");
|
|
6996
6983
|
function diffSchemas(before, after) {
|
|
@@ -7022,15 +7009,15 @@ function diffSchemas(before, after) {
|
|
|
7022
7009
|
}
|
|
7023
7010
|
tableDiffs.push(diff);
|
|
7024
7011
|
}
|
|
7025
|
-
for (const
|
|
7026
|
-
if (
|
|
7027
|
-
else if (
|
|
7012
|
+
for (const columnDiff of colDiffs) {
|
|
7013
|
+
if (columnDiff.type === "added") columnsAdded++;
|
|
7014
|
+
else if (columnDiff.type === "removed") columnsRemoved++;
|
|
7028
7015
|
else columnsChanged++;
|
|
7029
7016
|
}
|
|
7030
7017
|
}
|
|
7031
|
-
const tablesAdded = tableDiffs.filter((
|
|
7032
|
-
const tablesRemoved = tableDiffs.filter((
|
|
7033
|
-
const tablesChanged = tableDiffs.filter((
|
|
7018
|
+
const tablesAdded = tableDiffs.filter((diff) => diff.type === "added").length;
|
|
7019
|
+
const tablesRemoved = tableDiffs.filter((diff) => diff.type === "removed").length;
|
|
7020
|
+
const tablesChanged = tableDiffs.filter((diff) => diff.type === "changed").length;
|
|
7034
7021
|
const identical = tableDiffs.length === 0;
|
|
7035
7022
|
logger14.debug("Schema diff computed", {
|
|
7036
7023
|
identical,
|
|
@@ -7044,58 +7031,10 @@ function diffSchemas(before, after) {
|
|
|
7044
7031
|
summary: { tablesAdded, tablesRemoved, tablesChanged, columnsAdded, columnsRemoved, columnsChanged }
|
|
7045
7032
|
};
|
|
7046
7033
|
}
|
|
7047
|
-
function exportSchemaToJson(schema) {
|
|
7048
|
-
return JSON.stringify(schema, sortedReplacer, 2);
|
|
7049
|
-
}
|
|
7050
|
-
function importSchemaFromJson(json) {
|
|
7051
|
-
const parsed = JSON.parse(json);
|
|
7052
|
-
if (!parsed || typeof parsed !== "object") {
|
|
7053
|
-
throw new Error("Invalid schema JSON: expected an object");
|
|
7054
|
-
}
|
|
7055
|
-
const obj = parsed;
|
|
7056
|
-
if (!obj.vendor || typeof obj.vendor !== "string") {
|
|
7057
|
-
throw new Error('Invalid schema JSON: missing or invalid "vendor" field');
|
|
7058
|
-
}
|
|
7059
|
-
if (!Array.isArray(obj.tables)) {
|
|
7060
|
-
throw new Error('Invalid schema JSON: missing or invalid "tables" array');
|
|
7061
|
-
}
|
|
7062
|
-
if (!obj.generatedAt || typeof obj.generatedAt !== "string") {
|
|
7063
|
-
throw new Error('Invalid schema JSON: missing or invalid "generatedAt" field');
|
|
7064
|
-
}
|
|
7065
|
-
for (const table of obj.tables) {
|
|
7066
|
-
if (!table || typeof table !== "object") {
|
|
7067
|
-
throw new Error("Invalid schema JSON: each table must be an object");
|
|
7068
|
-
}
|
|
7069
|
-
if (!table.name || typeof table.name !== "string") {
|
|
7070
|
-
throw new Error('Invalid schema JSON: each table must have a "name" string');
|
|
7071
|
-
}
|
|
7072
|
-
if (!Array.isArray(table.columns)) {
|
|
7073
|
-
throw new Error(`Invalid schema JSON: table "${table.name}" missing "columns" array`);
|
|
7074
|
-
}
|
|
7075
|
-
if (!Array.isArray(table.primaryKey)) {
|
|
7076
|
-
throw new Error(`Invalid schema JSON: table "${table.name}" missing "primaryKey" array`);
|
|
7077
|
-
}
|
|
7078
|
-
}
|
|
7079
|
-
logger14.debug("Schema imported from JSON", {
|
|
7080
|
-
vendor: obj.vendor,
|
|
7081
|
-
tableCount: obj.tables.length
|
|
7082
|
-
});
|
|
7083
|
-
return parsed;
|
|
7084
|
-
}
|
|
7085
|
-
function sortedReplacer(_key, value) {
|
|
7086
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7087
|
-
const sorted = {};
|
|
7088
|
-
for (const k of Object.keys(value).sort()) {
|
|
7089
|
-
sorted[k] = value[k];
|
|
7090
|
-
}
|
|
7091
|
-
return sorted;
|
|
7092
|
-
}
|
|
7093
|
-
return value;
|
|
7094
|
-
}
|
|
7095
7034
|
function tableMap(tables) {
|
|
7096
7035
|
const map = /* @__PURE__ */ new Map();
|
|
7097
|
-
for (const
|
|
7098
|
-
map.set(formatName(
|
|
7036
|
+
for (const table of tables) {
|
|
7037
|
+
map.set(formatName(table).toLowerCase(), table);
|
|
7099
7038
|
}
|
|
7100
7039
|
return map;
|
|
7101
7040
|
}
|
|
@@ -7106,43 +7045,113 @@ function diffColumns(before, after) {
|
|
|
7106
7045
|
const diffs = [];
|
|
7107
7046
|
const beforeMap = /* @__PURE__ */ new Map();
|
|
7108
7047
|
const afterMap = /* @__PURE__ */ new Map();
|
|
7109
|
-
for (const
|
|
7110
|
-
for (const
|
|
7111
|
-
for (const [key] of beforeMap) {
|
|
7048
|
+
for (const column of before) beforeMap.set(column.name.toLowerCase(), column);
|
|
7049
|
+
for (const column of after) afterMap.set(column.name.toLowerCase(), column);
|
|
7050
|
+
for (const [key, beforeColumn] of beforeMap) {
|
|
7112
7051
|
if (!afterMap.has(key)) {
|
|
7113
|
-
diffs.push({ column:
|
|
7052
|
+
diffs.push({ column: beforeColumn.name, type: "removed" });
|
|
7114
7053
|
}
|
|
7115
7054
|
}
|
|
7116
|
-
for (const [key] of afterMap) {
|
|
7055
|
+
for (const [key, afterColumn] of afterMap) {
|
|
7117
7056
|
if (!beforeMap.has(key)) {
|
|
7118
|
-
diffs.push({ column:
|
|
7057
|
+
diffs.push({ column: afterColumn.name, type: "added" });
|
|
7119
7058
|
}
|
|
7120
7059
|
}
|
|
7121
|
-
for (const [key,
|
|
7122
|
-
const
|
|
7123
|
-
if (!
|
|
7060
|
+
for (const [key, beforeColumn] of beforeMap) {
|
|
7061
|
+
const afterColumn = afterMap.get(key);
|
|
7062
|
+
if (!afterColumn) continue;
|
|
7124
7063
|
const changes = [];
|
|
7125
|
-
if (
|
|
7126
|
-
changes.push({ property: "type", before:
|
|
7127
|
-
}
|
|
7128
|
-
if (
|
|
7129
|
-
changes.push({
|
|
7064
|
+
if (beforeColumn.type.toLowerCase() !== afterColumn.type.toLowerCase()) {
|
|
7065
|
+
changes.push({ property: "type", before: beforeColumn.type, after: afterColumn.type });
|
|
7066
|
+
}
|
|
7067
|
+
if (beforeColumn.isNullable !== afterColumn.isNullable) {
|
|
7068
|
+
changes.push({
|
|
7069
|
+
property: "isNullable",
|
|
7070
|
+
before: beforeColumn.isNullable,
|
|
7071
|
+
after: afterColumn.isNullable
|
|
7072
|
+
});
|
|
7130
7073
|
}
|
|
7131
|
-
if (
|
|
7132
|
-
changes.push({
|
|
7074
|
+
if (beforeColumn.isPrimaryKey !== afterColumn.isPrimaryKey) {
|
|
7075
|
+
changes.push({
|
|
7076
|
+
property: "isPrimaryKey",
|
|
7077
|
+
before: beforeColumn.isPrimaryKey,
|
|
7078
|
+
after: afterColumn.isPrimaryKey
|
|
7079
|
+
});
|
|
7133
7080
|
}
|
|
7134
|
-
if (String(
|
|
7135
|
-
changes.push({
|
|
7081
|
+
if (String(beforeColumn.defaultValue) !== String(afterColumn.defaultValue)) {
|
|
7082
|
+
changes.push({
|
|
7083
|
+
property: "defaultValue",
|
|
7084
|
+
before: beforeColumn.defaultValue,
|
|
7085
|
+
after: afterColumn.defaultValue
|
|
7086
|
+
});
|
|
7136
7087
|
}
|
|
7137
7088
|
if (changes.length > 0) {
|
|
7138
|
-
diffs.push({ column:
|
|
7089
|
+
diffs.push({ column: beforeColumn.name, type: "changed", changes });
|
|
7139
7090
|
}
|
|
7140
7091
|
}
|
|
7141
7092
|
return diffs;
|
|
7142
7093
|
}
|
|
7143
|
-
function arraysEqual(
|
|
7144
|
-
if (
|
|
7145
|
-
return
|
|
7094
|
+
function arraysEqual(before, after) {
|
|
7095
|
+
if (before.length !== after.length) return false;
|
|
7096
|
+
return before.every((value, index) => value === after[index]);
|
|
7097
|
+
}
|
|
7098
|
+
var logger15 = core.createLogger("agentforge:tools:data:relational:schema-diff");
|
|
7099
|
+
function exportSchemaToJson(schema) {
|
|
7100
|
+
return JSON.stringify(schema, sortedReplacer, 2);
|
|
7101
|
+
}
|
|
7102
|
+
function importSchemaFromJson(json) {
|
|
7103
|
+
const parsed = JSON.parse(json);
|
|
7104
|
+
validateSchemaJson(parsed);
|
|
7105
|
+
const schema = parsed;
|
|
7106
|
+
logger15.debug("Schema imported from JSON", {
|
|
7107
|
+
vendor: schema.vendor,
|
|
7108
|
+
tableCount: schema.tables.length
|
|
7109
|
+
});
|
|
7110
|
+
return schema;
|
|
7111
|
+
}
|
|
7112
|
+
function validateSchemaJson(parsed) {
|
|
7113
|
+
if (!parsed || typeof parsed !== "object") {
|
|
7114
|
+
throw new Error("Invalid schema JSON: expected an object");
|
|
7115
|
+
}
|
|
7116
|
+
const schema = parsed;
|
|
7117
|
+
if (!schema.vendor || typeof schema.vendor !== "string") {
|
|
7118
|
+
throw new Error('Invalid schema JSON: missing or invalid "vendor" field');
|
|
7119
|
+
}
|
|
7120
|
+
if (!Array.isArray(schema.tables)) {
|
|
7121
|
+
throw new Error('Invalid schema JSON: missing or invalid "tables" array');
|
|
7122
|
+
}
|
|
7123
|
+
if (!schema.generatedAt || typeof schema.generatedAt !== "string") {
|
|
7124
|
+
throw new Error('Invalid schema JSON: missing or invalid "generatedAt" field');
|
|
7125
|
+
}
|
|
7126
|
+
for (const table of schema.tables) {
|
|
7127
|
+
validateTableJson(table);
|
|
7128
|
+
}
|
|
7129
|
+
}
|
|
7130
|
+
function validateTableJson(table) {
|
|
7131
|
+
if (!table || typeof table !== "object") {
|
|
7132
|
+
throw new Error("Invalid schema JSON: each table must be an object");
|
|
7133
|
+
}
|
|
7134
|
+
const record = table;
|
|
7135
|
+
if (!record.name || typeof record.name !== "string") {
|
|
7136
|
+
throw new Error('Invalid schema JSON: each table must have a "name" string');
|
|
7137
|
+
}
|
|
7138
|
+
if (!Array.isArray(record.columns)) {
|
|
7139
|
+
throw new Error(`Invalid schema JSON: table "${record.name}" missing "columns" array`);
|
|
7140
|
+
}
|
|
7141
|
+
if (!Array.isArray(record.primaryKey)) {
|
|
7142
|
+
throw new Error(`Invalid schema JSON: table "${record.name}" missing "primaryKey" array`);
|
|
7143
|
+
}
|
|
7144
|
+
}
|
|
7145
|
+
function sortedReplacer(_key, value) {
|
|
7146
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
7147
|
+
const record = value;
|
|
7148
|
+
const sorted = {};
|
|
7149
|
+
for (const key of Object.keys(record).sort()) {
|
|
7150
|
+
sorted[key] = record[key];
|
|
7151
|
+
}
|
|
7152
|
+
return sorted;
|
|
7153
|
+
}
|
|
7154
|
+
return value;
|
|
7146
7155
|
}
|
|
7147
7156
|
var relationalQuerySchema = zod.z.object({
|
|
7148
7157
|
sql: zod.z.string().describe("SQL query string to execute"),
|
|
@@ -7373,7 +7382,7 @@ function isSafeValidationError(error) {
|
|
|
7373
7382
|
}
|
|
7374
7383
|
|
|
7375
7384
|
// src/data/relational/tools/relational-select/executor.ts
|
|
7376
|
-
var
|
|
7385
|
+
var logger16 = core.createLogger("agentforge:tools:data:relational:select");
|
|
7377
7386
|
function toSelectQueryInput(input) {
|
|
7378
7387
|
return {
|
|
7379
7388
|
table: input.table,
|
|
@@ -7387,7 +7396,7 @@ function toSelectQueryInput(input) {
|
|
|
7387
7396
|
}
|
|
7388
7397
|
async function executeSelect(manager, input, context) {
|
|
7389
7398
|
const startTime = Date.now();
|
|
7390
|
-
|
|
7399
|
+
logger16.debug("Building SELECT query", {
|
|
7391
7400
|
vendor: input.vendor,
|
|
7392
7401
|
table: input.table,
|
|
7393
7402
|
hasWhere: !!input.where,
|
|
@@ -7405,7 +7414,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7405
7414
|
};
|
|
7406
7415
|
const streamInput = toSelectQueryInput(input);
|
|
7407
7416
|
if (input.streaming.benchmark) {
|
|
7408
|
-
|
|
7417
|
+
logger16.warn("Streaming benchmark enabled; SELECT will execute up to three times (result + benchmark regular + benchmark streaming).", {
|
|
7409
7418
|
vendor: input.vendor,
|
|
7410
7419
|
table: input.table,
|
|
7411
7420
|
chunkSize: streamOptions.chunkSize ?? DEFAULT_CHUNK_SIZE,
|
|
@@ -7416,7 +7425,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7416
7425
|
const streamResult = await executeStreamingSelect(executor, streamInput, streamOptions);
|
|
7417
7426
|
const benchmark = input.streaming.benchmark ? await benchmarkStreamingSelectMemory(executor, streamInput, streamOptions) : void 0;
|
|
7418
7427
|
const executionTime2 = Date.now() - startTime;
|
|
7419
|
-
|
|
7428
|
+
logger16.debug("Streaming SELECT query executed successfully", {
|
|
7420
7429
|
vendor: input.vendor,
|
|
7421
7430
|
table: input.table,
|
|
7422
7431
|
rowCount: streamResult.rowCount,
|
|
@@ -7445,7 +7454,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7445
7454
|
const executionTime = Date.now() - startTime;
|
|
7446
7455
|
const rows = Array.isArray(result) ? result : result.rows || [];
|
|
7447
7456
|
const rowCount = rows.length;
|
|
7448
|
-
|
|
7457
|
+
logger16.debug("SELECT query executed successfully", {
|
|
7449
7458
|
vendor: input.vendor,
|
|
7450
7459
|
table: input.table,
|
|
7451
7460
|
rowCount,
|
|
@@ -7458,7 +7467,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7458
7467
|
};
|
|
7459
7468
|
} catch (error) {
|
|
7460
7469
|
const executionTime = Date.now() - startTime;
|
|
7461
|
-
|
|
7470
|
+
logger16.error("SELECT query execution failed", {
|
|
7462
7471
|
vendor: input.vendor,
|
|
7463
7472
|
table: input.table,
|
|
7464
7473
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -9028,7 +9037,7 @@ function isSafeGetSchemaValidationError(error) {
|
|
|
9028
9037
|
}
|
|
9029
9038
|
|
|
9030
9039
|
// src/data/relational/tools/relational-get-schema.ts
|
|
9031
|
-
var
|
|
9040
|
+
var logger17 = core.createLogger("agentforge:tools:data:relational:get-schema");
|
|
9032
9041
|
function buildSchemaCacheKey(vendor, connectionString, database) {
|
|
9033
9042
|
const databaseScope = database ?? "default";
|
|
9034
9043
|
const connectionHash = crypto.createHash("sha256").update(connectionString).digest("hex");
|
|
@@ -9100,7 +9109,7 @@ var relationalGetSchema = core.toolBuilder().name("relational-get-schema").displ
|
|
|
9100
9109
|
summary
|
|
9101
9110
|
};
|
|
9102
9111
|
} catch (error) {
|
|
9103
|
-
|
|
9112
|
+
logger17.error("Schema introspection failed", {
|
|
9104
9113
|
vendor: input.vendor,
|
|
9105
9114
|
hasTablesFilter: Array.isArray(input.tables),
|
|
9106
9115
|
tablesFilterCount: input.tables?.length ?? 0,
|
|
@@ -10266,7 +10275,7 @@ var AskHumanInputSchema = zod.z.object({
|
|
|
10266
10275
|
suggestions: zod.z.array(zod.z.string()).optional().describe("Suggested responses for the human")
|
|
10267
10276
|
});
|
|
10268
10277
|
var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || core.LogLevel.INFO;
|
|
10269
|
-
var
|
|
10278
|
+
var logger18 = core.createLogger("agentforge:tools:agent:ask-human", { level: logLevel3 });
|
|
10270
10279
|
function isRecord2(value) {
|
|
10271
10280
|
return typeof value === "object" && value !== null;
|
|
10272
10281
|
}
|
|
@@ -10331,7 +10340,7 @@ function createAskHumanTool() {
|
|
|
10331
10340
|
suggestions: validatedInput.suggestions,
|
|
10332
10341
|
status: "pending"
|
|
10333
10342
|
};
|
|
10334
|
-
|
|
10343
|
+
logger18.debug("About to call interrupt()", {
|
|
10335
10344
|
humanRequest: {
|
|
10336
10345
|
id: humanRequest.id,
|
|
10337
10346
|
question: humanRequest.question,
|
|
@@ -10347,13 +10356,13 @@ function createAskHumanTool() {
|
|
|
10347
10356
|
let response;
|
|
10348
10357
|
try {
|
|
10349
10358
|
response = interrupt(humanRequest);
|
|
10350
|
-
|
|
10359
|
+
logger18.debug("interrupt() returned successfully", {
|
|
10351
10360
|
responseType: typeof response,
|
|
10352
10361
|
hasResponse: response != null,
|
|
10353
10362
|
...typeof response === "string" ? { responseLength: response.length } : {}
|
|
10354
10363
|
});
|
|
10355
10364
|
} catch (error) {
|
|
10356
|
-
|
|
10365
|
+
logger18.debug("interrupt() threw error (expected for GraphInterrupt)", {
|
|
10357
10366
|
...error && typeof error === "object" && "constructor" in error ? { errorType: error.constructor?.name } : {},
|
|
10358
10367
|
error: error instanceof Error ? error.message : String(error)
|
|
10359
10368
|
});
|