fix(agent-tools): include recursively fetched child sections in output

Previously when recursive=true, child sections were fetched into sectionsData
but never included in the returned sections array. Now child sections are
properly appended to the output when recursive fetching is enabled.

- Refactor section building from .map() to for..of for clarity
- Add logic to append child sections not in original request
- Add test coverage for recursive child section inclusion
This commit is contained in:
2026-04-22 13:43:13 +05:30
parent afd7c465d7
commit ee233859a7
2 changed files with 58 additions and 15 deletions
+41 -14
View File
@@ -126,8 +126,10 @@ export function createGetSectionContentTool(table: Table) {
// Sort by partindex to maintain order (nulls last for single-part sections) // Sort by partindex to maintain order (nulls last for single-part sections)
const sortedResults = results.sort((a: unknown, b: unknown) => { const sortedResults = results.sort((a: unknown, b: unknown) => {
const aIndex = (a as { partindex?: number }).partindex ?? Infinity; const aIndex =
const bIndex = (b as { partindex?: number }).partindex ?? Infinity; (a as { partindex?: number }).partindex ?? Infinity;
const bIndex =
(b as { partindex?: number }).partindex ?? Infinity;
return aIndex - bIndex; return aIndex - bIndex;
}); });
@@ -168,26 +170,51 @@ export function createGetSectionContentTool(table: Table) {
} }
} }
// Build output array from all requested sections // Build output array from all fetched sections
// Missing sections are included with found: false and error message // Missing originally requested sections are included with found: false
const sections = sectionIds.map((id) => { const sections: {
sectionId: string;
content: string;
found: boolean;
error?: string;
sectionTitle?: string;
childrensectionids?: string[];
}[] = [];
for (const id of sectionIds) {
const data = sectionsData.get(id); const data = sectionsData.get(id);
if (data) { if (data) {
return { sections.push({
sectionId: id, sectionId: id,
content: data.content.join("\n\n"), content: data.content.join("\n\n"),
found: true, found: true,
sectionTitle: data.title, sectionTitle: data.title,
childrensectionids: data.childrenSectionIds, childrensectionids: data.childrenSectionIds,
}; });
} else {
sections.push({
sectionId: id,
content: "",
found: false,
error: `Section '${id}' not found in database`,
});
} }
return { }
sectionId: id,
content: "", // Include recursively fetched child sections that were not in the original request
found: false, if (recursive) {
error: `Section '${id}' not found in database`, for (const [id, data] of sectionsData) {
}; if (!sectionIds.includes(id)) {
}); sections.push({
sectionId: id,
content: data.content.join("\n\n"),
found: true,
sectionTitle: data.title,
childrensectionids: data.childrenSectionIds,
});
}
}
}
const totalSectionsFetched = sectionsData.size; const totalSectionsFetched = sectionsData.size;
const totalContentLength = sections.reduce( const totalContentLength = sections.reduce(
+16
View File
@@ -108,6 +108,22 @@ describe("getSectionContent", () => {
expect(requestedSection?.found).toBe(true); expect(requestedSection?.found).toBe(true);
}); });
test("should include recursively fetched child sections in output", async () => {
const result = await getContentTool({
sectionIds: ["sec-catch-clause"],
recursive: true,
});
// sec-catch-clause has sec-try-statement as a child in mock data
const childSection = result.sections.find(
(s) => s.sectionId === "sec-try-statement",
);
expect(childSection).toBeDefined();
expect(childSection?.found).toBe(true);
expect(childSection?.content).toBeString();
expect(childSection?.content.length).toBeGreaterThan(0);
});
test("should preserve input order in output", async () => { test("should preserve input order in output", async () => {
const sectionIds = ["sec-for-statement", "sec-if-statement"]; const sectionIds = ["sec-for-statement", "sec-if-statement"];
const result = await getContentTool({ const result = await getContentTool({