@agentforge/tools 0.16.43 → 0.16.45
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 +140 -133
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -41
- package/dist/index.d.ts +1 -41
- package/dist/index.js +140 -133
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -788,7 +788,7 @@ function getDefaultSlackClient() {
|
|
|
788
788
|
}
|
|
789
789
|
};
|
|
790
790
|
}
|
|
791
|
-
function createSendSlackMessageTool(getSlackClient,
|
|
791
|
+
function createSendSlackMessageTool(getSlackClient, logger24) {
|
|
792
792
|
return toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
|
|
793
793
|
"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."
|
|
794
794
|
).suggests(["get-slack-channels"]).schema(
|
|
@@ -797,7 +797,7 @@ function createSendSlackMessageTool(getSlackClient, logger23) {
|
|
|
797
797
|
message: z.string().describe("Message content to send")
|
|
798
798
|
})
|
|
799
799
|
).implementSafe(async ({ channel, message }) => {
|
|
800
|
-
|
|
800
|
+
logger24.info("send-slack-message called", { channel, messageLength: message.length });
|
|
801
801
|
try {
|
|
802
802
|
const { client: slack, config } = getSlackClient();
|
|
803
803
|
const result = await slack.chat.postMessage({
|
|
@@ -806,7 +806,7 @@ function createSendSlackMessageTool(getSlackClient, logger23) {
|
|
|
806
806
|
username: config.botName,
|
|
807
807
|
icon_emoji: config.botIcon
|
|
808
808
|
});
|
|
809
|
-
|
|
809
|
+
logger24.info("send-slack-message result", {
|
|
810
810
|
...result.channel ? { channel: result.channel } : {},
|
|
811
811
|
...result.ts ? { timestamp: result.ts } : {},
|
|
812
812
|
messageLength: message.length,
|
|
@@ -819,7 +819,7 @@ function createSendSlackMessageTool(getSlackClient, logger23) {
|
|
|
819
819
|
message_id: result.ts
|
|
820
820
|
};
|
|
821
821
|
} catch (error) {
|
|
822
|
-
|
|
822
|
+
logger24.error("send-slack-message failed", {
|
|
823
823
|
channel,
|
|
824
824
|
error: error.message,
|
|
825
825
|
data: error.data
|
|
@@ -828,7 +828,7 @@ function createSendSlackMessageTool(getSlackClient, logger23) {
|
|
|
828
828
|
}
|
|
829
829
|
}).build();
|
|
830
830
|
}
|
|
831
|
-
function createNotifySlackTool(getSlackClient,
|
|
831
|
+
function createNotifySlackTool(getSlackClient, logger24) {
|
|
832
832
|
return toolBuilder().name("notify-slack").description("Send a notification to a Slack channel with optional @mentions for urgent alerts").category(ToolCategory.WEB).tags(["slack", "notification", "alert"]).usageNotes(
|
|
833
833
|
"Use this for urgent notifications that require @mentions. For general messages without mentions, use send-slack-message instead."
|
|
834
834
|
).suggests(["get-slack-channels"]).schema(
|
|
@@ -838,7 +838,7 @@ function createNotifySlackTool(getSlackClient, logger23) {
|
|
|
838
838
|
mentions: z.array(z.string()).optional().describe("List of usernames to mention (without @)")
|
|
839
839
|
})
|
|
840
840
|
).implementSafe(async ({ channel, message, mentions = [] }) => {
|
|
841
|
-
|
|
841
|
+
logger24.info("notify-slack called", {
|
|
842
842
|
channel,
|
|
843
843
|
messageLength: message.length,
|
|
844
844
|
mentionCount: mentions.length
|
|
@@ -852,7 +852,7 @@ function createNotifySlackTool(getSlackClient, logger23) {
|
|
|
852
852
|
username: config.botName,
|
|
853
853
|
icon_emoji: config.botIcon
|
|
854
854
|
});
|
|
855
|
-
|
|
855
|
+
logger24.info("notify-slack result", {
|
|
856
856
|
...result.channel ? { channel: result.channel } : {},
|
|
857
857
|
...result.ts ? { timestamp: result.ts } : {},
|
|
858
858
|
mentions: mentions.length
|
|
@@ -866,7 +866,7 @@ function createNotifySlackTool(getSlackClient, logger23) {
|
|
|
866
866
|
};
|
|
867
867
|
}).build();
|
|
868
868
|
}
|
|
869
|
-
function createGetSlackChannelsTool(getSlackClient,
|
|
869
|
+
function createGetSlackChannelsTool(getSlackClient, logger24) {
|
|
870
870
|
return toolBuilder().name("get-slack-channels").description("Get a list of available Slack channels to find the right channel for messaging").category(ToolCategory.WEB).tags(["slack", "channels", "list"]).usageNotes(
|
|
871
871
|
"Use this first to discover available channels before sending messages. Helps ensure you are sending to the correct channel."
|
|
872
872
|
).follows(["send-slack-message", "notify-slack"]).schema(
|
|
@@ -874,7 +874,7 @@ function createGetSlackChannelsTool(getSlackClient, logger23) {
|
|
|
874
874
|
include_private: z.boolean().optional().describe("Include private channels (default: false)")
|
|
875
875
|
})
|
|
876
876
|
).implementSafe(async ({ include_private = false }) => {
|
|
877
|
-
|
|
877
|
+
logger24.info("get-slack-channels called", { include_private });
|
|
878
878
|
const { client: slack } = getSlackClient();
|
|
879
879
|
const publicChannels = await slack.conversations.list({
|
|
880
880
|
types: "public_channel",
|
|
@@ -888,7 +888,7 @@ function createGetSlackChannelsTool(getSlackClient, logger23) {
|
|
|
888
888
|
});
|
|
889
889
|
allChannels = [...allChannels, ...privateChannels.channels || []];
|
|
890
890
|
}
|
|
891
|
-
|
|
891
|
+
logger24.info("get-slack-channels result", {
|
|
892
892
|
channelCount: allChannels.length,
|
|
893
893
|
includePrivate: include_private
|
|
894
894
|
});
|
|
@@ -903,7 +903,7 @@ function createGetSlackChannelsTool(getSlackClient, logger23) {
|
|
|
903
903
|
};
|
|
904
904
|
}).build();
|
|
905
905
|
}
|
|
906
|
-
function createGetSlackMessagesTool(getSlackClient,
|
|
906
|
+
function createGetSlackMessagesTool(getSlackClient, logger24) {
|
|
907
907
|
return toolBuilder().name("get-slack-messages").description("Retrieve message history from a Slack channel to read recent conversations").category(ToolCategory.WEB).tags(["slack", "messages", "history", "read"]).usageNotes(
|
|
908
908
|
"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)."
|
|
909
909
|
).suggests(["get-slack-channels"]).schema(
|
|
@@ -912,7 +912,7 @@ function createGetSlackMessagesTool(getSlackClient, logger23) {
|
|
|
912
912
|
limit: z.number().int().min(1).max(100).optional().describe("Number of messages to retrieve (default: 20, max: 100)")
|
|
913
913
|
})
|
|
914
914
|
).implementSafe(async ({ channel, limit = 20 }) => {
|
|
915
|
-
|
|
915
|
+
logger24.info("get-slack-messages called", { channel, limit });
|
|
916
916
|
try {
|
|
917
917
|
const { client: slack } = getSlackClient();
|
|
918
918
|
let channelId = channel;
|
|
@@ -923,7 +923,7 @@ function createGetSlackMessagesTool(getSlackClient, logger23) {
|
|
|
923
923
|
});
|
|
924
924
|
const found = channels.channels?.find((c) => c.name === channel);
|
|
925
925
|
if (!found) {
|
|
926
|
-
|
|
926
|
+
logger24.error("get-slack-messages: channel not found", { channel });
|
|
927
927
|
throw new Error(
|
|
928
928
|
`Channel '${channel}' not found. Use get-slack-channels to see available channels.`
|
|
929
929
|
);
|
|
@@ -935,7 +935,7 @@ function createGetSlackMessagesTool(getSlackClient, logger23) {
|
|
|
935
935
|
limit: Math.min(limit, 100)
|
|
936
936
|
// Cap at 100 for performance
|
|
937
937
|
});
|
|
938
|
-
|
|
938
|
+
logger24.info("get-slack-messages result", {
|
|
939
939
|
channel: channelId,
|
|
940
940
|
messageCount: result.messages?.length || 0,
|
|
941
941
|
limit
|
|
@@ -953,7 +953,7 @@ function createGetSlackMessagesTool(getSlackClient, logger23) {
|
|
|
953
953
|
})) || []
|
|
954
954
|
};
|
|
955
955
|
} catch (error) {
|
|
956
|
-
|
|
956
|
+
logger24.error("get-slack-messages failed", {
|
|
957
957
|
channel,
|
|
958
958
|
error: error.message,
|
|
959
959
|
data: error.data
|
|
@@ -1034,12 +1034,12 @@ function getAuthHeader() {
|
|
|
1034
1034
|
const auth2 = Buffer.from(`${ATLASSIAN_EMAIL}:${ATLASSIAN_API_KEY}`).toString("base64");
|
|
1035
1035
|
return `Basic ${auth2}`;
|
|
1036
1036
|
}
|
|
1037
|
-
function createSearchConfluenceTool(getAuth, getAuthHeader2,
|
|
1037
|
+
function createSearchConfluenceTool(getAuth, getAuthHeader2, logger24) {
|
|
1038
1038
|
return 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(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(z.object({
|
|
1039
1039
|
query: z.string().describe("Search query or CQL expression (e.g., 'payment processing' or 'space=BL3 AND title~payment')"),
|
|
1040
1040
|
limit: z.number().optional().describe("Maximum number of results to return (default: 10, max: 25)")
|
|
1041
1041
|
})).implement(async ({ query, limit = 10 }) => {
|
|
1042
|
-
|
|
1042
|
+
logger24.info("search-confluence called", { query, limit });
|
|
1043
1043
|
try {
|
|
1044
1044
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1045
1045
|
const response = await axios16.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/search`, {
|
|
@@ -1064,13 +1064,13 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1064
1064
|
lastModified: page.version?.when || ""
|
|
1065
1065
|
}));
|
|
1066
1066
|
if (results.length === 0) {
|
|
1067
|
-
|
|
1067
|
+
logger24.warn("search-confluence returned NO RESULTS - this is a valid outcome, agent should not retry", {
|
|
1068
1068
|
query,
|
|
1069
1069
|
limit,
|
|
1070
1070
|
totalSize: response.data.totalSize
|
|
1071
1071
|
});
|
|
1072
1072
|
} else {
|
|
1073
|
-
|
|
1073
|
+
logger24.info("search-confluence result", {
|
|
1074
1074
|
query,
|
|
1075
1075
|
resultCount: results.length,
|
|
1076
1076
|
totalSize: response.data.totalSize,
|
|
@@ -1085,7 +1085,7 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1085
1085
|
results
|
|
1086
1086
|
});
|
|
1087
1087
|
} catch (error) {
|
|
1088
|
-
|
|
1088
|
+
logger24.error("search-confluence error", {
|
|
1089
1089
|
query,
|
|
1090
1090
|
error: error.response?.data?.message || error.message,
|
|
1091
1091
|
status: error.response?.status
|
|
@@ -1097,11 +1097,11 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1097
1097
|
}
|
|
1098
1098
|
}).build();
|
|
1099
1099
|
}
|
|
1100
|
-
function createGetConfluencePageTool(getAuth, getAuthHeader2,
|
|
1100
|
+
function createGetConfluencePageTool(getAuth, getAuthHeader2, logger24) {
|
|
1101
1101
|
return 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(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(z.object({
|
|
1102
1102
|
page_id: z.string().describe("The Confluence page ID (from search results)")
|
|
1103
1103
|
})).implement(async ({ page_id }) => {
|
|
1104
|
-
|
|
1104
|
+
logger24.info("get-confluence-page called", { page_id });
|
|
1105
1105
|
try {
|
|
1106
1106
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1107
1107
|
const response = await axios16.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`, {
|
|
@@ -1114,7 +1114,7 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1114
1114
|
}
|
|
1115
1115
|
});
|
|
1116
1116
|
const page = response.data;
|
|
1117
|
-
|
|
1117
|
+
logger24.info("get-confluence-page result", {
|
|
1118
1118
|
page_id,
|
|
1119
1119
|
title: page.title,
|
|
1120
1120
|
space: page.space?.name,
|
|
@@ -1136,7 +1136,7 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1136
1136
|
}
|
|
1137
1137
|
});
|
|
1138
1138
|
} catch (error) {
|
|
1139
|
-
|
|
1139
|
+
logger24.error("get-confluence-page error", {
|
|
1140
1140
|
page_id,
|
|
1141
1141
|
error: error.response?.data?.message || error.message,
|
|
1142
1142
|
status: error.response?.status
|
|
@@ -1148,11 +1148,11 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1148
1148
|
}
|
|
1149
1149
|
}).build();
|
|
1150
1150
|
}
|
|
1151
|
-
function createListConfluenceSpacesTool(getAuth, getAuthHeader2,
|
|
1151
|
+
function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger24) {
|
|
1152
1152
|
return 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(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(z.object({
|
|
1153
1153
|
limit: z.number().optional().describe("Maximum number of spaces to return (default: 25)")
|
|
1154
1154
|
})).implement(async ({ limit = 25 }) => {
|
|
1155
|
-
|
|
1155
|
+
logger24.info("list-confluence-spaces called", { limit });
|
|
1156
1156
|
try {
|
|
1157
1157
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1158
1158
|
const response = await axios16.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/space`, {
|
|
@@ -1171,7 +1171,7 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1171
1171
|
description: space.description?.plain?.value || "",
|
|
1172
1172
|
url: `${ATLASSIAN_SITE_URL}/wiki${space._links.webui}`
|
|
1173
1173
|
}));
|
|
1174
|
-
|
|
1174
|
+
logger24.info("list-confluence-spaces result", {
|
|
1175
1175
|
spaceCount: spaces.length,
|
|
1176
1176
|
spaceKeys: spaces.map((s) => s.key).slice(0, 5)
|
|
1177
1177
|
// Log first 5 space keys
|
|
@@ -1182,7 +1182,7 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1182
1182
|
spaces
|
|
1183
1183
|
});
|
|
1184
1184
|
} catch (error) {
|
|
1185
|
-
|
|
1185
|
+
logger24.error("list-confluence-spaces error", {
|
|
1186
1186
|
error: error.response?.data?.message || error.message,
|
|
1187
1187
|
status: error.response?.status
|
|
1188
1188
|
});
|
|
@@ -1193,12 +1193,12 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1193
1193
|
}
|
|
1194
1194
|
}).build();
|
|
1195
1195
|
}
|
|
1196
|
-
function createGetSpacePagesTool(getAuth, getAuthHeader2,
|
|
1196
|
+
function createGetSpacePagesTool(getAuth, getAuthHeader2, logger24) {
|
|
1197
1197
|
return 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(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(z.object({
|
|
1198
1198
|
space_key: z.string().describe("The space key (e.g., 'AI', 'BL3', 'FIN')"),
|
|
1199
1199
|
limit: z.number().optional().describe("Maximum number of pages to return (default: 25)")
|
|
1200
1200
|
})).implement(async ({ space_key, limit = 25 }) => {
|
|
1201
|
-
|
|
1201
|
+
logger24.info("get-space-pages called", { space_key, limit });
|
|
1202
1202
|
try {
|
|
1203
1203
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1204
1204
|
const response = await axios16.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`, {
|
|
@@ -1220,12 +1220,12 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1220
1220
|
lastModified: page.version?.when || ""
|
|
1221
1221
|
}));
|
|
1222
1222
|
if (pages.length === 0) {
|
|
1223
|
-
|
|
1223
|
+
logger24.warn("get-space-pages returned NO PAGES - this is a valid outcome, agent should not retry", {
|
|
1224
1224
|
space_key,
|
|
1225
1225
|
limit
|
|
1226
1226
|
});
|
|
1227
1227
|
} else {
|
|
1228
|
-
|
|
1228
|
+
logger24.info("get-space-pages result", {
|
|
1229
1229
|
space_key,
|
|
1230
1230
|
pageCount: pages.length,
|
|
1231
1231
|
titles: pages.map((p) => p.title).slice(0, 3)
|
|
@@ -1239,7 +1239,7 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1239
1239
|
pages
|
|
1240
1240
|
});
|
|
1241
1241
|
} catch (error) {
|
|
1242
|
-
|
|
1242
|
+
logger24.error("get-space-pages error", {
|
|
1243
1243
|
space_key,
|
|
1244
1244
|
error: error.response?.data?.message || error.message,
|
|
1245
1245
|
status: error.response?.status
|
|
@@ -1251,14 +1251,14 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1251
1251
|
}
|
|
1252
1252
|
}).build();
|
|
1253
1253
|
}
|
|
1254
|
-
function createCreateConfluencePageTool(getAuth, getAuthHeader2,
|
|
1254
|
+
function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger24) {
|
|
1255
1255
|
return 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(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(z.object({
|
|
1256
1256
|
space_key: z.string().describe("The space key where the page will be created (e.g., 'AI', 'BL3')"),
|
|
1257
1257
|
title: z.string().describe("The title of the new page"),
|
|
1258
1258
|
content: z.string().describe("The page content in HTML format (Confluence storage format)"),
|
|
1259
1259
|
parent_page_id: z.string().optional().describe("Optional parent page ID to create this as a child page")
|
|
1260
1260
|
})).implement(async ({ space_key, title, content, parent_page_id }) => {
|
|
1261
|
-
|
|
1261
|
+
logger24.info("create-confluence-page called", { space_key, title, hasParent: !!parent_page_id });
|
|
1262
1262
|
try {
|
|
1263
1263
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1264
1264
|
const pageData = {
|
|
@@ -1285,7 +1285,7 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1285
1285
|
}
|
|
1286
1286
|
}
|
|
1287
1287
|
);
|
|
1288
|
-
|
|
1288
|
+
logger24.info("create-confluence-page result", {
|
|
1289
1289
|
page_id: response.data.id,
|
|
1290
1290
|
title: response.data.title,
|
|
1291
1291
|
space: space_key
|
|
@@ -1301,7 +1301,7 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1301
1301
|
}
|
|
1302
1302
|
});
|
|
1303
1303
|
} catch (error) {
|
|
1304
|
-
|
|
1304
|
+
logger24.error("create-confluence-page error", {
|
|
1305
1305
|
space_key,
|
|
1306
1306
|
title,
|
|
1307
1307
|
error: error.response?.data?.message || error.message,
|
|
@@ -1314,13 +1314,13 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1314
1314
|
}
|
|
1315
1315
|
}).build();
|
|
1316
1316
|
}
|
|
1317
|
-
function createUpdateConfluencePageTool(getAuth, getAuthHeader2,
|
|
1317
|
+
function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger24) {
|
|
1318
1318
|
return toolBuilder().name("update-confluence-page").description("Update an existing Confluence page's content. Requires page ID, new title, and new content.").category(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(z.object({
|
|
1319
1319
|
page_id: z.string().describe("The ID of the page to update"),
|
|
1320
1320
|
title: z.string().describe("The new title for the page"),
|
|
1321
1321
|
content: z.string().describe("The new content in HTML format (Confluence storage format)")
|
|
1322
1322
|
})).implement(async ({ page_id, title, content }) => {
|
|
1323
|
-
|
|
1323
|
+
logger24.info("update-confluence-page called", { page_id, title });
|
|
1324
1324
|
try {
|
|
1325
1325
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1326
1326
|
const getResponse = await axios16.get(
|
|
@@ -1353,7 +1353,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1353
1353
|
}
|
|
1354
1354
|
}
|
|
1355
1355
|
);
|
|
1356
|
-
|
|
1356
|
+
logger24.info("update-confluence-page result", {
|
|
1357
1357
|
page_id,
|
|
1358
1358
|
title: updateResponse.data.title,
|
|
1359
1359
|
previousVersion: currentVersion,
|
|
@@ -1370,7 +1370,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1370
1370
|
}
|
|
1371
1371
|
});
|
|
1372
1372
|
} catch (error) {
|
|
1373
|
-
|
|
1373
|
+
logger24.error("update-confluence-page error", {
|
|
1374
1374
|
page_id,
|
|
1375
1375
|
title,
|
|
1376
1376
|
error: error.response?.data?.message || error.message,
|
|
@@ -1383,12 +1383,12 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1383
1383
|
}
|
|
1384
1384
|
}).build();
|
|
1385
1385
|
}
|
|
1386
|
-
function createArchiveConfluencePageTool(getAuth, getAuthHeader2,
|
|
1386
|
+
function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger24) {
|
|
1387
1387
|
return 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(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(z.object({
|
|
1388
1388
|
page_id: z.string().describe("The ID of the page to archive"),
|
|
1389
1389
|
reason: z.string().optional().describe("Optional reason for archiving (for audit trail)")
|
|
1390
1390
|
})).implement(async ({ page_id, reason }) => {
|
|
1391
|
-
|
|
1391
|
+
logger24.info("archive-confluence-page called", {
|
|
1392
1392
|
page_id,
|
|
1393
1393
|
...reason ? { reason } : {}
|
|
1394
1394
|
});
|
|
@@ -1422,7 +1422,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1422
1422
|
}
|
|
1423
1423
|
}
|
|
1424
1424
|
);
|
|
1425
|
-
|
|
1425
|
+
logger24.info("archive-confluence-page result", {
|
|
1426
1426
|
page_id,
|
|
1427
1427
|
title: pageData.title,
|
|
1428
1428
|
previousVersion: currentVersion,
|
|
@@ -1440,7 +1440,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
|
1440
1440
|
}
|
|
1441
1441
|
});
|
|
1442
1442
|
} catch (error) {
|
|
1443
|
-
|
|
1443
|
+
logger24.error("archive-confluence-page error", {
|
|
1444
1444
|
page_id,
|
|
1445
1445
|
error: error.response?.data?.message || error.message,
|
|
1446
1446
|
status: error.response?.status
|
|
@@ -4121,19 +4121,19 @@ var ConnectionState = /* @__PURE__ */ ((ConnectionState2) => {
|
|
|
4121
4121
|
ConnectionState2["ERROR"] = "error";
|
|
4122
4122
|
return ConnectionState2;
|
|
4123
4123
|
})(ConnectionState || {});
|
|
4124
|
-
function cancelPendingReconnection(timer,
|
|
4124
|
+
function cancelPendingReconnection(timer, logger24, vendor, message) {
|
|
4125
4125
|
if (!timer) {
|
|
4126
4126
|
return null;
|
|
4127
4127
|
}
|
|
4128
|
-
|
|
4128
|
+
logger24.debug(message, { vendor });
|
|
4129
4129
|
clearTimeout(timer);
|
|
4130
4130
|
return null;
|
|
4131
4131
|
}
|
|
4132
|
-
async function waitForInFlightConnection(promise,
|
|
4132
|
+
async function waitForInFlightConnection(promise, logger24, vendor, phase) {
|
|
4133
4133
|
if (!promise) {
|
|
4134
4134
|
return null;
|
|
4135
4135
|
}
|
|
4136
|
-
|
|
4136
|
+
logger24.debug(`Waiting for in-flight connection attempt to complete before ${phase}`, {
|
|
4137
4137
|
vendor
|
|
4138
4138
|
});
|
|
4139
4139
|
try {
|
|
@@ -4150,9 +4150,9 @@ function shutdownClient(vendor, client) {
|
|
|
4150
4150
|
client.close();
|
|
4151
4151
|
}
|
|
4152
4152
|
}
|
|
4153
|
-
function scheduleReconnection(context,
|
|
4153
|
+
function scheduleReconnection(context, logger24) {
|
|
4154
4154
|
if (context.reconnectionConfig.maxAttempts > 0 && context.reconnectionAttempts >= context.reconnectionConfig.maxAttempts) {
|
|
4155
|
-
|
|
4155
|
+
logger24.error("Max reconnection attempts reached", {
|
|
4156
4156
|
vendor: context.vendor,
|
|
4157
4157
|
attempts: context.reconnectionAttempts,
|
|
4158
4158
|
maxAttempts: context.reconnectionConfig.maxAttempts
|
|
@@ -4166,7 +4166,7 @@ function scheduleReconnection(context, logger23) {
|
|
|
4166
4166
|
const nextAttempt = context.reconnectionAttempts + 1;
|
|
4167
4167
|
context.setReconnectionAttempts(nextAttempt);
|
|
4168
4168
|
context.setState("reconnecting" /* RECONNECTING */);
|
|
4169
|
-
|
|
4169
|
+
logger24.info("Scheduling reconnection attempt", {
|
|
4170
4170
|
vendor: context.vendor,
|
|
4171
4171
|
attempt: nextAttempt,
|
|
4172
4172
|
maxAttempts: context.reconnectionConfig.maxAttempts,
|
|
@@ -4180,7 +4180,7 @@ function scheduleReconnection(context, logger23) {
|
|
|
4180
4180
|
const timer = setTimeout(async () => {
|
|
4181
4181
|
context.setReconnectionTimer(null);
|
|
4182
4182
|
try {
|
|
4183
|
-
|
|
4183
|
+
logger24.info("Attempting reconnection", {
|
|
4184
4184
|
vendor: context.vendor,
|
|
4185
4185
|
attempt: nextAttempt
|
|
4186
4186
|
});
|
|
@@ -4190,7 +4190,7 @@ function scheduleReconnection(context, logger23) {
|
|
|
4190
4190
|
context.setConnectPromise(promise);
|
|
4191
4191
|
await promise;
|
|
4192
4192
|
} catch (error) {
|
|
4193
|
-
|
|
4193
|
+
logger24.error("Reconnection attempt failed", {
|
|
4194
4194
|
vendor: context.vendor,
|
|
4195
4195
|
attempt: nextAttempt,
|
|
4196
4196
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -4201,17 +4201,17 @@ function scheduleReconnection(context, logger23) {
|
|
|
4201
4201
|
}
|
|
4202
4202
|
|
|
4203
4203
|
// src/data/relational/connection/connection-cleanup.ts
|
|
4204
|
-
async function cleanupConnectionResources(vendor, client, clearConnection,
|
|
4204
|
+
async function cleanupConnectionResources(vendor, client, clearConnection, logger24) {
|
|
4205
4205
|
if (!client) {
|
|
4206
4206
|
return;
|
|
4207
4207
|
}
|
|
4208
|
-
|
|
4208
|
+
logger24.debug("Cleaning up cancelled connection", {
|
|
4209
4209
|
vendor
|
|
4210
4210
|
});
|
|
4211
4211
|
try {
|
|
4212
4212
|
await shutdownClient(vendor, client);
|
|
4213
4213
|
} catch (error) {
|
|
4214
|
-
|
|
4214
|
+
logger24.debug("Error during cancelled connection cleanup", {
|
|
4215
4215
|
vendor,
|
|
4216
4216
|
error: error instanceof Error ? error.message : String(error)
|
|
4217
4217
|
});
|
|
@@ -4219,10 +4219,10 @@ async function cleanupConnectionResources(vendor, client, clearConnection, logge
|
|
|
4219
4219
|
clearConnection();
|
|
4220
4220
|
}
|
|
4221
4221
|
}
|
|
4222
|
-
async function closeManagedConnection(runtime,
|
|
4222
|
+
async function closeManagedConnection(runtime, logger24) {
|
|
4223
4223
|
const client = runtime.getClient();
|
|
4224
4224
|
if (client) {
|
|
4225
|
-
|
|
4225
|
+
logger24.info("Closing database connection", {
|
|
4226
4226
|
vendor: runtime.vendor,
|
|
4227
4227
|
state: runtime.getState()
|
|
4228
4228
|
});
|
|
@@ -4230,12 +4230,12 @@ async function closeManagedConnection(runtime, logger23) {
|
|
|
4230
4230
|
await shutdownClient(runtime.vendor, client);
|
|
4231
4231
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4232
4232
|
runtime.emitDisconnected();
|
|
4233
|
-
|
|
4233
|
+
logger24.debug("Database connection closed successfully", {
|
|
4234
4234
|
vendor: runtime.vendor,
|
|
4235
4235
|
state: runtime.getState()
|
|
4236
4236
|
});
|
|
4237
4237
|
} catch (error) {
|
|
4238
|
-
|
|
4238
|
+
logger24.error("Error closing database connection", {
|
|
4239
4239
|
vendor: runtime.vendor,
|
|
4240
4240
|
error: error instanceof Error ? error.message : String(error),
|
|
4241
4241
|
state: runtime.getState()
|
|
@@ -4408,11 +4408,11 @@ async function initializeSQLiteConnection(connection) {
|
|
|
4408
4408
|
}
|
|
4409
4409
|
|
|
4410
4410
|
// src/data/relational/connection/connection-initialization.ts
|
|
4411
|
-
async function initializeManagedConnection(runtime,
|
|
4411
|
+
async function initializeManagedConnection(runtime, logger24) {
|
|
4412
4412
|
const startTime = Date.now();
|
|
4413
4413
|
const currentGeneration = runtime.getConnectionGeneration();
|
|
4414
4414
|
if (runtime.getState() === "connected" /* CONNECTED */ && runtime.getClient()) {
|
|
4415
|
-
|
|
4415
|
+
logger24.warn("Re-initializing an already connected manager; emitting disconnected before cleanup", {
|
|
4416
4416
|
vendor: runtime.vendor
|
|
4417
4417
|
});
|
|
4418
4418
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
@@ -4424,11 +4424,11 @@ async function initializeManagedConnection(runtime, logger23) {
|
|
|
4424
4424
|
runtime.setClient(null);
|
|
4425
4425
|
runtime.setDb(null);
|
|
4426
4426
|
},
|
|
4427
|
-
|
|
4427
|
+
logger24
|
|
4428
4428
|
);
|
|
4429
4429
|
}
|
|
4430
4430
|
runtime.setState("connecting" /* CONNECTING */);
|
|
4431
|
-
|
|
4431
|
+
logger24.info("Initializing database connection", {
|
|
4432
4432
|
vendor: runtime.vendor,
|
|
4433
4433
|
connectionType: typeof runtime.config.connection,
|
|
4434
4434
|
state: runtime.getState()
|
|
@@ -4438,7 +4438,7 @@ async function initializeManagedConnection(runtime, logger23) {
|
|
|
4438
4438
|
runtime.setClient(initialized.client);
|
|
4439
4439
|
runtime.setDb(initialized.db);
|
|
4440
4440
|
if (currentGeneration !== runtime.getConnectionGeneration()) {
|
|
4441
|
-
|
|
4441
|
+
logger24.debug("Connection cancelled during initialization", {
|
|
4442
4442
|
vendor: runtime.vendor,
|
|
4443
4443
|
currentGeneration,
|
|
4444
4444
|
newGeneration: runtime.getConnectionGeneration()
|
|
@@ -4450,18 +4450,18 @@ async function initializeManagedConnection(runtime, logger23) {
|
|
|
4450
4450
|
runtime.setClient(null);
|
|
4451
4451
|
runtime.setDb(null);
|
|
4452
4452
|
},
|
|
4453
|
-
|
|
4453
|
+
logger24
|
|
4454
4454
|
);
|
|
4455
4455
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4456
4456
|
throw new Error("Connection cancelled during initialization");
|
|
4457
4457
|
}
|
|
4458
|
-
|
|
4458
|
+
logger24.debug("Validating connection health", { vendor: runtime.vendor });
|
|
4459
4459
|
const healthy = await runtime.isHealthy();
|
|
4460
4460
|
if (!healthy) {
|
|
4461
4461
|
throw new Error(`Failed to establish healthy connection to ${runtime.vendor} database`);
|
|
4462
4462
|
}
|
|
4463
4463
|
if (currentGeneration !== runtime.getConnectionGeneration()) {
|
|
4464
|
-
|
|
4464
|
+
logger24.debug("Connection cancelled during health check", {
|
|
4465
4465
|
vendor: runtime.vendor,
|
|
4466
4466
|
currentGeneration,
|
|
4467
4467
|
newGeneration: runtime.getConnectionGeneration()
|
|
@@ -4473,7 +4473,7 @@ async function initializeManagedConnection(runtime, logger23) {
|
|
|
4473
4473
|
runtime.setClient(null);
|
|
4474
4474
|
runtime.setDb(null);
|
|
4475
4475
|
},
|
|
4476
|
-
|
|
4476
|
+
logger24
|
|
4477
4477
|
);
|
|
4478
4478
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4479
4479
|
throw new Error("Connection cancelled during health check");
|
|
@@ -4481,7 +4481,7 @@ async function initializeManagedConnection(runtime, logger23) {
|
|
|
4481
4481
|
runtime.setState("connected" /* CONNECTED */);
|
|
4482
4482
|
runtime.emitConnected();
|
|
4483
4483
|
runtime.resetReconnectionAttempts();
|
|
4484
|
-
|
|
4484
|
+
logger24.info("Database connection initialized successfully", {
|
|
4485
4485
|
vendor: runtime.vendor,
|
|
4486
4486
|
duration: Date.now() - startTime,
|
|
4487
4487
|
state: runtime.getState()
|
|
@@ -4502,7 +4502,7 @@ async function initializeManagedConnection(runtime, logger23) {
|
|
|
4502
4502
|
if (runtime.errorListenerCount() > 0) {
|
|
4503
4503
|
runtime.emitError(normalizedError);
|
|
4504
4504
|
}
|
|
4505
|
-
|
|
4505
|
+
logger24.error(errorMessage, {
|
|
4506
4506
|
vendor: runtime.vendor,
|
|
4507
4507
|
error: normalizedError.message,
|
|
4508
4508
|
duration: Date.now() - startTime,
|
|
@@ -4515,13 +4515,13 @@ async function initializeManagedConnection(runtime, logger23) {
|
|
|
4515
4515
|
runtime.setClient(null);
|
|
4516
4516
|
runtime.setDb(null);
|
|
4517
4517
|
},
|
|
4518
|
-
|
|
4518
|
+
logger24
|
|
4519
4519
|
);
|
|
4520
4520
|
if (runtime.getReconnectionConfig().enabled && currentGeneration === runtime.getConnectionGeneration()) {
|
|
4521
4521
|
runtime.scheduleReconnection();
|
|
4522
4522
|
}
|
|
4523
4523
|
} else {
|
|
4524
|
-
|
|
4524
|
+
logger24.debug("Connection initialization cancelled", {
|
|
4525
4525
|
vendor: runtime.vendor,
|
|
4526
4526
|
duration: Date.now() - startTime,
|
|
4527
4527
|
state: runtime.getState()
|
|
@@ -4539,17 +4539,17 @@ function isSqliteNonQueryError(error) {
|
|
|
4539
4539
|
const hasNonQueryMessage = error.message.includes("does not return data");
|
|
4540
4540
|
return isSqliteOrTypeError && hasNonQueryMessage;
|
|
4541
4541
|
}
|
|
4542
|
-
async function checkConnectionHealth(args,
|
|
4542
|
+
async function checkConnectionHealth(args, logger24) {
|
|
4543
4543
|
if (!args.db || !args.client) {
|
|
4544
|
-
|
|
4544
|
+
logger24.debug("Health check failed: connection not initialized", { vendor: args.vendor });
|
|
4545
4545
|
return false;
|
|
4546
4546
|
}
|
|
4547
4547
|
try {
|
|
4548
4548
|
await args.execute(sql`SELECT 1`);
|
|
4549
|
-
|
|
4549
|
+
logger24.debug("Health check passed", { vendor: args.vendor });
|
|
4550
4550
|
return true;
|
|
4551
4551
|
} catch (error) {
|
|
4552
|
-
|
|
4552
|
+
logger24.debug("Health check failed", {
|
|
4553
4553
|
vendor: args.vendor,
|
|
4554
4554
|
error: error instanceof Error ? error.message : String(error)
|
|
4555
4555
|
});
|
|
@@ -4592,8 +4592,8 @@ function getConnectionPoolMetrics(vendor, client) {
|
|
|
4592
4592
|
}
|
|
4593
4593
|
|
|
4594
4594
|
// src/data/relational/connection/query-execution.ts
|
|
4595
|
-
async function executeQuery(context, query,
|
|
4596
|
-
|
|
4595
|
+
async function executeQuery(context, query, logger24) {
|
|
4596
|
+
logger24.debug("Executing SQL query", {
|
|
4597
4597
|
vendor: context.vendor
|
|
4598
4598
|
});
|
|
4599
4599
|
if (context.vendor === "sqlite") {
|
|
@@ -5762,9 +5762,8 @@ async function benchmarkStreamingSelectMemory(executor, input, options = {}) {
|
|
|
5762
5762
|
memorySavedPercent
|
|
5763
5763
|
};
|
|
5764
5764
|
}
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
var SAVEPOINT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
5765
|
+
|
|
5766
|
+
// src/data/relational/query/transaction-options.ts
|
|
5768
5767
|
function toSqlIsolationLevel(level) {
|
|
5769
5768
|
switch (level) {
|
|
5770
5769
|
case "read uncommitted":
|
|
@@ -5777,7 +5776,7 @@ function toSqlIsolationLevel(level) {
|
|
|
5777
5776
|
return "SERIALIZABLE";
|
|
5778
5777
|
}
|
|
5779
5778
|
}
|
|
5780
|
-
function
|
|
5779
|
+
function resolveTransactionOptions(options) {
|
|
5781
5780
|
if (!options) {
|
|
5782
5781
|
return {};
|
|
5783
5782
|
}
|
|
@@ -5789,7 +5788,7 @@ function resolveOptions2(options) {
|
|
|
5789
5788
|
timeoutMs: options.timeoutMs
|
|
5790
5789
|
};
|
|
5791
5790
|
}
|
|
5792
|
-
function
|
|
5791
|
+
function withTransactionTimeout(operation, timeoutMs, onTimeout) {
|
|
5793
5792
|
if (!timeoutMs) {
|
|
5794
5793
|
return operation;
|
|
5795
5794
|
}
|
|
@@ -5815,6 +5814,10 @@ function withTimeout(operation, timeoutMs, onTimeout) {
|
|
|
5815
5814
|
});
|
|
5816
5815
|
});
|
|
5817
5816
|
}
|
|
5817
|
+
|
|
5818
|
+
// src/data/relational/query/transaction-managed.ts
|
|
5819
|
+
var logger12 = createLogger("agentforge:tools:data:relational:transaction");
|
|
5820
|
+
var SAVEPOINT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
5818
5821
|
var ManagedTransaction = class {
|
|
5819
5822
|
id;
|
|
5820
5823
|
vendor;
|
|
@@ -5970,12 +5973,16 @@ var ManagedTransaction = class {
|
|
|
5970
5973
|
return null;
|
|
5971
5974
|
}
|
|
5972
5975
|
};
|
|
5976
|
+
|
|
5977
|
+
// src/data/relational/query/transaction-runner.ts
|
|
5978
|
+
var logger13 = createLogger("agentforge:tools:data:relational:transaction");
|
|
5979
|
+
var transactionSequence = 0;
|
|
5973
5980
|
async function withTransaction(manager, operation, options) {
|
|
5974
5981
|
const startTime = Date.now();
|
|
5975
|
-
const resolvedOptions =
|
|
5982
|
+
const resolvedOptions = resolveTransactionOptions(options);
|
|
5976
5983
|
const transactionId = `tx-${++transactionSequence}`;
|
|
5977
5984
|
const vendor = manager.getVendor();
|
|
5978
|
-
|
|
5985
|
+
logger13.debug("Starting transaction", {
|
|
5979
5986
|
transactionId,
|
|
5980
5987
|
vendor,
|
|
5981
5988
|
...resolvedOptions.isolationLevel ? { isolationLevel: resolvedOptions.isolationLevel } : {},
|
|
@@ -5990,7 +5997,7 @@ async function withTransaction(manager, operation, options) {
|
|
|
5990
5997
|
});
|
|
5991
5998
|
await transaction.begin();
|
|
5992
5999
|
try {
|
|
5993
|
-
const result = await
|
|
6000
|
+
const result = await withTransactionTimeout(
|
|
5994
6001
|
operation(transaction),
|
|
5995
6002
|
resolvedOptions.timeoutMs,
|
|
5996
6003
|
() => {
|
|
@@ -6002,7 +6009,7 @@ async function withTransaction(manager, operation, options) {
|
|
|
6002
6009
|
if (transaction.isActive()) {
|
|
6003
6010
|
await transaction.commit();
|
|
6004
6011
|
}
|
|
6005
|
-
|
|
6012
|
+
logger13.debug("Transaction committed", {
|
|
6006
6013
|
transactionId,
|
|
6007
6014
|
vendor,
|
|
6008
6015
|
duration: Date.now() - startTime
|
|
@@ -6013,14 +6020,14 @@ async function withTransaction(manager, operation, options) {
|
|
|
6013
6020
|
try {
|
|
6014
6021
|
await transaction.rollback();
|
|
6015
6022
|
} catch (rollbackError) {
|
|
6016
|
-
|
|
6023
|
+
logger13.error("Transaction rollback failed", {
|
|
6017
6024
|
transactionId,
|
|
6018
6025
|
vendor,
|
|
6019
6026
|
error: rollbackError instanceof Error ? rollbackError.message : String(rollbackError)
|
|
6020
6027
|
});
|
|
6021
6028
|
}
|
|
6022
6029
|
}
|
|
6023
|
-
|
|
6030
|
+
logger13.error("Transaction failed", {
|
|
6024
6031
|
transactionId,
|
|
6025
6032
|
vendor,
|
|
6026
6033
|
duration: Date.now() - startTime,
|
|
@@ -6511,7 +6518,7 @@ async function inspectSQLite(runQueryRows) {
|
|
|
6511
6518
|
}
|
|
6512
6519
|
|
|
6513
6520
|
// src/data/relational/schema/schema-inspector.ts
|
|
6514
|
-
var
|
|
6521
|
+
var logger14 = createLogger("agentforge:tools:data:relational:schema-inspector");
|
|
6515
6522
|
var DEFAULT_CACHE_TTL_MS = 6e4;
|
|
6516
6523
|
var schemaCache = /* @__PURE__ */ new Map();
|
|
6517
6524
|
var SchemaInspector = class _SchemaInspector {
|
|
@@ -6539,7 +6546,7 @@ var SchemaInspector = class _SchemaInspector {
|
|
|
6539
6546
|
if (!bypassCache && this.cacheKey) {
|
|
6540
6547
|
const cached = schemaCache.get(this.cacheKey);
|
|
6541
6548
|
if (cached && cached.expiresAt > Date.now()) {
|
|
6542
|
-
|
|
6549
|
+
logger14.debug("Schema cache hit", { vendor: this.vendor });
|
|
6543
6550
|
return filterSchemaTables(cloneSchema(cached.schema), tableFilters);
|
|
6544
6551
|
}
|
|
6545
6552
|
}
|
|
@@ -6584,7 +6591,7 @@ var SchemaInspector = class _SchemaInspector {
|
|
|
6584
6591
|
return result.rows;
|
|
6585
6592
|
}
|
|
6586
6593
|
};
|
|
6587
|
-
var
|
|
6594
|
+
var logger15 = createLogger("agentforge:tools:data:relational:schema-validator");
|
|
6588
6595
|
function validateTableExists(schema, tableName) {
|
|
6589
6596
|
const errors = [];
|
|
6590
6597
|
if (!tableName || typeof tableName !== "string") {
|
|
@@ -6598,7 +6605,7 @@ function validateTableExists(schema, tableName) {
|
|
|
6598
6605
|
`Table "${tableName}" does not exist. Available tables: ${available || "(none)"}`
|
|
6599
6606
|
);
|
|
6600
6607
|
}
|
|
6601
|
-
|
|
6608
|
+
logger15.debug("Table existence validation", { tableName, valid: errors.length === 0 });
|
|
6602
6609
|
return { valid: errors.length === 0, errors };
|
|
6603
6610
|
}
|
|
6604
6611
|
function validateColumnsExist(schema, tableName, columnNames) {
|
|
@@ -6621,7 +6628,7 @@ function validateColumnsExist(schema, tableName, columnNames) {
|
|
|
6621
6628
|
);
|
|
6622
6629
|
}
|
|
6623
6630
|
}
|
|
6624
|
-
|
|
6631
|
+
logger15.debug("Column existence validation", {
|
|
6625
6632
|
tableName,
|
|
6626
6633
|
columnCount: columnNames.length,
|
|
6627
6634
|
valid: errors.length === 0
|
|
@@ -6657,7 +6664,7 @@ function validateColumnTypes(schema, tableName, expectedTypes) {
|
|
|
6657
6664
|
);
|
|
6658
6665
|
}
|
|
6659
6666
|
}
|
|
6660
|
-
|
|
6667
|
+
logger15.debug("Column type validation", {
|
|
6661
6668
|
tableName,
|
|
6662
6669
|
typeChecks: Object.keys(expectedTypes).length,
|
|
6663
6670
|
valid: errors.length === 0
|
|
@@ -6677,7 +6684,7 @@ function findTable(schema, tableName) {
|
|
|
6677
6684
|
function formatTableName(table) {
|
|
6678
6685
|
return table.schema ? `${table.schema}.${table.name}` : table.name;
|
|
6679
6686
|
}
|
|
6680
|
-
var
|
|
6687
|
+
var logger16 = createLogger("agentforge:tools:data:relational:type-mapper");
|
|
6681
6688
|
var POSTGRES_TYPE_MAP = {
|
|
6682
6689
|
// Numeric
|
|
6683
6690
|
smallint: "number",
|
|
@@ -6843,7 +6850,7 @@ function mapColumnType(vendor, dbType, nullable = false) {
|
|
|
6843
6850
|
const result = { tsType, nullable, dbType };
|
|
6844
6851
|
if (tsType === "unknown" && normalised !== "json" && normalised !== "jsonb") {
|
|
6845
6852
|
result.notes = `No explicit mapping for "${dbType}"; defaulting to unknown`;
|
|
6846
|
-
|
|
6853
|
+
logger16.debug("Unmapped database type", { vendor, dbType, normalised });
|
|
6847
6854
|
}
|
|
6848
6855
|
if ((normalised === "bigint" || normalised === "int8" || normalised === "bigserial") && (vendor === "postgresql" || vendor === "mysql")) {
|
|
6849
6856
|
result.notes = "Mapped to string to avoid JavaScript number precision loss for 64-bit integers";
|
|
@@ -6858,7 +6865,7 @@ function mapSchemaTypes(vendor, columns) {
|
|
|
6858
6865
|
}
|
|
6859
6866
|
result.get(col.table).set(col.name, mapColumnType(vendor, col.type, col.nullable));
|
|
6860
6867
|
}
|
|
6861
|
-
|
|
6868
|
+
logger16.debug("Schema type mapping complete", {
|
|
6862
6869
|
vendor,
|
|
6863
6870
|
tables: result.size,
|
|
6864
6871
|
columns: columns.length
|
|
@@ -6875,7 +6882,7 @@ function normaliseDbType(raw) {
|
|
|
6875
6882
|
type = type.replace(/\s+unsigned$/, "");
|
|
6876
6883
|
return type.trim();
|
|
6877
6884
|
}
|
|
6878
|
-
var
|
|
6885
|
+
var logger17 = createLogger("agentforge:tools:data:relational:schema-diff");
|
|
6879
6886
|
function diffSchemas(before, after) {
|
|
6880
6887
|
const tableDiffs = [];
|
|
6881
6888
|
let columnsAdded = 0;
|
|
@@ -6915,7 +6922,7 @@ function diffSchemas(before, after) {
|
|
|
6915
6922
|
const tablesRemoved = tableDiffs.filter((d) => d.type === "removed").length;
|
|
6916
6923
|
const tablesChanged = tableDiffs.filter((d) => d.type === "changed").length;
|
|
6917
6924
|
const identical = tableDiffs.length === 0;
|
|
6918
|
-
|
|
6925
|
+
logger17.debug("Schema diff computed", {
|
|
6919
6926
|
identical,
|
|
6920
6927
|
tablesAdded,
|
|
6921
6928
|
tablesRemoved,
|
|
@@ -6959,7 +6966,7 @@ function importSchemaFromJson(json) {
|
|
|
6959
6966
|
throw new Error(`Invalid schema JSON: table "${table.name}" missing "primaryKey" array`);
|
|
6960
6967
|
}
|
|
6961
6968
|
}
|
|
6962
|
-
|
|
6969
|
+
logger17.debug("Schema imported from JSON", {
|
|
6963
6970
|
vendor: obj.vendor,
|
|
6964
6971
|
tableCount: obj.tables.length
|
|
6965
6972
|
});
|
|
@@ -7256,7 +7263,7 @@ function isSafeValidationError(error) {
|
|
|
7256
7263
|
}
|
|
7257
7264
|
|
|
7258
7265
|
// src/data/relational/tools/relational-select/executor.ts
|
|
7259
|
-
var
|
|
7266
|
+
var logger18 = createLogger("agentforge:tools:data:relational:select");
|
|
7260
7267
|
function toSelectQueryInput(input) {
|
|
7261
7268
|
return {
|
|
7262
7269
|
table: input.table,
|
|
@@ -7270,7 +7277,7 @@ function toSelectQueryInput(input) {
|
|
|
7270
7277
|
}
|
|
7271
7278
|
async function executeSelect(manager, input, context) {
|
|
7272
7279
|
const startTime = Date.now();
|
|
7273
|
-
|
|
7280
|
+
logger18.debug("Building SELECT query", {
|
|
7274
7281
|
vendor: input.vendor,
|
|
7275
7282
|
table: input.table,
|
|
7276
7283
|
hasWhere: !!input.where,
|
|
@@ -7288,7 +7295,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7288
7295
|
};
|
|
7289
7296
|
const streamInput = toSelectQueryInput(input);
|
|
7290
7297
|
if (input.streaming.benchmark) {
|
|
7291
|
-
|
|
7298
|
+
logger18.warn("Streaming benchmark enabled; SELECT will execute up to three times (result + benchmark regular + benchmark streaming).", {
|
|
7292
7299
|
vendor: input.vendor,
|
|
7293
7300
|
table: input.table,
|
|
7294
7301
|
chunkSize: streamOptions.chunkSize ?? DEFAULT_CHUNK_SIZE,
|
|
@@ -7299,7 +7306,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7299
7306
|
const streamResult = await executeStreamingSelect(executor, streamInput, streamOptions);
|
|
7300
7307
|
const benchmark = input.streaming.benchmark ? await benchmarkStreamingSelectMemory(executor, streamInput, streamOptions) : void 0;
|
|
7301
7308
|
const executionTime2 = Date.now() - startTime;
|
|
7302
|
-
|
|
7309
|
+
logger18.debug("Streaming SELECT query executed successfully", {
|
|
7303
7310
|
vendor: input.vendor,
|
|
7304
7311
|
table: input.table,
|
|
7305
7312
|
rowCount: streamResult.rowCount,
|
|
@@ -7328,7 +7335,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7328
7335
|
const executionTime = Date.now() - startTime;
|
|
7329
7336
|
const rows = Array.isArray(result) ? result : result.rows || [];
|
|
7330
7337
|
const rowCount = rows.length;
|
|
7331
|
-
|
|
7338
|
+
logger18.debug("SELECT query executed successfully", {
|
|
7332
7339
|
vendor: input.vendor,
|
|
7333
7340
|
table: input.table,
|
|
7334
7341
|
rowCount,
|
|
@@ -7341,7 +7348,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7341
7348
|
};
|
|
7342
7349
|
} catch (error) {
|
|
7343
7350
|
const executionTime = Date.now() - startTime;
|
|
7344
|
-
|
|
7351
|
+
logger18.error("SELECT query execution failed", {
|
|
7345
7352
|
vendor: input.vendor,
|
|
7346
7353
|
table: input.table,
|
|
7347
7354
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -7517,7 +7524,7 @@ function isSafeInsertError(error) {
|
|
|
7517
7524
|
}
|
|
7518
7525
|
|
|
7519
7526
|
// src/data/relational/tools/relational-insert/executor.ts
|
|
7520
|
-
var
|
|
7527
|
+
var logger19 = createLogger("agentforge:tools:data:relational:insert");
|
|
7521
7528
|
function toNumber(value) {
|
|
7522
7529
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
7523
7530
|
}
|
|
@@ -7666,7 +7673,7 @@ async function executeInsertInBatchMode(manager, input, context, options) {
|
|
|
7666
7673
|
maxRetries: options.maxRetries,
|
|
7667
7674
|
retryDelayMs: options.retryDelayMs,
|
|
7668
7675
|
onProgress: (progress) => {
|
|
7669
|
-
|
|
7676
|
+
logger19.debug("INSERT batch progress", {
|
|
7670
7677
|
vendor: input.vendor,
|
|
7671
7678
|
table: input.table,
|
|
7672
7679
|
...progress
|
|
@@ -7679,7 +7686,7 @@ async function executeInsertInBatchMode(manager, input, context, options) {
|
|
|
7679
7686
|
const insertedIds = batchResult.results.flatMap((result) => result.insertedIds);
|
|
7680
7687
|
let benchmark;
|
|
7681
7688
|
if (options.benchmark) {
|
|
7682
|
-
|
|
7689
|
+
logger19.warn("INSERT batch benchmark enabled. Synthetic benchmark callbacks are side-effect free and do not execute SQL.", {
|
|
7683
7690
|
vendor: input.vendor,
|
|
7684
7691
|
table: input.table,
|
|
7685
7692
|
totalRows: input.data.length,
|
|
@@ -7716,7 +7723,7 @@ async function executeInsertInBatchMode(manager, input, context, options) {
|
|
|
7716
7723
|
}
|
|
7717
7724
|
async function executeInsert(manager, input, context) {
|
|
7718
7725
|
const startTime = Date.now();
|
|
7719
|
-
|
|
7726
|
+
logger19.debug("Building INSERT query", {
|
|
7720
7727
|
vendor: input.vendor,
|
|
7721
7728
|
table: input.table,
|
|
7722
7729
|
isBatch: Array.isArray(input.data),
|
|
@@ -7732,7 +7739,7 @@ async function executeInsert(manager, input, context) {
|
|
|
7732
7739
|
batchOptions
|
|
7733
7740
|
) : await executeInsertOnce(manager, input, context);
|
|
7734
7741
|
const executionTime = Date.now() - startTime;
|
|
7735
|
-
|
|
7742
|
+
logger19.debug("INSERT query executed successfully", {
|
|
7736
7743
|
vendor: input.vendor,
|
|
7737
7744
|
table: input.table,
|
|
7738
7745
|
rowCount: result.rowCount,
|
|
@@ -7748,7 +7755,7 @@ async function executeInsert(manager, input, context) {
|
|
|
7748
7755
|
};
|
|
7749
7756
|
} catch (error) {
|
|
7750
7757
|
const executionTime = Date.now() - startTime;
|
|
7751
|
-
|
|
7758
|
+
logger19.error("INSERT query execution failed", {
|
|
7752
7759
|
vendor: input.vendor,
|
|
7753
7760
|
table: input.table,
|
|
7754
7761
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -8078,7 +8085,7 @@ function isSafeUpdateError(error) {
|
|
|
8078
8085
|
}
|
|
8079
8086
|
|
|
8080
8087
|
// src/data/relational/tools/relational-update/executor.ts
|
|
8081
|
-
var
|
|
8088
|
+
var logger20 = createLogger("agentforge:tools:data:relational:update");
|
|
8082
8089
|
function toNumber2(value) {
|
|
8083
8090
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
8084
8091
|
}
|
|
@@ -8200,7 +8207,7 @@ async function executeUpdateInBatchMode(manager, input, context, options) {
|
|
|
8200
8207
|
maxRetries: options.maxRetries,
|
|
8201
8208
|
retryDelayMs: options.retryDelayMs,
|
|
8202
8209
|
onProgress: (progress) => {
|
|
8203
|
-
|
|
8210
|
+
logger20.debug("UPDATE batch progress", {
|
|
8204
8211
|
vendor: input.vendor,
|
|
8205
8212
|
table: input.table,
|
|
8206
8213
|
...progress
|
|
@@ -8212,7 +8219,7 @@ async function executeUpdateInBatchMode(manager, input, context, options) {
|
|
|
8212
8219
|
const operationFailures = batchResult.results.flatMap((result) => result.failures);
|
|
8213
8220
|
let benchmark;
|
|
8214
8221
|
if (options.benchmark) {
|
|
8215
|
-
|
|
8222
|
+
logger20.warn("UPDATE batch benchmark enabled. Synthetic benchmark callbacks are side-effect free and do not execute SQL.", {
|
|
8216
8223
|
vendor: input.vendor,
|
|
8217
8224
|
table: input.table,
|
|
8218
8225
|
operationCount: input.operations.length,
|
|
@@ -8247,7 +8254,7 @@ async function executeUpdateInBatchMode(manager, input, context, options) {
|
|
|
8247
8254
|
}
|
|
8248
8255
|
async function executeUpdate(manager, input, context) {
|
|
8249
8256
|
const startTime = Date.now();
|
|
8250
|
-
|
|
8257
|
+
logger20.debug("Building UPDATE query", {
|
|
8251
8258
|
vendor: input.vendor,
|
|
8252
8259
|
table: input.table,
|
|
8253
8260
|
hasWhere: !!input.where?.length,
|
|
@@ -8265,7 +8272,7 @@ async function executeUpdate(manager, input, context) {
|
|
|
8265
8272
|
batchOptions
|
|
8266
8273
|
) : await executeSingleUpdate(manager, input, toSingleUpdateOperation(input), context);
|
|
8267
8274
|
const executionTime = Date.now() - startTime;
|
|
8268
|
-
|
|
8275
|
+
logger20.debug("UPDATE query executed successfully", {
|
|
8269
8276
|
vendor: input.vendor,
|
|
8270
8277
|
table: input.table,
|
|
8271
8278
|
rowCount: result.rowCount,
|
|
@@ -8279,7 +8286,7 @@ async function executeUpdate(manager, input, context) {
|
|
|
8279
8286
|
};
|
|
8280
8287
|
} catch (error) {
|
|
8281
8288
|
const executionTime = Date.now() - startTime;
|
|
8282
|
-
|
|
8289
|
+
logger20.error("UPDATE query execution failed", {
|
|
8283
8290
|
vendor: input.vendor,
|
|
8284
8291
|
table: input.table,
|
|
8285
8292
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -8583,7 +8590,7 @@ function isSafeDeleteError(error) {
|
|
|
8583
8590
|
}
|
|
8584
8591
|
|
|
8585
8592
|
// src/data/relational/tools/relational-delete/executor.ts
|
|
8586
|
-
var
|
|
8593
|
+
var logger21 = createLogger("agentforge:tools:data:relational:delete");
|
|
8587
8594
|
function toNumber3(value) {
|
|
8588
8595
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
8589
8596
|
}
|
|
@@ -8704,7 +8711,7 @@ async function executeDeleteInBatchMode(manager, input, context, options) {
|
|
|
8704
8711
|
maxRetries: options.maxRetries,
|
|
8705
8712
|
retryDelayMs: options.retryDelayMs,
|
|
8706
8713
|
onProgress: (progress) => {
|
|
8707
|
-
|
|
8714
|
+
logger21.debug("DELETE batch progress", {
|
|
8708
8715
|
vendor: input.vendor,
|
|
8709
8716
|
table: input.table,
|
|
8710
8717
|
...progress
|
|
@@ -8717,7 +8724,7 @@ async function executeDeleteInBatchMode(manager, input, context, options) {
|
|
|
8717
8724
|
const operationFailures = batchResult.results.flatMap((result) => result.failures);
|
|
8718
8725
|
let benchmark;
|
|
8719
8726
|
if (options.benchmark) {
|
|
8720
|
-
|
|
8727
|
+
logger21.warn("DELETE batch benchmark enabled. Synthetic benchmark callbacks are side-effect free and do not execute SQL.", {
|
|
8721
8728
|
vendor: input.vendor,
|
|
8722
8729
|
table: input.table,
|
|
8723
8730
|
operationCount: input.operations.length,
|
|
@@ -8753,7 +8760,7 @@ async function executeDeleteInBatchMode(manager, input, context, options) {
|
|
|
8753
8760
|
}
|
|
8754
8761
|
async function executeDelete(manager, input, context) {
|
|
8755
8762
|
const startTime = Date.now();
|
|
8756
|
-
|
|
8763
|
+
logger21.debug("Building DELETE query", {
|
|
8757
8764
|
vendor: input.vendor,
|
|
8758
8765
|
table: input.table,
|
|
8759
8766
|
hasWhere: !!input.where?.length,
|
|
@@ -8772,7 +8779,7 @@ async function executeDelete(manager, input, context) {
|
|
|
8772
8779
|
batchOptions
|
|
8773
8780
|
) : await executeSingleDelete(manager, input, toSingleDeleteOperation(input), context);
|
|
8774
8781
|
const executionTime = Date.now() - startTime;
|
|
8775
|
-
|
|
8782
|
+
logger21.debug("DELETE query executed successfully", {
|
|
8776
8783
|
vendor: input.vendor,
|
|
8777
8784
|
table: input.table,
|
|
8778
8785
|
rowCount: result.rowCount,
|
|
@@ -8788,7 +8795,7 @@ async function executeDelete(manager, input, context) {
|
|
|
8788
8795
|
};
|
|
8789
8796
|
} catch (error) {
|
|
8790
8797
|
const executionTime = Date.now() - startTime;
|
|
8791
|
-
|
|
8798
|
+
logger21.error("DELETE query execution failed", {
|
|
8792
8799
|
vendor: input.vendor,
|
|
8793
8800
|
table: input.table,
|
|
8794
8801
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -8893,7 +8900,7 @@ function isSafeGetSchemaValidationError(error) {
|
|
|
8893
8900
|
}
|
|
8894
8901
|
|
|
8895
8902
|
// src/data/relational/tools/relational-get-schema.ts
|
|
8896
|
-
var
|
|
8903
|
+
var logger22 = createLogger("agentforge:tools:data:relational:get-schema");
|
|
8897
8904
|
function buildSchemaCacheKey(vendor, connectionString, database) {
|
|
8898
8905
|
const databaseScope = database ?? "default";
|
|
8899
8906
|
const connectionHash = createHash("sha256").update(connectionString).digest("hex");
|
|
@@ -8965,7 +8972,7 @@ var relationalGetSchema = toolBuilder().name("relational-get-schema").displayNam
|
|
|
8965
8972
|
summary
|
|
8966
8973
|
};
|
|
8967
8974
|
} catch (error) {
|
|
8968
|
-
|
|
8975
|
+
logger22.error("Schema introspection failed", {
|
|
8969
8976
|
vendor: input.vendor,
|
|
8970
8977
|
hasTablesFilter: Array.isArray(input.tables),
|
|
8971
8978
|
tablesFilterCount: input.tables?.length ?? 0,
|
|
@@ -10131,7 +10138,7 @@ var AskHumanInputSchema = z.object({
|
|
|
10131
10138
|
suggestions: z.array(z.string()).optional().describe("Suggested responses for the human")
|
|
10132
10139
|
});
|
|
10133
10140
|
var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || LogLevel.INFO;
|
|
10134
|
-
var
|
|
10141
|
+
var logger23 = createLogger("agentforge:tools:agent:ask-human", { level: logLevel3 });
|
|
10135
10142
|
function isRecord2(value) {
|
|
10136
10143
|
return typeof value === "object" && value !== null;
|
|
10137
10144
|
}
|
|
@@ -10196,7 +10203,7 @@ function createAskHumanTool() {
|
|
|
10196
10203
|
suggestions: validatedInput.suggestions,
|
|
10197
10204
|
status: "pending"
|
|
10198
10205
|
};
|
|
10199
|
-
|
|
10206
|
+
logger23.debug("About to call interrupt()", {
|
|
10200
10207
|
humanRequest: {
|
|
10201
10208
|
id: humanRequest.id,
|
|
10202
10209
|
question: humanRequest.question,
|
|
@@ -10212,13 +10219,13 @@ function createAskHumanTool() {
|
|
|
10212
10219
|
let response;
|
|
10213
10220
|
try {
|
|
10214
10221
|
response = interrupt(humanRequest);
|
|
10215
|
-
|
|
10222
|
+
logger23.debug("interrupt() returned successfully", {
|
|
10216
10223
|
responseType: typeof response,
|
|
10217
10224
|
hasResponse: response != null,
|
|
10218
10225
|
...typeof response === "string" ? { responseLength: response.length } : {}
|
|
10219
10226
|
});
|
|
10220
10227
|
} catch (error) {
|
|
10221
|
-
|
|
10228
|
+
logger23.debug("interrupt() threw error (expected for GraphInterrupt)", {
|
|
10222
10229
|
...error && typeof error === "object" && "constructor" in error ? { errorType: error.constructor?.name } : {},
|
|
10223
10230
|
error: error instanceof Error ? error.message : String(error)
|
|
10224
10231
|
});
|