feat(ai-assist): add docs generation with folder and collection context (#8246)

This commit is contained in:
Utkarsh
2026-06-22 11:38:28 +05:30
committed by GitHub
parent ccf62641dd
commit fd30eaeccf
9 changed files with 679 additions and 38 deletions

View File

@@ -1,4 +1,5 @@
import { callIpc } from 'utils/common/ipc';
import { isItemAFolder, isItemARequest, sortItemsBySidebarOrder } from 'utils/collections';
/**
* Renderer-side wrapper around the AI IPC channels.
@@ -41,6 +42,66 @@ export const buildRequestContextFromItem = (item) => {
};
};
const summarizeDocsItems = (items = []) => {
const folders = [];
const requests = [];
for (const item of sortItemsBySidebarOrder(items)) {
if (item.isTransient) continue;
if (isItemAFolder(item)) {
const nestedItems = item.items || [];
const nestedRequests = nestedItems.filter((i) => isItemARequest(i) && !i.isTransient);
const nestedFolders = nestedItems.filter((i) => isItemAFolder(i) && !i.isTransient);
folders.push({
name: item.name,
requestCount: nestedRequests.length,
subfolderCount: nestedFolders.length
});
continue;
}
if (isItemARequest(item)) {
const req = item.draft?.request || item.request;
requests.push({
name: item.name,
method: req?.method || 'GET',
url: req?.url || '',
type: item.type
});
}
}
return { folders, requests };
};
export const buildDocsContextFromCollection = (collection) => {
if (!collection) return null;
const { folders, requests } = summarizeDocsItems(collection.items || []);
return {
scope: 'collection',
name: collection.name || '',
folders,
requests
};
};
export const buildDocsContextFromFolder = (collection, folder) => {
if (!folder) return null;
const { folders, requests } = summarizeDocsItems(folder.items || []);
return {
scope: 'folder',
name: folder.name || '',
collectionName: collection?.name || '',
folders,
requests
};
};
/**
* Start a streaming generation. Subscribes to the corresponding `main:ai-stream-*`
* channels filtered by streamId. Returns a handle with `.stop()` and a promise

View File

@@ -0,0 +1,118 @@
import {
buildDocsContextFromCollection,
buildDocsContextFromFolder,
buildRequestContextFromItem
} from './index';
describe('utils/ai', () => {
const collection = {
name: 'Pet Store API',
items: [
{
uid: 'f1',
type: 'folder',
name: 'Users',
items: [
{
uid: 'r1',
type: 'http-request',
name: 'List Users',
request: { method: 'GET', url: '{{base}}/users' }
},
{
uid: 'f2',
type: 'folder',
name: 'Admin',
items: [
{
uid: 'r2',
type: 'http-request',
name: 'Delete User',
request: { method: 'DELETE', url: '{{base}}/users/1' }
}
]
}
]
},
{
uid: 'r3',
type: 'http-request',
name: 'Health Check',
request: { method: 'GET', url: '{{base}}/health' }
}
]
};
describe('buildDocsContextFromCollection', () => {
it('summarizes top-level folders and requests', () => {
expect(buildDocsContextFromCollection(collection)).toEqual({
scope: 'collection',
name: 'Pet Store API',
folders: [
{
name: 'Users',
requestCount: 1,
subfolderCount: 1
}
],
requests: [
{
name: 'Health Check',
method: 'GET',
url: '{{base}}/health',
type: 'http-request'
}
]
});
});
it('returns null when collection is missing', () => {
expect(buildDocsContextFromCollection(null)).toBeNull();
});
});
describe('buildDocsContextFromFolder', () => {
it('summarizes direct child folders and requests for the folder scope', () => {
const folder = collection.items[0];
expect(buildDocsContextFromFolder(collection, folder)).toEqual({
scope: 'folder',
name: 'Users',
collectionName: 'Pet Store API',
folders: [
{
name: 'Admin',
requestCount: 1,
subfolderCount: 0
}
],
requests: [
{
name: 'List Users',
method: 'GET',
url: '{{base}}/users',
type: 'http-request'
}
]
});
});
it('returns null when folder is missing', () => {
expect(buildDocsContextFromFolder(collection, null)).toBeNull();
});
});
describe('buildRequestContextFromItem', () => {
it('builds request details for request-level docs', () => {
const item = collection.items[1];
expect(buildRequestContextFromItem(item)).toEqual({
url: '{{base}}/health',
method: 'GET',
headers: [],
params: [],
body: null
});
});
});
});