@agentforge/tools 0.16.52 → 0.16.54
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 +215 -204
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -13
- package/dist/index.d.ts +28 -13
- package/dist/index.js +215 -204
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -494,7 +494,7 @@ function sleep(ms) {
|
|
|
494
494
|
}
|
|
495
495
|
async function retryWithBackoff(fn, config = DEFAULT_RETRY_CONFIG) {
|
|
496
496
|
let lastError;
|
|
497
|
-
let
|
|
497
|
+
let delay = config.initialDelay;
|
|
498
498
|
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
499
499
|
try {
|
|
500
500
|
return await fn();
|
|
@@ -506,8 +506,8 @@ async function retryWithBackoff(fn, config = DEFAULT_RETRY_CONFIG) {
|
|
|
506
506
|
if (attempt === config.maxRetries) {
|
|
507
507
|
break;
|
|
508
508
|
}
|
|
509
|
-
await sleep(
|
|
510
|
-
|
|
509
|
+
await sleep(delay);
|
|
510
|
+
delay = Math.min(delay * config.backoffMultiplier, config.maxDelay);
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
513
|
throw lastError;
|
|
@@ -815,7 +815,7 @@ function getDefaultSlackClient() {
|
|
|
815
815
|
}
|
|
816
816
|
};
|
|
817
817
|
}
|
|
818
|
-
function createSendSlackMessageTool(getSlackClient,
|
|
818
|
+
function createSendSlackMessageTool(getSlackClient, logger23) {
|
|
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, logger24) {
|
|
|
824
824
|
message: zod.z.string().describe("Message content to send")
|
|
825
825
|
})
|
|
826
826
|
).implementSafe(async ({ channel, message }) => {
|
|
827
|
-
|
|
827
|
+
logger23.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, logger24) {
|
|
|
833
833
|
username: config.botName,
|
|
834
834
|
icon_emoji: config.botIcon
|
|
835
835
|
});
|
|
836
|
-
|
|
836
|
+
logger23.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, logger24) {
|
|
|
846
846
|
message_id: result.ts
|
|
847
847
|
};
|
|
848
848
|
} catch (error) {
|
|
849
|
-
|
|
849
|
+
logger23.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, logger24) {
|
|
|
855
855
|
}
|
|
856
856
|
}).build();
|
|
857
857
|
}
|
|
858
|
-
function createNotifySlackTool(getSlackClient,
|
|
858
|
+
function createNotifySlackTool(getSlackClient, logger23) {
|
|
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, logger24) {
|
|
|
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
|
+
logger23.info("notify-slack called", {
|
|
869
869
|
channel,
|
|
870
870
|
messageLength: message.length,
|
|
871
871
|
mentionCount: mentions.length
|
|
@@ -879,7 +879,7 @@ function createNotifySlackTool(getSlackClient, logger24) {
|
|
|
879
879
|
username: config.botName,
|
|
880
880
|
icon_emoji: config.botIcon
|
|
881
881
|
});
|
|
882
|
-
|
|
882
|
+
logger23.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, logger24) {
|
|
|
893
893
|
};
|
|
894
894
|
}).build();
|
|
895
895
|
}
|
|
896
|
-
function createGetSlackChannelsTool(getSlackClient,
|
|
896
|
+
function createGetSlackChannelsTool(getSlackClient, logger23) {
|
|
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, logger24) {
|
|
|
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
|
+
logger23.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, logger24) {
|
|
|
915
915
|
});
|
|
916
916
|
allChannels = [...allChannels, ...privateChannels.channels || []];
|
|
917
917
|
}
|
|
918
|
-
|
|
918
|
+
logger23.info("get-slack-channels result", {
|
|
919
919
|
channelCount: allChannels.length,
|
|
920
920
|
includePrivate: include_private
|
|
921
921
|
});
|
|
@@ -930,7 +930,7 @@ function createGetSlackChannelsTool(getSlackClient, logger24) {
|
|
|
930
930
|
};
|
|
931
931
|
}).build();
|
|
932
932
|
}
|
|
933
|
-
function createGetSlackMessagesTool(getSlackClient,
|
|
933
|
+
function createGetSlackMessagesTool(getSlackClient, logger23) {
|
|
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, logger24) {
|
|
|
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
|
+
logger23.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, logger24) {
|
|
|
950
950
|
});
|
|
951
951
|
const found = channels.channels?.find((c) => c.name === channel);
|
|
952
952
|
if (!found) {
|
|
953
|
-
|
|
953
|
+
logger23.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, logger24) {
|
|
|
962
962
|
limit: Math.min(limit, 100)
|
|
963
963
|
// Cap at 100 for performance
|
|
964
964
|
});
|
|
965
|
-
|
|
965
|
+
logger23.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, logger24) {
|
|
|
980
980
|
})) || []
|
|
981
981
|
};
|
|
982
982
|
} catch (error) {
|
|
983
|
-
|
|
983
|
+
logger23.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, logger23) {
|
|
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
|
+
logger23.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, logger24) {
|
|
|
1091
1091
|
lastModified: page.version?.when || ""
|
|
1092
1092
|
}));
|
|
1093
1093
|
if (results.length === 0) {
|
|
1094
|
-
|
|
1094
|
+
logger23.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
|
+
logger23.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, logger24) {
|
|
|
1112
1112
|
results
|
|
1113
1113
|
});
|
|
1114
1114
|
} catch (error) {
|
|
1115
|
-
|
|
1115
|
+
logger23.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, logger24) {
|
|
|
1124
1124
|
}
|
|
1125
1125
|
}).build();
|
|
1126
1126
|
}
|
|
1127
|
-
function createGetConfluencePageTool(getAuth, getAuthHeader2,
|
|
1127
|
+
function createGetConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
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
|
+
logger23.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, logger24) {
|
|
|
1141
1141
|
}
|
|
1142
1142
|
});
|
|
1143
1143
|
const page = response.data;
|
|
1144
|
-
|
|
1144
|
+
logger23.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, logger24) {
|
|
|
1163
1163
|
}
|
|
1164
1164
|
});
|
|
1165
1165
|
} catch (error) {
|
|
1166
|
-
|
|
1166
|
+
logger23.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, logger24) {
|
|
|
1175
1175
|
}
|
|
1176
1176
|
}).build();
|
|
1177
1177
|
}
|
|
1178
|
-
function createListConfluenceSpacesTool(getAuth, getAuthHeader2,
|
|
1178
|
+
function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger23) {
|
|
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
|
+
logger23.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, logger24) {
|
|
|
1198
1198
|
description: space.description?.plain?.value || "",
|
|
1199
1199
|
url: `${ATLASSIAN_SITE_URL}/wiki${space._links.webui}`
|
|
1200
1200
|
}));
|
|
1201
|
-
|
|
1201
|
+
logger23.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, logger24) {
|
|
|
1209
1209
|
spaces
|
|
1210
1210
|
});
|
|
1211
1211
|
} catch (error) {
|
|
1212
|
-
|
|
1212
|
+
logger23.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, logger24) {
|
|
|
1220
1220
|
}
|
|
1221
1221
|
}).build();
|
|
1222
1222
|
}
|
|
1223
|
-
function createGetSpacePagesTool(getAuth, getAuthHeader2,
|
|
1223
|
+
function createGetSpacePagesTool(getAuth, getAuthHeader2, logger23) {
|
|
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
|
+
logger23.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, logger24) {
|
|
|
1247
1247
|
lastModified: page.version?.when || ""
|
|
1248
1248
|
}));
|
|
1249
1249
|
if (pages.length === 0) {
|
|
1250
|
-
|
|
1250
|
+
logger23.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
|
+
logger23.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, logger24) {
|
|
|
1266
1266
|
pages
|
|
1267
1267
|
});
|
|
1268
1268
|
} catch (error) {
|
|
1269
|
-
|
|
1269
|
+
logger23.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, logger24) {
|
|
|
1278
1278
|
}
|
|
1279
1279
|
}).build();
|
|
1280
1280
|
}
|
|
1281
|
-
function createCreateConfluencePageTool(getAuth, getAuthHeader2,
|
|
1281
|
+
function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
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
|
+
logger23.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, logger24) {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
}
|
|
1314
1314
|
);
|
|
1315
|
-
|
|
1315
|
+
logger23.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, logger24) {
|
|
|
1328
1328
|
}
|
|
1329
1329
|
});
|
|
1330
1330
|
} catch (error) {
|
|
1331
|
-
|
|
1331
|
+
logger23.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, logger24) {
|
|
|
1341
1341
|
}
|
|
1342
1342
|
}).build();
|
|
1343
1343
|
}
|
|
1344
|
-
function createUpdateConfluencePageTool(getAuth, getAuthHeader2,
|
|
1344
|
+
function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
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
|
+
logger23.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, logger24) {
|
|
|
1380
1380
|
}
|
|
1381
1381
|
}
|
|
1382
1382
|
);
|
|
1383
|
-
|
|
1383
|
+
logger23.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, logger24) {
|
|
|
1397
1397
|
}
|
|
1398
1398
|
});
|
|
1399
1399
|
} catch (error) {
|
|
1400
|
-
|
|
1400
|
+
logger23.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, logger24) {
|
|
|
1410
1410
|
}
|
|
1411
1411
|
}).build();
|
|
1412
1412
|
}
|
|
1413
|
-
function createArchiveConfluencePageTool(getAuth, getAuthHeader2,
|
|
1413
|
+
function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger23) {
|
|
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
|
+
logger23.info("archive-confluence-page called", {
|
|
1419
1419
|
page_id,
|
|
1420
1420
|
...reason ? { reason } : {}
|
|
1421
1421
|
});
|
|
@@ -1449,7 +1449,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger24) {
|
|
|
1449
1449
|
}
|
|
1450
1450
|
}
|
|
1451
1451
|
);
|
|
1452
|
-
|
|
1452
|
+
logger23.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, logger24) {
|
|
|
1467
1467
|
}
|
|
1468
1468
|
});
|
|
1469
1469
|
} catch (error) {
|
|
1470
|
-
|
|
1470
|
+
logger23.error("archive-confluence-page error", {
|
|
1471
1471
|
page_id,
|
|
1472
1472
|
error: error.response?.data?.message || error.message,
|
|
1473
1473
|
status: error.response?.status
|
|
@@ -2394,7 +2394,7 @@ function sleep2(ms) {
|
|
|
2394
2394
|
}
|
|
2395
2395
|
async function retryWithBackoff2(fn, config = DEFAULT_RETRY_CONFIG2) {
|
|
2396
2396
|
let lastError;
|
|
2397
|
-
let
|
|
2397
|
+
let delay = config.initialDelay;
|
|
2398
2398
|
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
2399
2399
|
try {
|
|
2400
2400
|
return await fn();
|
|
@@ -2406,8 +2406,8 @@ async function retryWithBackoff2(fn, config = DEFAULT_RETRY_CONFIG2) {
|
|
|
2406
2406
|
if (attempt === config.maxRetries) {
|
|
2407
2407
|
break;
|
|
2408
2408
|
}
|
|
2409
|
-
await sleep2(
|
|
2410
|
-
|
|
2409
|
+
await sleep2(delay);
|
|
2410
|
+
delay = Math.min(delay * config.backoffMultiplier, config.maxDelay);
|
|
2411
2411
|
}
|
|
2412
2412
|
}
|
|
2413
2413
|
throw lastError;
|
|
@@ -4148,19 +4148,19 @@ var ConnectionState = /* @__PURE__ */ ((ConnectionState2) => {
|
|
|
4148
4148
|
ConnectionState2["ERROR"] = "error";
|
|
4149
4149
|
return ConnectionState2;
|
|
4150
4150
|
})(ConnectionState || {});
|
|
4151
|
-
function cancelPendingReconnection(timer,
|
|
4151
|
+
function cancelPendingReconnection(timer, logger23, vendor, message) {
|
|
4152
4152
|
if (!timer) {
|
|
4153
4153
|
return null;
|
|
4154
4154
|
}
|
|
4155
|
-
|
|
4155
|
+
logger23.debug(message, { vendor });
|
|
4156
4156
|
clearTimeout(timer);
|
|
4157
4157
|
return null;
|
|
4158
4158
|
}
|
|
4159
|
-
async function waitForInFlightConnection(promise,
|
|
4159
|
+
async function waitForInFlightConnection(promise, logger23, vendor, phase) {
|
|
4160
4160
|
if (!promise) {
|
|
4161
4161
|
return null;
|
|
4162
4162
|
}
|
|
4163
|
-
|
|
4163
|
+
logger23.debug(`Waiting for in-flight connection attempt to complete before ${phase}`, {
|
|
4164
4164
|
vendor
|
|
4165
4165
|
});
|
|
4166
4166
|
try {
|
|
@@ -4177,37 +4177,37 @@ function shutdownClient(vendor, client) {
|
|
|
4177
4177
|
client.close();
|
|
4178
4178
|
}
|
|
4179
4179
|
}
|
|
4180
|
-
function scheduleReconnection(context,
|
|
4180
|
+
function scheduleReconnection(context, logger23) {
|
|
4181
4181
|
if (context.reconnectionConfig.maxAttempts > 0 && context.reconnectionAttempts >= context.reconnectionConfig.maxAttempts) {
|
|
4182
|
-
|
|
4182
|
+
logger23.error("Max reconnection attempts reached", {
|
|
4183
4183
|
vendor: context.vendor,
|
|
4184
4184
|
attempts: context.reconnectionAttempts,
|
|
4185
4185
|
maxAttempts: context.reconnectionConfig.maxAttempts
|
|
4186
4186
|
});
|
|
4187
4187
|
return;
|
|
4188
4188
|
}
|
|
4189
|
-
const
|
|
4189
|
+
const delay = Math.min(
|
|
4190
4190
|
context.reconnectionConfig.baseDelayMs * Math.pow(2, context.reconnectionAttempts),
|
|
4191
4191
|
context.reconnectionConfig.maxDelayMs
|
|
4192
4192
|
);
|
|
4193
4193
|
const nextAttempt = context.reconnectionAttempts + 1;
|
|
4194
4194
|
context.setReconnectionAttempts(nextAttempt);
|
|
4195
4195
|
context.setState("reconnecting" /* RECONNECTING */);
|
|
4196
|
-
|
|
4196
|
+
logger23.info("Scheduling reconnection attempt", {
|
|
4197
4197
|
vendor: context.vendor,
|
|
4198
4198
|
attempt: nextAttempt,
|
|
4199
4199
|
maxAttempts: context.reconnectionConfig.maxAttempts,
|
|
4200
|
-
delayMs:
|
|
4200
|
+
delayMs: delay
|
|
4201
4201
|
});
|
|
4202
4202
|
context.emitReconnecting({
|
|
4203
4203
|
attempt: nextAttempt,
|
|
4204
4204
|
maxAttempts: context.reconnectionConfig.maxAttempts,
|
|
4205
|
-
delayMs:
|
|
4205
|
+
delayMs: delay
|
|
4206
4206
|
});
|
|
4207
4207
|
const timer = setTimeout(async () => {
|
|
4208
4208
|
context.setReconnectionTimer(null);
|
|
4209
4209
|
try {
|
|
4210
|
-
|
|
4210
|
+
logger23.info("Attempting reconnection", {
|
|
4211
4211
|
vendor: context.vendor,
|
|
4212
4212
|
attempt: nextAttempt
|
|
4213
4213
|
});
|
|
@@ -4217,28 +4217,28 @@ function scheduleReconnection(context, logger24) {
|
|
|
4217
4217
|
context.setConnectPromise(promise);
|
|
4218
4218
|
await promise;
|
|
4219
4219
|
} catch (error) {
|
|
4220
|
-
|
|
4220
|
+
logger23.error("Reconnection attempt failed", {
|
|
4221
4221
|
vendor: context.vendor,
|
|
4222
4222
|
attempt: nextAttempt,
|
|
4223
4223
|
error: error instanceof Error ? error.message : String(error)
|
|
4224
4224
|
});
|
|
4225
4225
|
}
|
|
4226
|
-
},
|
|
4226
|
+
}, delay);
|
|
4227
4227
|
context.setReconnectionTimer(timer);
|
|
4228
4228
|
}
|
|
4229
4229
|
|
|
4230
4230
|
// src/data/relational/connection/connection-cleanup.ts
|
|
4231
|
-
async function cleanupConnectionResources(vendor, client, clearConnection,
|
|
4231
|
+
async function cleanupConnectionResources(vendor, client, clearConnection, logger23) {
|
|
4232
4232
|
if (!client) {
|
|
4233
4233
|
return;
|
|
4234
4234
|
}
|
|
4235
|
-
|
|
4235
|
+
logger23.debug("Cleaning up cancelled connection", {
|
|
4236
4236
|
vendor
|
|
4237
4237
|
});
|
|
4238
4238
|
try {
|
|
4239
4239
|
await shutdownClient(vendor, client);
|
|
4240
4240
|
} catch (error) {
|
|
4241
|
-
|
|
4241
|
+
logger23.debug("Error during cancelled connection cleanup", {
|
|
4242
4242
|
vendor,
|
|
4243
4243
|
error: error instanceof Error ? error.message : String(error)
|
|
4244
4244
|
});
|
|
@@ -4246,10 +4246,10 @@ async function cleanupConnectionResources(vendor, client, clearConnection, logge
|
|
|
4246
4246
|
clearConnection();
|
|
4247
4247
|
}
|
|
4248
4248
|
}
|
|
4249
|
-
async function closeManagedConnection(runtime,
|
|
4249
|
+
async function closeManagedConnection(runtime, logger23) {
|
|
4250
4250
|
const client = runtime.getClient();
|
|
4251
4251
|
if (client) {
|
|
4252
|
-
|
|
4252
|
+
logger23.info("Closing database connection", {
|
|
4253
4253
|
vendor: runtime.vendor,
|
|
4254
4254
|
state: runtime.getState()
|
|
4255
4255
|
});
|
|
@@ -4257,12 +4257,12 @@ async function closeManagedConnection(runtime, logger24) {
|
|
|
4257
4257
|
await shutdownClient(runtime.vendor, client);
|
|
4258
4258
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4259
4259
|
runtime.emitDisconnected();
|
|
4260
|
-
|
|
4260
|
+
logger23.debug("Database connection closed successfully", {
|
|
4261
4261
|
vendor: runtime.vendor,
|
|
4262
4262
|
state: runtime.getState()
|
|
4263
4263
|
});
|
|
4264
4264
|
} catch (error) {
|
|
4265
|
-
|
|
4265
|
+
logger23.error("Error closing database connection", {
|
|
4266
4266
|
vendor: runtime.vendor,
|
|
4267
4267
|
error: error instanceof Error ? error.message : String(error),
|
|
4268
4268
|
state: runtime.getState()
|
|
@@ -4435,11 +4435,11 @@ async function initializeSQLiteConnection(connection) {
|
|
|
4435
4435
|
}
|
|
4436
4436
|
|
|
4437
4437
|
// src/data/relational/connection/connection-initialization.ts
|
|
4438
|
-
async function initializeManagedConnection(runtime,
|
|
4438
|
+
async function initializeManagedConnection(runtime, logger23) {
|
|
4439
4439
|
const startTime = Date.now();
|
|
4440
4440
|
const currentGeneration = runtime.getConnectionGeneration();
|
|
4441
4441
|
if (runtime.getState() === "connected" /* CONNECTED */ && runtime.getClient()) {
|
|
4442
|
-
|
|
4442
|
+
logger23.warn("Re-initializing an already connected manager; emitting disconnected before cleanup", {
|
|
4443
4443
|
vendor: runtime.vendor
|
|
4444
4444
|
});
|
|
4445
4445
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
@@ -4451,11 +4451,11 @@ async function initializeManagedConnection(runtime, logger24) {
|
|
|
4451
4451
|
runtime.setClient(null);
|
|
4452
4452
|
runtime.setDb(null);
|
|
4453
4453
|
},
|
|
4454
|
-
|
|
4454
|
+
logger23
|
|
4455
4455
|
);
|
|
4456
4456
|
}
|
|
4457
4457
|
runtime.setState("connecting" /* CONNECTING */);
|
|
4458
|
-
|
|
4458
|
+
logger23.info("Initializing database connection", {
|
|
4459
4459
|
vendor: runtime.vendor,
|
|
4460
4460
|
connectionType: typeof runtime.config.connection,
|
|
4461
4461
|
state: runtime.getState()
|
|
@@ -4465,7 +4465,7 @@ async function initializeManagedConnection(runtime, logger24) {
|
|
|
4465
4465
|
runtime.setClient(initialized.client);
|
|
4466
4466
|
runtime.setDb(initialized.db);
|
|
4467
4467
|
if (currentGeneration !== runtime.getConnectionGeneration()) {
|
|
4468
|
-
|
|
4468
|
+
logger23.debug("Connection cancelled during initialization", {
|
|
4469
4469
|
vendor: runtime.vendor,
|
|
4470
4470
|
currentGeneration,
|
|
4471
4471
|
newGeneration: runtime.getConnectionGeneration()
|
|
@@ -4477,18 +4477,18 @@ async function initializeManagedConnection(runtime, logger24) {
|
|
|
4477
4477
|
runtime.setClient(null);
|
|
4478
4478
|
runtime.setDb(null);
|
|
4479
4479
|
},
|
|
4480
|
-
|
|
4480
|
+
logger23
|
|
4481
4481
|
);
|
|
4482
4482
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4483
4483
|
throw new Error("Connection cancelled during initialization");
|
|
4484
4484
|
}
|
|
4485
|
-
|
|
4485
|
+
logger23.debug("Validating connection health", { vendor: runtime.vendor });
|
|
4486
4486
|
const healthy = await runtime.isHealthy();
|
|
4487
4487
|
if (!healthy) {
|
|
4488
4488
|
throw new Error(`Failed to establish healthy connection to ${runtime.vendor} database`);
|
|
4489
4489
|
}
|
|
4490
4490
|
if (currentGeneration !== runtime.getConnectionGeneration()) {
|
|
4491
|
-
|
|
4491
|
+
logger23.debug("Connection cancelled during health check", {
|
|
4492
4492
|
vendor: runtime.vendor,
|
|
4493
4493
|
currentGeneration,
|
|
4494
4494
|
newGeneration: runtime.getConnectionGeneration()
|
|
@@ -4500,7 +4500,7 @@ async function initializeManagedConnection(runtime, logger24) {
|
|
|
4500
4500
|
runtime.setClient(null);
|
|
4501
4501
|
runtime.setDb(null);
|
|
4502
4502
|
},
|
|
4503
|
-
|
|
4503
|
+
logger23
|
|
4504
4504
|
);
|
|
4505
4505
|
runtime.setState("disconnected" /* DISCONNECTED */);
|
|
4506
4506
|
throw new Error("Connection cancelled during health check");
|
|
@@ -4508,7 +4508,7 @@ async function initializeManagedConnection(runtime, logger24) {
|
|
|
4508
4508
|
runtime.setState("connected" /* CONNECTED */);
|
|
4509
4509
|
runtime.emitConnected();
|
|
4510
4510
|
runtime.resetReconnectionAttempts();
|
|
4511
|
-
|
|
4511
|
+
logger23.info("Database connection initialized successfully", {
|
|
4512
4512
|
vendor: runtime.vendor,
|
|
4513
4513
|
duration: Date.now() - startTime,
|
|
4514
4514
|
state: runtime.getState()
|
|
@@ -4529,7 +4529,7 @@ async function initializeManagedConnection(runtime, logger24) {
|
|
|
4529
4529
|
if (runtime.errorListenerCount() > 0) {
|
|
4530
4530
|
runtime.emitError(normalizedError);
|
|
4531
4531
|
}
|
|
4532
|
-
|
|
4532
|
+
logger23.error(errorMessage, {
|
|
4533
4533
|
vendor: runtime.vendor,
|
|
4534
4534
|
error: normalizedError.message,
|
|
4535
4535
|
duration: Date.now() - startTime,
|
|
@@ -4542,13 +4542,13 @@ async function initializeManagedConnection(runtime, logger24) {
|
|
|
4542
4542
|
runtime.setClient(null);
|
|
4543
4543
|
runtime.setDb(null);
|
|
4544
4544
|
},
|
|
4545
|
-
|
|
4545
|
+
logger23
|
|
4546
4546
|
);
|
|
4547
4547
|
if (runtime.getReconnectionConfig().enabled && currentGeneration === runtime.getConnectionGeneration()) {
|
|
4548
4548
|
runtime.scheduleReconnection();
|
|
4549
4549
|
}
|
|
4550
4550
|
} else {
|
|
4551
|
-
|
|
4551
|
+
logger23.debug("Connection initialization cancelled", {
|
|
4552
4552
|
vendor: runtime.vendor,
|
|
4553
4553
|
duration: Date.now() - startTime,
|
|
4554
4554
|
state: runtime.getState()
|
|
@@ -4566,17 +4566,17 @@ function isSqliteNonQueryError(error) {
|
|
|
4566
4566
|
const hasNonQueryMessage = error.message.includes("does not return data");
|
|
4567
4567
|
return isSqliteOrTypeError && hasNonQueryMessage;
|
|
4568
4568
|
}
|
|
4569
|
-
async function checkConnectionHealth(args,
|
|
4569
|
+
async function checkConnectionHealth(args, logger23) {
|
|
4570
4570
|
if (!args.db || !args.client) {
|
|
4571
|
-
|
|
4571
|
+
logger23.debug("Health check failed: connection not initialized", { vendor: args.vendor });
|
|
4572
4572
|
return false;
|
|
4573
4573
|
}
|
|
4574
4574
|
try {
|
|
4575
4575
|
await args.execute(drizzleOrm.sql`SELECT 1`);
|
|
4576
|
-
|
|
4576
|
+
logger23.debug("Health check passed", { vendor: args.vendor });
|
|
4577
4577
|
return true;
|
|
4578
4578
|
} catch (error) {
|
|
4579
|
-
|
|
4579
|
+
logger23.debug("Health check failed", {
|
|
4580
4580
|
vendor: args.vendor,
|
|
4581
4581
|
error: error instanceof Error ? error.message : String(error)
|
|
4582
4582
|
});
|
|
@@ -4619,8 +4619,8 @@ function getConnectionPoolMetrics(vendor, client) {
|
|
|
4619
4619
|
}
|
|
4620
4620
|
|
|
4621
4621
|
// src/data/relational/connection/query-execution.ts
|
|
4622
|
-
async function executeQuery(context, query,
|
|
4623
|
-
|
|
4622
|
+
async function executeQuery(context, query, logger23) {
|
|
4623
|
+
logger23.debug("Executing SQL query", {
|
|
4624
4624
|
vendor: context.vendor
|
|
4625
4625
|
});
|
|
4626
4626
|
if (context.vendor === "sqlite") {
|
|
@@ -5389,7 +5389,8 @@ function buildSelectQuery(input) {
|
|
|
5389
5389
|
}
|
|
5390
5390
|
return query;
|
|
5391
5391
|
}
|
|
5392
|
-
|
|
5392
|
+
|
|
5393
|
+
// src/data/relational/query/batch-executor-options.ts
|
|
5393
5394
|
var DEFAULT_BATCH_SIZE = 100;
|
|
5394
5395
|
var MAX_BATCH_SIZE = 5e3;
|
|
5395
5396
|
var MAX_RETRY_ATTEMPTS = 5;
|
|
@@ -5403,7 +5404,7 @@ function normalizePositiveInt(value, fieldName, min, max, fallback) {
|
|
|
5403
5404
|
}
|
|
5404
5405
|
return value;
|
|
5405
5406
|
}
|
|
5406
|
-
function
|
|
5407
|
+
function resolveBatchExecutionOptions(options) {
|
|
5407
5408
|
return {
|
|
5408
5409
|
batchSize: normalizePositiveInt(options.batchSize, "batchSize", 1, MAX_BATCH_SIZE, DEFAULT_BATCH_SIZE),
|
|
5409
5410
|
continueOnError: options.continueOnError ?? true,
|
|
@@ -5412,7 +5413,7 @@ function resolveOptions(options) {
|
|
|
5412
5413
|
onProgress: options.onProgress
|
|
5413
5414
|
};
|
|
5414
5415
|
}
|
|
5415
|
-
function
|
|
5416
|
+
function chunkBatchItems(items, chunkSize) {
|
|
5416
5417
|
if (items.length === 0) {
|
|
5417
5418
|
return [];
|
|
5418
5419
|
}
|
|
@@ -5422,25 +5423,77 @@ function chunkItems(items, chunkSize) {
|
|
|
5422
5423
|
}
|
|
5423
5424
|
return chunks;
|
|
5424
5425
|
}
|
|
5425
|
-
|
|
5426
|
+
var batchExecutionLogger = core.createLogger("agentforge:tools:data:relational:batch");
|
|
5427
|
+
function toBatchErrorMessage(error) {
|
|
5426
5428
|
return error instanceof Error ? error.message : String(error);
|
|
5427
5429
|
}
|
|
5428
|
-
function
|
|
5430
|
+
function delayBatchRetry(ms) {
|
|
5429
5431
|
return new Promise((resolve2) => {
|
|
5430
5432
|
setTimeout(resolve2, ms);
|
|
5431
5433
|
});
|
|
5432
5434
|
}
|
|
5435
|
+
|
|
5436
|
+
// src/data/relational/query/batch-executor-benchmark.ts
|
|
5437
|
+
function resolveBenchmarkBatchSize(options) {
|
|
5438
|
+
return resolveBatchExecutionOptions({
|
|
5439
|
+
...options,
|
|
5440
|
+
continueOnError: true,
|
|
5441
|
+
maxRetries: 0,
|
|
5442
|
+
retryDelayMs: 0,
|
|
5443
|
+
batchSize: options.batchSize ?? DEFAULT_BATCH_SIZE
|
|
5444
|
+
}).batchSize;
|
|
5445
|
+
}
|
|
5446
|
+
async function benchmarkBatchExecution(params) {
|
|
5447
|
+
const batchSize = resolveBenchmarkBatchSize({
|
|
5448
|
+
batchSize: params.batchSize ?? DEFAULT_BATCH_SIZE
|
|
5449
|
+
});
|
|
5450
|
+
const batches = chunkBatchItems(params.items, Math.min(batchSize, MAX_BATCH_SIZE));
|
|
5451
|
+
const individualStart = Date.now();
|
|
5452
|
+
for (const [index, item] of params.items.entries()) {
|
|
5453
|
+
await params.runIndividual(item, index);
|
|
5454
|
+
}
|
|
5455
|
+
const individualExecutionTime = Date.now() - individualStart;
|
|
5456
|
+
const batchStart = Date.now();
|
|
5457
|
+
for (const [batchIndex, batchItems] of batches.entries()) {
|
|
5458
|
+
await params.runBatch(batchItems, batchIndex);
|
|
5459
|
+
}
|
|
5460
|
+
const batchedExecutionTime = Date.now() - batchStart;
|
|
5461
|
+
const timeSavedMs = Math.max(individualExecutionTime - batchedExecutionTime, 0);
|
|
5462
|
+
const speedupRatio = batchedExecutionTime > 0 ? individualExecutionTime / batchedExecutionTime : 0;
|
|
5463
|
+
const speedupPercent = individualExecutionTime > 0 ? timeSavedMs / individualExecutionTime * 100 : 0;
|
|
5464
|
+
batchExecutionLogger.debug("Batch benchmark completed", {
|
|
5465
|
+
itemCount: params.items.length,
|
|
5466
|
+
batchCount: batches.length,
|
|
5467
|
+
batchSize,
|
|
5468
|
+
individualExecutionTime,
|
|
5469
|
+
batchedExecutionTime,
|
|
5470
|
+
timeSavedMs,
|
|
5471
|
+
speedupPercent
|
|
5472
|
+
});
|
|
5473
|
+
return {
|
|
5474
|
+
itemCount: params.items.length,
|
|
5475
|
+
batchSize,
|
|
5476
|
+
batchCount: batches.length,
|
|
5477
|
+
individualExecutionTime,
|
|
5478
|
+
batchedExecutionTime,
|
|
5479
|
+
timeSavedMs,
|
|
5480
|
+
speedupRatio,
|
|
5481
|
+
speedupPercent
|
|
5482
|
+
};
|
|
5483
|
+
}
|
|
5484
|
+
|
|
5485
|
+
// src/data/relational/query/batch-executor-execution.ts
|
|
5433
5486
|
async function executeBatchedTask(task, options = {}) {
|
|
5434
5487
|
const startTime = Date.now();
|
|
5435
|
-
const resolved =
|
|
5436
|
-
const batches =
|
|
5488
|
+
const resolved = resolveBatchExecutionOptions(options);
|
|
5489
|
+
const batches = chunkBatchItems(task.items, resolved.batchSize);
|
|
5437
5490
|
const results = [];
|
|
5438
5491
|
const failures = [];
|
|
5439
5492
|
let processedItems = 0;
|
|
5440
5493
|
let successfulItems = 0;
|
|
5441
5494
|
let failedItems = 0;
|
|
5442
5495
|
let retries = 0;
|
|
5443
|
-
|
|
5496
|
+
batchExecutionLogger.debug("Starting batched execution", {
|
|
5444
5497
|
operation: task.operation,
|
|
5445
5498
|
totalItems: task.items.length,
|
|
5446
5499
|
totalBatches: batches.length,
|
|
@@ -5479,15 +5532,15 @@ async function executeBatchedTask(task, options = {}) {
|
|
|
5479
5532
|
lastError = error;
|
|
5480
5533
|
if (attempts <= resolved.maxRetries) {
|
|
5481
5534
|
retries += 1;
|
|
5482
|
-
|
|
5535
|
+
batchExecutionLogger.warn("Batch execution failed, retrying", {
|
|
5483
5536
|
operation: task.operation,
|
|
5484
5537
|
batchIndex,
|
|
5485
5538
|
attempts,
|
|
5486
5539
|
maxRetries: resolved.maxRetries,
|
|
5487
|
-
error:
|
|
5540
|
+
error: toBatchErrorMessage(error)
|
|
5488
5541
|
});
|
|
5489
5542
|
if (resolved.retryDelayMs > 0) {
|
|
5490
|
-
await
|
|
5543
|
+
await delayBatchRetry(resolved.retryDelayMs);
|
|
5491
5544
|
}
|
|
5492
5545
|
continue;
|
|
5493
5546
|
}
|
|
@@ -5496,7 +5549,7 @@ async function executeBatchedTask(task, options = {}) {
|
|
|
5496
5549
|
batchIndex,
|
|
5497
5550
|
batchSize: batchItems.length,
|
|
5498
5551
|
attempts,
|
|
5499
|
-
error:
|
|
5552
|
+
error: toBatchErrorMessage(error)
|
|
5500
5553
|
};
|
|
5501
5554
|
failures.push(failure);
|
|
5502
5555
|
processedItems += batchItems.length;
|
|
@@ -5518,7 +5571,7 @@ async function executeBatchedTask(task, options = {}) {
|
|
|
5518
5571
|
{ cause: lastError }
|
|
5519
5572
|
);
|
|
5520
5573
|
}
|
|
5521
|
-
|
|
5574
|
+
batchExecutionLogger.warn("Batch execution failed and was recorded for partial success", {
|
|
5522
5575
|
operation: task.operation,
|
|
5523
5576
|
batchIndex,
|
|
5524
5577
|
attempts,
|
|
@@ -5530,7 +5583,7 @@ async function executeBatchedTask(task, options = {}) {
|
|
|
5530
5583
|
}
|
|
5531
5584
|
const executionTime = Date.now() - startTime;
|
|
5532
5585
|
const partialSuccess = successfulItems > 0 && failedItems > 0;
|
|
5533
|
-
|
|
5586
|
+
batchExecutionLogger.debug("Batched execution completed", {
|
|
5534
5587
|
operation: task.operation,
|
|
5535
5588
|
totalItems: task.items.length,
|
|
5536
5589
|
successfulItems,
|
|
@@ -5552,49 +5605,7 @@ async function executeBatchedTask(task, options = {}) {
|
|
|
5552
5605
|
failures
|
|
5553
5606
|
};
|
|
5554
5607
|
}
|
|
5555
|
-
|
|
5556
|
-
const batchSize = normalizePositiveInt(
|
|
5557
|
-
params.batchSize,
|
|
5558
|
-
"batchSize",
|
|
5559
|
-
1,
|
|
5560
|
-
MAX_BATCH_SIZE,
|
|
5561
|
-
DEFAULT_BATCH_SIZE
|
|
5562
|
-
);
|
|
5563
|
-
const batches = chunkItems(params.items, batchSize);
|
|
5564
|
-
const individualStart = Date.now();
|
|
5565
|
-
for (const [index, item] of params.items.entries()) {
|
|
5566
|
-
await params.runIndividual(item, index);
|
|
5567
|
-
}
|
|
5568
|
-
const individualExecutionTime = Date.now() - individualStart;
|
|
5569
|
-
const batchStart = Date.now();
|
|
5570
|
-
for (const [batchIndex, batchItems] of batches.entries()) {
|
|
5571
|
-
await params.runBatch(batchItems, batchIndex);
|
|
5572
|
-
}
|
|
5573
|
-
const batchedExecutionTime = Date.now() - batchStart;
|
|
5574
|
-
const timeSavedMs = Math.max(individualExecutionTime - batchedExecutionTime, 0);
|
|
5575
|
-
const speedupRatio = batchedExecutionTime > 0 ? individualExecutionTime / batchedExecutionTime : 0;
|
|
5576
|
-
const speedupPercent = individualExecutionTime > 0 ? timeSavedMs / individualExecutionTime * 100 : 0;
|
|
5577
|
-
logger10.debug("Batch benchmark completed", {
|
|
5578
|
-
itemCount: params.items.length,
|
|
5579
|
-
batchCount: batches.length,
|
|
5580
|
-
batchSize,
|
|
5581
|
-
individualExecutionTime,
|
|
5582
|
-
batchedExecutionTime,
|
|
5583
|
-
timeSavedMs,
|
|
5584
|
-
speedupPercent
|
|
5585
|
-
});
|
|
5586
|
-
return {
|
|
5587
|
-
itemCount: params.items.length,
|
|
5588
|
-
batchSize,
|
|
5589
|
-
batchCount: batches.length,
|
|
5590
|
-
individualExecutionTime,
|
|
5591
|
-
batchedExecutionTime,
|
|
5592
|
-
timeSavedMs,
|
|
5593
|
-
speedupRatio,
|
|
5594
|
-
speedupPercent
|
|
5595
|
-
};
|
|
5596
|
-
}
|
|
5597
|
-
var logger11 = core.createLogger("agentforge:tools:data:relational:stream");
|
|
5608
|
+
var logger10 = core.createLogger("agentforge:tools:data:relational:stream");
|
|
5598
5609
|
var DEFAULT_CHUNK_SIZE = 100;
|
|
5599
5610
|
var MAX_CHUNK_SIZE = 5e3;
|
|
5600
5611
|
var DEFAULT_SAMPLE_SIZE = 50;
|
|
@@ -5727,7 +5738,7 @@ async function executeStreamingSelect(executor, input, options = {}) {
|
|
|
5727
5738
|
const endHeapUsed = process.memoryUsage().heapUsed;
|
|
5728
5739
|
peakHeapUsed = Math.max(peakHeapUsed, endHeapUsed);
|
|
5729
5740
|
const executionTime = Date.now() - startTime;
|
|
5730
|
-
|
|
5741
|
+
logger10.debug("Streaming SELECT execution completed", {
|
|
5731
5742
|
table: input.table,
|
|
5732
5743
|
vendor: input.vendor,
|
|
5733
5744
|
chunkCount,
|
|
@@ -5751,7 +5762,7 @@ async function executeStreamingSelect(executor, input, options = {}) {
|
|
|
5751
5762
|
};
|
|
5752
5763
|
}
|
|
5753
5764
|
async function benchmarkStreamingSelectMemory(executor, input, options = {}) {
|
|
5754
|
-
|
|
5765
|
+
logger10.warn("Running streaming benchmark will execute the SELECT query twice (regular + streaming).", {
|
|
5755
5766
|
table: input.table,
|
|
5756
5767
|
vendor: input.vendor
|
|
5757
5768
|
});
|
|
@@ -5771,7 +5782,7 @@ async function benchmarkStreamingSelectMemory(executor, input, options = {}) {
|
|
|
5771
5782
|
0
|
|
5772
5783
|
);
|
|
5773
5784
|
const memorySavedPercent = nonStreamingPeakHeapUsed > 0 ? memorySavedBytes / nonStreamingPeakHeapUsed * 100 : 0;
|
|
5774
|
-
|
|
5785
|
+
logger10.debug("Streaming benchmark completed", {
|
|
5775
5786
|
table: input.table,
|
|
5776
5787
|
vendor: input.vendor,
|
|
5777
5788
|
nonStreamingRows: nonStreamingRows.length,
|
|
@@ -5843,7 +5854,7 @@ function withTransactionTimeout(operation, timeoutMs, onTimeout) {
|
|
|
5843
5854
|
}
|
|
5844
5855
|
|
|
5845
5856
|
// src/data/relational/query/transaction-managed.ts
|
|
5846
|
-
var
|
|
5857
|
+
var logger11 = core.createLogger("agentforge:tools:data:relational:transaction");
|
|
5847
5858
|
var SAVEPOINT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
5848
5859
|
var ManagedTransaction = class {
|
|
5849
5860
|
id;
|
|
@@ -5951,7 +5962,7 @@ var ManagedTransaction = class {
|
|
|
5951
5962
|
await this.executeQuery(drizzleOrm.sql.raw("PRAGMA read_uncommitted = 1"));
|
|
5952
5963
|
this.shouldRestoreSqliteReadUncommitted = true;
|
|
5953
5964
|
} else {
|
|
5954
|
-
|
|
5965
|
+
logger11.debug("Ignoring SQLite isolation level override", {
|
|
5955
5966
|
transactionId: this.id,
|
|
5956
5967
|
isolationLevel: this.options.isolationLevel
|
|
5957
5968
|
});
|
|
@@ -5976,7 +5987,7 @@ var ManagedTransaction = class {
|
|
|
5976
5987
|
const targetValue = this.sqliteReadUncommittedOriginal ?? 0;
|
|
5977
5988
|
await this.executeQuery(drizzleOrm.sql.raw(`PRAGMA read_uncommitted = ${targetValue}`));
|
|
5978
5989
|
} catch (error) {
|
|
5979
|
-
|
|
5990
|
+
logger11.warn("Failed to restore SQLite read_uncommitted pragma", {
|
|
5980
5991
|
transactionId: this.id,
|
|
5981
5992
|
error: error instanceof Error ? error.message : String(error)
|
|
5982
5993
|
});
|
|
@@ -6002,14 +6013,14 @@ var ManagedTransaction = class {
|
|
|
6002
6013
|
};
|
|
6003
6014
|
|
|
6004
6015
|
// src/data/relational/query/transaction-runner.ts
|
|
6005
|
-
var
|
|
6016
|
+
var logger12 = core.createLogger("agentforge:tools:data:relational:transaction");
|
|
6006
6017
|
var transactionSequence = 0;
|
|
6007
6018
|
async function withTransaction(manager, operation, options) {
|
|
6008
6019
|
const startTime = Date.now();
|
|
6009
6020
|
const resolvedOptions = resolveTransactionOptions(options);
|
|
6010
6021
|
const transactionId = `tx-${++transactionSequence}`;
|
|
6011
6022
|
const vendor = manager.getVendor();
|
|
6012
|
-
|
|
6023
|
+
logger12.debug("Starting transaction", {
|
|
6013
6024
|
transactionId,
|
|
6014
6025
|
vendor,
|
|
6015
6026
|
...resolvedOptions.isolationLevel ? { isolationLevel: resolvedOptions.isolationLevel } : {},
|
|
@@ -6036,7 +6047,7 @@ async function withTransaction(manager, operation, options) {
|
|
|
6036
6047
|
if (transaction.isActive()) {
|
|
6037
6048
|
await transaction.commit();
|
|
6038
6049
|
}
|
|
6039
|
-
|
|
6050
|
+
logger12.debug("Transaction committed", {
|
|
6040
6051
|
transactionId,
|
|
6041
6052
|
vendor,
|
|
6042
6053
|
duration: Date.now() - startTime
|
|
@@ -6047,14 +6058,14 @@ async function withTransaction(manager, operation, options) {
|
|
|
6047
6058
|
try {
|
|
6048
6059
|
await transaction.rollback();
|
|
6049
6060
|
} catch (rollbackError) {
|
|
6050
|
-
|
|
6061
|
+
logger12.error("Transaction rollback failed", {
|
|
6051
6062
|
transactionId,
|
|
6052
6063
|
vendor,
|
|
6053
6064
|
error: rollbackError instanceof Error ? rollbackError.message : String(rollbackError)
|
|
6054
6065
|
});
|
|
6055
6066
|
}
|
|
6056
6067
|
}
|
|
6057
|
-
|
|
6068
|
+
logger12.error("Transaction failed", {
|
|
6058
6069
|
transactionId,
|
|
6059
6070
|
vendor,
|
|
6060
6071
|
duration: Date.now() - startTime,
|
|
@@ -6545,7 +6556,7 @@ async function inspectSQLite(runQueryRows) {
|
|
|
6545
6556
|
}
|
|
6546
6557
|
|
|
6547
6558
|
// src/data/relational/schema/schema-inspector.ts
|
|
6548
|
-
var
|
|
6559
|
+
var logger13 = core.createLogger("agentforge:tools:data:relational:schema-inspector");
|
|
6549
6560
|
var DEFAULT_CACHE_TTL_MS = 6e4;
|
|
6550
6561
|
var schemaCache = /* @__PURE__ */ new Map();
|
|
6551
6562
|
var SchemaInspector = class _SchemaInspector {
|
|
@@ -6573,7 +6584,7 @@ var SchemaInspector = class _SchemaInspector {
|
|
|
6573
6584
|
if (!bypassCache && this.cacheKey) {
|
|
6574
6585
|
const cached = schemaCache.get(this.cacheKey);
|
|
6575
6586
|
if (cached && cached.expiresAt > Date.now()) {
|
|
6576
|
-
|
|
6587
|
+
logger13.debug("Schema cache hit", { vendor: this.vendor });
|
|
6577
6588
|
return filterSchemaTables(cloneSchema(cached.schema), tableFilters);
|
|
6578
6589
|
}
|
|
6579
6590
|
}
|
|
@@ -6618,7 +6629,7 @@ var SchemaInspector = class _SchemaInspector {
|
|
|
6618
6629
|
return result.rows;
|
|
6619
6630
|
}
|
|
6620
6631
|
};
|
|
6621
|
-
var
|
|
6632
|
+
var logger14 = core.createLogger("agentforge:tools:data:relational:schema-validator");
|
|
6622
6633
|
function validateTableExists(schema, tableName) {
|
|
6623
6634
|
const errors = [];
|
|
6624
6635
|
if (!tableName || typeof tableName !== "string") {
|
|
@@ -6632,7 +6643,7 @@ function validateTableExists(schema, tableName) {
|
|
|
6632
6643
|
`Table "${tableName}" does not exist. Available tables: ${available || "(none)"}`
|
|
6633
6644
|
);
|
|
6634
6645
|
}
|
|
6635
|
-
|
|
6646
|
+
logger14.debug("Table existence validation", { tableName, valid: errors.length === 0 });
|
|
6636
6647
|
return { valid: errors.length === 0, errors };
|
|
6637
6648
|
}
|
|
6638
6649
|
function validateColumnsExist(schema, tableName, columnNames) {
|
|
@@ -6655,7 +6666,7 @@ function validateColumnsExist(schema, tableName, columnNames) {
|
|
|
6655
6666
|
);
|
|
6656
6667
|
}
|
|
6657
6668
|
}
|
|
6658
|
-
|
|
6669
|
+
logger14.debug("Column existence validation", {
|
|
6659
6670
|
tableName,
|
|
6660
6671
|
columnCount: columnNames.length,
|
|
6661
6672
|
valid: errors.length === 0
|
|
@@ -6691,7 +6702,7 @@ function validateColumnTypes(schema, tableName, expectedTypes) {
|
|
|
6691
6702
|
);
|
|
6692
6703
|
}
|
|
6693
6704
|
}
|
|
6694
|
-
|
|
6705
|
+
logger14.debug("Column type validation", {
|
|
6695
6706
|
tableName,
|
|
6696
6707
|
typeChecks: Object.keys(expectedTypes).length,
|
|
6697
6708
|
valid: errors.length === 0
|
|
@@ -6711,7 +6722,7 @@ function findTable(schema, tableName) {
|
|
|
6711
6722
|
function formatTableName(table) {
|
|
6712
6723
|
return table.schema ? `${table.schema}.${table.name}` : table.name;
|
|
6713
6724
|
}
|
|
6714
|
-
var
|
|
6725
|
+
var logger15 = core.createLogger("agentforge:tools:data:relational:type-mapper");
|
|
6715
6726
|
var POSTGRES_TYPE_MAP = {
|
|
6716
6727
|
// Numeric
|
|
6717
6728
|
smallint: "number",
|
|
@@ -6877,7 +6888,7 @@ function mapColumnType(vendor, dbType, nullable = false) {
|
|
|
6877
6888
|
const result = { tsType, nullable, dbType };
|
|
6878
6889
|
if (tsType === "unknown" && normalised !== "json" && normalised !== "jsonb") {
|
|
6879
6890
|
result.notes = `No explicit mapping for "${dbType}"; defaulting to unknown`;
|
|
6880
|
-
|
|
6891
|
+
logger15.debug("Unmapped database type", { vendor, dbType, normalised });
|
|
6881
6892
|
}
|
|
6882
6893
|
if ((normalised === "bigint" || normalised === "int8" || normalised === "bigserial") && (vendor === "postgresql" || vendor === "mysql")) {
|
|
6883
6894
|
result.notes = "Mapped to string to avoid JavaScript number precision loss for 64-bit integers";
|
|
@@ -6892,7 +6903,7 @@ function mapSchemaTypes(vendor, columns) {
|
|
|
6892
6903
|
}
|
|
6893
6904
|
result.get(col.table).set(col.name, mapColumnType(vendor, col.type, col.nullable));
|
|
6894
6905
|
}
|
|
6895
|
-
|
|
6906
|
+
logger15.debug("Schema type mapping complete", {
|
|
6896
6907
|
vendor,
|
|
6897
6908
|
tables: result.size,
|
|
6898
6909
|
columns: columns.length
|
|
@@ -6909,7 +6920,7 @@ function normaliseDbType(raw) {
|
|
|
6909
6920
|
type = type.replace(/\s+unsigned$/, "");
|
|
6910
6921
|
return type.trim();
|
|
6911
6922
|
}
|
|
6912
|
-
var
|
|
6923
|
+
var logger16 = core.createLogger("agentforge:tools:data:relational:schema-diff");
|
|
6913
6924
|
function diffSchemas(before, after) {
|
|
6914
6925
|
const tableDiffs = [];
|
|
6915
6926
|
let columnsAdded = 0;
|
|
@@ -6949,7 +6960,7 @@ function diffSchemas(before, after) {
|
|
|
6949
6960
|
const tablesRemoved = tableDiffs.filter((d) => d.type === "removed").length;
|
|
6950
6961
|
const tablesChanged = tableDiffs.filter((d) => d.type === "changed").length;
|
|
6951
6962
|
const identical = tableDiffs.length === 0;
|
|
6952
|
-
|
|
6963
|
+
logger16.debug("Schema diff computed", {
|
|
6953
6964
|
identical,
|
|
6954
6965
|
tablesAdded,
|
|
6955
6966
|
tablesRemoved,
|
|
@@ -6993,7 +7004,7 @@ function importSchemaFromJson(json) {
|
|
|
6993
7004
|
throw new Error(`Invalid schema JSON: table "${table.name}" missing "primaryKey" array`);
|
|
6994
7005
|
}
|
|
6995
7006
|
}
|
|
6996
|
-
|
|
7007
|
+
logger16.debug("Schema imported from JSON", {
|
|
6997
7008
|
vendor: obj.vendor,
|
|
6998
7009
|
tableCount: obj.tables.length
|
|
6999
7010
|
});
|
|
@@ -7290,7 +7301,7 @@ function isSafeValidationError(error) {
|
|
|
7290
7301
|
}
|
|
7291
7302
|
|
|
7292
7303
|
// src/data/relational/tools/relational-select/executor.ts
|
|
7293
|
-
var
|
|
7304
|
+
var logger17 = core.createLogger("agentforge:tools:data:relational:select");
|
|
7294
7305
|
function toSelectQueryInput(input) {
|
|
7295
7306
|
return {
|
|
7296
7307
|
table: input.table,
|
|
@@ -7304,7 +7315,7 @@ function toSelectQueryInput(input) {
|
|
|
7304
7315
|
}
|
|
7305
7316
|
async function executeSelect(manager, input, context) {
|
|
7306
7317
|
const startTime = Date.now();
|
|
7307
|
-
|
|
7318
|
+
logger17.debug("Building SELECT query", {
|
|
7308
7319
|
vendor: input.vendor,
|
|
7309
7320
|
table: input.table,
|
|
7310
7321
|
hasWhere: !!input.where,
|
|
@@ -7322,7 +7333,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7322
7333
|
};
|
|
7323
7334
|
const streamInput = toSelectQueryInput(input);
|
|
7324
7335
|
if (input.streaming.benchmark) {
|
|
7325
|
-
|
|
7336
|
+
logger17.warn("Streaming benchmark enabled; SELECT will execute up to three times (result + benchmark regular + benchmark streaming).", {
|
|
7326
7337
|
vendor: input.vendor,
|
|
7327
7338
|
table: input.table,
|
|
7328
7339
|
chunkSize: streamOptions.chunkSize ?? DEFAULT_CHUNK_SIZE,
|
|
@@ -7333,7 +7344,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7333
7344
|
const streamResult = await executeStreamingSelect(executor, streamInput, streamOptions);
|
|
7334
7345
|
const benchmark = input.streaming.benchmark ? await benchmarkStreamingSelectMemory(executor, streamInput, streamOptions) : void 0;
|
|
7335
7346
|
const executionTime2 = Date.now() - startTime;
|
|
7336
|
-
|
|
7347
|
+
logger17.debug("Streaming SELECT query executed successfully", {
|
|
7337
7348
|
vendor: input.vendor,
|
|
7338
7349
|
table: input.table,
|
|
7339
7350
|
rowCount: streamResult.rowCount,
|
|
@@ -7362,7 +7373,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7362
7373
|
const executionTime = Date.now() - startTime;
|
|
7363
7374
|
const rows = Array.isArray(result) ? result : result.rows || [];
|
|
7364
7375
|
const rowCount = rows.length;
|
|
7365
|
-
|
|
7376
|
+
logger17.debug("SELECT query executed successfully", {
|
|
7366
7377
|
vendor: input.vendor,
|
|
7367
7378
|
table: input.table,
|
|
7368
7379
|
rowCount,
|
|
@@ -7375,7 +7386,7 @@ async function executeSelect(manager, input, context) {
|
|
|
7375
7386
|
};
|
|
7376
7387
|
} catch (error) {
|
|
7377
7388
|
const executionTime = Date.now() - startTime;
|
|
7378
|
-
|
|
7389
|
+
logger17.error("SELECT query execution failed", {
|
|
7379
7390
|
vendor: input.vendor,
|
|
7380
7391
|
table: input.table,
|
|
7381
7392
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -7551,7 +7562,7 @@ function isSafeInsertError(error) {
|
|
|
7551
7562
|
}
|
|
7552
7563
|
|
|
7553
7564
|
// src/data/relational/tools/relational-insert/executor.ts
|
|
7554
|
-
var
|
|
7565
|
+
var logger18 = core.createLogger("agentforge:tools:data:relational:insert");
|
|
7555
7566
|
function toNumber(value) {
|
|
7556
7567
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
7557
7568
|
}
|
|
@@ -7700,7 +7711,7 @@ async function executeInsertInBatchMode(manager, input, context, options) {
|
|
|
7700
7711
|
maxRetries: options.maxRetries,
|
|
7701
7712
|
retryDelayMs: options.retryDelayMs,
|
|
7702
7713
|
onProgress: (progress) => {
|
|
7703
|
-
|
|
7714
|
+
logger18.debug("INSERT batch progress", {
|
|
7704
7715
|
vendor: input.vendor,
|
|
7705
7716
|
table: input.table,
|
|
7706
7717
|
...progress
|
|
@@ -7713,7 +7724,7 @@ async function executeInsertInBatchMode(manager, input, context, options) {
|
|
|
7713
7724
|
const insertedIds = batchResult.results.flatMap((result) => result.insertedIds);
|
|
7714
7725
|
let benchmark;
|
|
7715
7726
|
if (options.benchmark) {
|
|
7716
|
-
|
|
7727
|
+
logger18.warn("INSERT batch benchmark enabled. Synthetic benchmark callbacks are side-effect free and do not execute SQL.", {
|
|
7717
7728
|
vendor: input.vendor,
|
|
7718
7729
|
table: input.table,
|
|
7719
7730
|
totalRows: input.data.length,
|
|
@@ -7750,7 +7761,7 @@ async function executeInsertInBatchMode(manager, input, context, options) {
|
|
|
7750
7761
|
}
|
|
7751
7762
|
async function executeInsert(manager, input, context) {
|
|
7752
7763
|
const startTime = Date.now();
|
|
7753
|
-
|
|
7764
|
+
logger18.debug("Building INSERT query", {
|
|
7754
7765
|
vendor: input.vendor,
|
|
7755
7766
|
table: input.table,
|
|
7756
7767
|
isBatch: Array.isArray(input.data),
|
|
@@ -7766,7 +7777,7 @@ async function executeInsert(manager, input, context) {
|
|
|
7766
7777
|
batchOptions
|
|
7767
7778
|
) : await executeInsertOnce(manager, input, context);
|
|
7768
7779
|
const executionTime = Date.now() - startTime;
|
|
7769
|
-
|
|
7780
|
+
logger18.debug("INSERT query executed successfully", {
|
|
7770
7781
|
vendor: input.vendor,
|
|
7771
7782
|
table: input.table,
|
|
7772
7783
|
rowCount: result.rowCount,
|
|
@@ -7782,7 +7793,7 @@ async function executeInsert(manager, input, context) {
|
|
|
7782
7793
|
};
|
|
7783
7794
|
} catch (error) {
|
|
7784
7795
|
const executionTime = Date.now() - startTime;
|
|
7785
|
-
|
|
7796
|
+
logger18.error("INSERT query execution failed", {
|
|
7786
7797
|
vendor: input.vendor,
|
|
7787
7798
|
table: input.table,
|
|
7788
7799
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -8112,7 +8123,7 @@ function isSafeUpdateError(error) {
|
|
|
8112
8123
|
}
|
|
8113
8124
|
|
|
8114
8125
|
// src/data/relational/tools/relational-update/executor.ts
|
|
8115
|
-
var
|
|
8126
|
+
var logger19 = core.createLogger("agentforge:tools:data:relational:update");
|
|
8116
8127
|
function toNumber2(value) {
|
|
8117
8128
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
8118
8129
|
}
|
|
@@ -8133,7 +8144,7 @@ function normalizeAffectedRows(result) {
|
|
|
8133
8144
|
}
|
|
8134
8145
|
return 0;
|
|
8135
8146
|
}
|
|
8136
|
-
function
|
|
8147
|
+
function toErrorMessage(error) {
|
|
8137
8148
|
return error instanceof Error ? error.message : String(error);
|
|
8138
8149
|
}
|
|
8139
8150
|
function resolveBatchOptions2(batch) {
|
|
@@ -8215,7 +8226,7 @@ async function executeUpdateInBatchMode(manager, input, context, options) {
|
|
|
8215
8226
|
batchIndex,
|
|
8216
8227
|
batchSize: operations.length,
|
|
8217
8228
|
attempts: 1,
|
|
8218
|
-
error:
|
|
8229
|
+
error: toErrorMessage(error)
|
|
8219
8230
|
});
|
|
8220
8231
|
}
|
|
8221
8232
|
}
|
|
@@ -8234,7 +8245,7 @@ async function executeUpdateInBatchMode(manager, input, context, options) {
|
|
|
8234
8245
|
maxRetries: options.maxRetries,
|
|
8235
8246
|
retryDelayMs: options.retryDelayMs,
|
|
8236
8247
|
onProgress: (progress) => {
|
|
8237
|
-
|
|
8248
|
+
logger19.debug("UPDATE batch progress", {
|
|
8238
8249
|
vendor: input.vendor,
|
|
8239
8250
|
table: input.table,
|
|
8240
8251
|
...progress
|
|
@@ -8246,7 +8257,7 @@ async function executeUpdateInBatchMode(manager, input, context, options) {
|
|
|
8246
8257
|
const operationFailures = batchResult.results.flatMap((result) => result.failures);
|
|
8247
8258
|
let benchmark;
|
|
8248
8259
|
if (options.benchmark) {
|
|
8249
|
-
|
|
8260
|
+
logger19.warn("UPDATE batch benchmark enabled. Synthetic benchmark callbacks are side-effect free and do not execute SQL.", {
|
|
8250
8261
|
vendor: input.vendor,
|
|
8251
8262
|
table: input.table,
|
|
8252
8263
|
operationCount: input.operations.length,
|
|
@@ -8281,7 +8292,7 @@ async function executeUpdateInBatchMode(manager, input, context, options) {
|
|
|
8281
8292
|
}
|
|
8282
8293
|
async function executeUpdate(manager, input, context) {
|
|
8283
8294
|
const startTime = Date.now();
|
|
8284
|
-
|
|
8295
|
+
logger19.debug("Building UPDATE query", {
|
|
8285
8296
|
vendor: input.vendor,
|
|
8286
8297
|
table: input.table,
|
|
8287
8298
|
hasWhere: !!input.where?.length,
|
|
@@ -8299,7 +8310,7 @@ async function executeUpdate(manager, input, context) {
|
|
|
8299
8310
|
batchOptions
|
|
8300
8311
|
) : await executeSingleUpdate(manager, input, toSingleUpdateOperation(input), context);
|
|
8301
8312
|
const executionTime = Date.now() - startTime;
|
|
8302
|
-
|
|
8313
|
+
logger19.debug("UPDATE query executed successfully", {
|
|
8303
8314
|
vendor: input.vendor,
|
|
8304
8315
|
table: input.table,
|
|
8305
8316
|
rowCount: result.rowCount,
|
|
@@ -8313,7 +8324,7 @@ async function executeUpdate(manager, input, context) {
|
|
|
8313
8324
|
};
|
|
8314
8325
|
} catch (error) {
|
|
8315
8326
|
const executionTime = Date.now() - startTime;
|
|
8316
|
-
|
|
8327
|
+
logger19.error("UPDATE query execution failed", {
|
|
8317
8328
|
vendor: input.vendor,
|
|
8318
8329
|
table: input.table,
|
|
8319
8330
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -8617,7 +8628,7 @@ function isSafeDeleteError(error) {
|
|
|
8617
8628
|
}
|
|
8618
8629
|
|
|
8619
8630
|
// src/data/relational/tools/relational-delete/executor.ts
|
|
8620
|
-
var
|
|
8631
|
+
var logger20 = core.createLogger("agentforge:tools:data:relational:delete");
|
|
8621
8632
|
function toNumber3(value) {
|
|
8622
8633
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
8623
8634
|
}
|
|
@@ -8638,7 +8649,7 @@ function normalizeAffectedRows2(result) {
|
|
|
8638
8649
|
}
|
|
8639
8650
|
return 0;
|
|
8640
8651
|
}
|
|
8641
|
-
function
|
|
8652
|
+
function toErrorMessage2(error) {
|
|
8642
8653
|
return error instanceof Error ? error.message : String(error);
|
|
8643
8654
|
}
|
|
8644
8655
|
function resolveBatchOptions3(batch) {
|
|
@@ -8718,7 +8729,7 @@ async function executeDeleteInBatchMode(manager, input, context, options) {
|
|
|
8718
8729
|
batchIndex,
|
|
8719
8730
|
batchSize: operations.length,
|
|
8720
8731
|
attempts: 1,
|
|
8721
|
-
error:
|
|
8732
|
+
error: toErrorMessage2(error)
|
|
8722
8733
|
});
|
|
8723
8734
|
}
|
|
8724
8735
|
}
|
|
@@ -8738,7 +8749,7 @@ async function executeDeleteInBatchMode(manager, input, context, options) {
|
|
|
8738
8749
|
maxRetries: options.maxRetries,
|
|
8739
8750
|
retryDelayMs: options.retryDelayMs,
|
|
8740
8751
|
onProgress: (progress) => {
|
|
8741
|
-
|
|
8752
|
+
logger20.debug("DELETE batch progress", {
|
|
8742
8753
|
vendor: input.vendor,
|
|
8743
8754
|
table: input.table,
|
|
8744
8755
|
...progress
|
|
@@ -8751,7 +8762,7 @@ async function executeDeleteInBatchMode(manager, input, context, options) {
|
|
|
8751
8762
|
const operationFailures = batchResult.results.flatMap((result) => result.failures);
|
|
8752
8763
|
let benchmark;
|
|
8753
8764
|
if (options.benchmark) {
|
|
8754
|
-
|
|
8765
|
+
logger20.warn("DELETE batch benchmark enabled. Synthetic benchmark callbacks are side-effect free and do not execute SQL.", {
|
|
8755
8766
|
vendor: input.vendor,
|
|
8756
8767
|
table: input.table,
|
|
8757
8768
|
operationCount: input.operations.length,
|
|
@@ -8787,7 +8798,7 @@ async function executeDeleteInBatchMode(manager, input, context, options) {
|
|
|
8787
8798
|
}
|
|
8788
8799
|
async function executeDelete(manager, input, context) {
|
|
8789
8800
|
const startTime = Date.now();
|
|
8790
|
-
|
|
8801
|
+
logger20.debug("Building DELETE query", {
|
|
8791
8802
|
vendor: input.vendor,
|
|
8792
8803
|
table: input.table,
|
|
8793
8804
|
hasWhere: !!input.where?.length,
|
|
@@ -8806,7 +8817,7 @@ async function executeDelete(manager, input, context) {
|
|
|
8806
8817
|
batchOptions
|
|
8807
8818
|
) : await executeSingleDelete(manager, input, toSingleDeleteOperation(input), context);
|
|
8808
8819
|
const executionTime = Date.now() - startTime;
|
|
8809
|
-
|
|
8820
|
+
logger20.debug("DELETE query executed successfully", {
|
|
8810
8821
|
vendor: input.vendor,
|
|
8811
8822
|
table: input.table,
|
|
8812
8823
|
rowCount: result.rowCount,
|
|
@@ -8822,7 +8833,7 @@ async function executeDelete(manager, input, context) {
|
|
|
8822
8833
|
};
|
|
8823
8834
|
} catch (error) {
|
|
8824
8835
|
const executionTime = Date.now() - startTime;
|
|
8825
|
-
|
|
8836
|
+
logger20.error("DELETE query execution failed", {
|
|
8826
8837
|
vendor: input.vendor,
|
|
8827
8838
|
table: input.table,
|
|
8828
8839
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -8927,7 +8938,7 @@ function isSafeGetSchemaValidationError(error) {
|
|
|
8927
8938
|
}
|
|
8928
8939
|
|
|
8929
8940
|
// src/data/relational/tools/relational-get-schema.ts
|
|
8930
|
-
var
|
|
8941
|
+
var logger21 = core.createLogger("agentforge:tools:data:relational:get-schema");
|
|
8931
8942
|
function buildSchemaCacheKey(vendor, connectionString, database) {
|
|
8932
8943
|
const databaseScope = database ?? "default";
|
|
8933
8944
|
const connectionHash = crypto.createHash("sha256").update(connectionString).digest("hex");
|
|
@@ -8999,7 +9010,7 @@ var relationalGetSchema = core.toolBuilder().name("relational-get-schema").displ
|
|
|
8999
9010
|
summary
|
|
9000
9011
|
};
|
|
9001
9012
|
} catch (error) {
|
|
9002
|
-
|
|
9013
|
+
logger21.error("Schema introspection failed", {
|
|
9003
9014
|
vendor: input.vendor,
|
|
9004
9015
|
hasTablesFilter: Array.isArray(input.tables),
|
|
9005
9016
|
tablesFilterCount: input.tables?.length ?? 0,
|
|
@@ -10165,7 +10176,7 @@ var AskHumanInputSchema = zod.z.object({
|
|
|
10165
10176
|
suggestions: zod.z.array(zod.z.string()).optional().describe("Suggested responses for the human")
|
|
10166
10177
|
});
|
|
10167
10178
|
var logLevel3 = process.env.LOG_LEVEL?.toLowerCase() || core.LogLevel.INFO;
|
|
10168
|
-
var
|
|
10179
|
+
var logger22 = core.createLogger("agentforge:tools:agent:ask-human", { level: logLevel3 });
|
|
10169
10180
|
function isRecord2(value) {
|
|
10170
10181
|
return typeof value === "object" && value !== null;
|
|
10171
10182
|
}
|
|
@@ -10230,7 +10241,7 @@ function createAskHumanTool() {
|
|
|
10230
10241
|
suggestions: validatedInput.suggestions,
|
|
10231
10242
|
status: "pending"
|
|
10232
10243
|
};
|
|
10233
|
-
|
|
10244
|
+
logger22.debug("About to call interrupt()", {
|
|
10234
10245
|
humanRequest: {
|
|
10235
10246
|
id: humanRequest.id,
|
|
10236
10247
|
question: humanRequest.question,
|
|
@@ -10246,13 +10257,13 @@ function createAskHumanTool() {
|
|
|
10246
10257
|
let response;
|
|
10247
10258
|
try {
|
|
10248
10259
|
response = interrupt(humanRequest);
|
|
10249
|
-
|
|
10260
|
+
logger22.debug("interrupt() returned successfully", {
|
|
10250
10261
|
responseType: typeof response,
|
|
10251
10262
|
hasResponse: response != null,
|
|
10252
10263
|
...typeof response === "string" ? { responseLength: response.length } : {}
|
|
10253
10264
|
});
|
|
10254
10265
|
} catch (error) {
|
|
10255
|
-
|
|
10266
|
+
logger22.debug("interrupt() threw error (expected for GraphInterrupt)", {
|
|
10256
10267
|
...error && typeof error === "object" && "constructor" in error ? { errorType: error.constructor?.name } : {},
|
|
10257
10268
|
error: error instanceof Error ? error.message : String(error)
|
|
10258
10269
|
});
|