diff --git a/doc-agents/src/agent/agent_pulse/tools.ts b/doc-agents/src/agent/agent_pulse/tools.ts index 3e24ca89..2efa844b 100644 --- a/doc-agents/src/agent/agent_pulse/tools.ts +++ b/doc-agents/src/agent/agent_pulse/tools.ts @@ -4,6 +4,7 @@ import { getTutorialMeta } from './tutorial'; import docQAAgent from '@agent/doc_qa'; import type { Action } from './types'; import { ActionType } from './types'; +import { documentPathToUrl } from '@utils/url'; interface ToolState { action: Action | null; @@ -60,6 +61,13 @@ export async function createTools(state: ToolState, agentContext: any) { const response = await docQAAgent.run({ message: query, }); + // Transform document URLs from raw paths to proper URLs + if (response.documents && Array.isArray(response.documents)) { + response.documents = response.documents.map((doc) => ({ + ...doc, + url: documentPathToUrl(doc.url), + })); + } return response; } catch (error) { agentContext.logger.error('Error calling doc-qa agent: %s', error); diff --git a/doc-agents/src/api/doc-qa/route.ts b/doc-agents/src/api/doc-qa/route.ts index 2d476460..5ae09fd7 100644 --- a/doc-agents/src/api/doc-qa/route.ts +++ b/doc-agents/src/api/doc-qa/route.ts @@ -1,41 +1,10 @@ import { createRouter } from '@agentuity/runtime'; import docQAAgent from '@agent/doc_qa'; import { bearerTokenAuth } from '@middleware/auth'; +import { documentPathToUrl } from '@utils/url'; const router = createRouter(); -/** - * Transforms a document path (e.g., "Agents/index.mdx") to a proper URL (e.g., "/Agents") - */ -function documentPathToUrl(docPath: string): string { - // Remove the .md or .mdx extension before any # symbol - const path = docPath.replace(/\.mdx?(?=#|$)/, ''); - - // Split path and hash (if any) - const [basePath = '', hash] = path.split('#'); - - // Split the base path into segments - const segments = basePath.split('/').filter(Boolean); - - // If the last segment is 'index', remove it - if ( - segments.length > 0 && - segments[segments.length - 1]?.toLowerCase() === 'index' - ) { - segments.pop(); - } - - // Reconstruct the path - let url = `/${segments.join('/')}`; - if (url === '/') { - url = '/'; - } - if (hash) { - url += `#${hash}`; - } - return url; -} - // POST /api/doc-qa - Answer questions about documentation (bearer token protected, no user context) router.post('/', bearerTokenAuth, docQAAgent.validator(), async (c) => { const data = c.req.valid('json'); diff --git a/doc-agents/src/utils/url.ts b/doc-agents/src/utils/url.ts new file mode 100644 index 00000000..9e29d469 --- /dev/null +++ b/doc-agents/src/utils/url.ts @@ -0,0 +1,33 @@ +/** + * Transforms a document path (e.g., "Get-Started/quickstart.mdx#7-deploy") to a proper URL (e.g., "/Get-Started/quickstart#7-deploy") + */ +export function documentPathToUrl(docPath?: string | null): string { + if (!docPath) { + return '/'; + } + // Remove the .md or .mdx extension before any # symbol + const path = docPath.replace(/\.mdx?(?=#|$)/, ''); + + // Split path and hash (if any) + const [basePath = '', hash] = path.split('#'); + // Split the base path into segments + const segments = basePath.split('/').filter(Boolean); + + // If the last segment is 'index', remove it + if ( + segments.length > 0 && + segments[segments.length - 1]?.toLowerCase() === 'index' + ) { + segments.pop(); + } + + // Reconstruct the path with leading slash + let url = `/${segments.join('/')}`; + if (url === '/') { + url = '/'; + } + if (hash) { + url += `#${hash}`; + } + return url; +} diff --git a/doc-agents/tsconfig.json b/doc-agents/tsconfig.json index 7f774deb..33afcbdd 100644 --- a/doc-agents/tsconfig.json +++ b/doc-agents/tsconfig.json @@ -21,7 +21,8 @@ "paths": { "@agent/*": ["./src/agent/*"], "@api/*": ["./src/api/*"], - "@middleware/*": ["./src/middleware/*"] + "@middleware/*": ["./src/middleware/*"], + "@utils/*": ["./src/utils/*"] } }, "include": ["src/**/*", "app.ts"]