diff --git a/components/DeepResearch.vue b/components/DeepResearch.vue index 3a15c58..5050284 100644 --- a/components/DeepResearch.vue +++ b/components/DeepResearch.vue @@ -1,345 +1,162 @@ - - - - - - - No research data - Please answer and submit the questions to start research - - - - - - - - - - - - - - {{ node.depth }} - - - - - - - - - - - Search Detail - - Query: - {{ selectedNode.query }} - - - Learning Content: - - - {{ learning }} - - - Follow-up Questions: - - - {{ question }} - - - - - - Select a node to view details - - - - - + + + + + Deep Research + Click a child node to view details + + + + + + + {{ hoveredNode.label }} + Research Goal: + {{ hoveredNode.researchGoal }} + + Learnings: + + {{ learning }} + + + + + + diff --git a/components/ResearchFeedback.vue b/components/ResearchFeedback.vue index 5d14077..a958f19 100644 --- a/components/ResearchFeedback.vue +++ b/components/ResearchFeedback.vue @@ -63,7 +63,6 @@ // Write the questions into modelValue const parseResult = parsePartialJson(content) - console.log(parseResult) if (parseResult.state === 'repaired-parse' || parseResult.state === 'successful-parse') { if (!isObject(parseResult.value) || Array.isArray(parseResult.value)) { return (modelValue.value = []) diff --git a/components/ResearchForm.vue b/components/ResearchForm.vue index f53c3d6..0537e7b 100644 --- a/components/ResearchForm.vue +++ b/components/ResearchForm.vue @@ -58,8 +58,8 @@ }>() const input = ref('天空为什么是蓝的?') - const breadth = ref(6) - const depth = ref(3) + const breadth = ref(3) + const depth = ref(2) const numQuestions = ref(1) const isLoading = ref(false) const result = ref(null) @@ -91,13 +91,13 @@ toast.add({ title: '复制成功', description: '研究报告已复制到剪贴板', - icon: 'i-heroicons-check-circle', + icon: 'i-lucide-badge-check', }) } catch (e) { toast.add({ title: '复制失败', description: '无法复制到剪贴板', - icon: 'i-heroicons-x-circle', + icon: 'i-lucide-x', color: 'error', }) } diff --git a/components/Tree.vue b/components/Tree.vue new file mode 100644 index 0000000..4859007 --- /dev/null +++ b/components/Tree.vue @@ -0,0 +1,76 @@ + + + + + + {{ + node.label + }} + + + + + + + diff --git a/lib/deep-research.ts b/lib/deep-research.ts index c16cf68..4876a02 100644 --- a/lib/deep-research.ts +++ b/lib/deep-research.ts @@ -8,20 +8,21 @@ import { o3MiniModel, trimPrompt } from './ai/providers'; import { systemPrompt } from './prompt'; import zodToJsonSchema from 'zod-to-json-schema'; import { tavily, type TavilySearchResponse } from '@tavily/core'; -// import 'dotenv/config'; // Used for streaming response -type PartialSerpQueries = DeepPartial['queries']>; -type PartialSearchResult = DeepPartial>; +export type SearchQuery = z.infer['queries'][0]; +export type PartialSearchQuery = DeepPartial; +export type SearchResult = z.infer; +export type PartialSearchResult = DeepPartial; export type ResearchStep = - | { type: 'start'; message: string; depth: number; breadth: number } - | { type: 'generating_queries'; result: PartialSerpQueries; depth: number; breadth: number } - | { type: 'query_generated'; query: string; researchGoal: string; depth: number; breadth: number; queryIndex: number } - | { type: 'searching'; query: string; depth: number; breadth: number; queryIndex: number } - | { type: 'search_complete'; query: string; urls: string[]; depth: number; breadth: number; queryIndex: number } - | { type: 'processing_serach_result'; query: string; result: PartialSearchResult; depth: number; breadth: number; queryIndex: number } - | { type: 'error'; message: string } + | { type: 'generating_query'; result: PartialSearchQuery; depth: number; breadth: number; nodeIndex: number; nodeId: string } + | { type: 'generated_query'; query: string; result: PartialSearchQuery; depth: number; breadth: number; nodeIndex: number; nodeId: string } + | { type: 'searching'; query: string; depth: number; breadth: number; nodeIndex: number; nodeId: string } + | { type: 'search_complete'; query: string; urls: string[]; depth: number; breadth: number; nodeIndex: number; nodeId: string } + | { type: 'processing_serach_result'; query: string; result: PartialSearchResult; depth: number; breadth: number; nodeIndex: number; nodeId: string } + | { type: 'processed_search_result'; query: string; result: SearchResult; depth: number; breadth: number; nodeIndex: number; nodeId: string } + | { type: 'error'; message: string; depth: number; nodeId: string } | { type: 'complete' }; // increase this if you have higher API rate limits @@ -38,9 +39,9 @@ const tvly = tavily({ }) /** - * Schema for {@link generateSerpQueries} without dynamic descriptions + * Schema for {@link generateSearchQueries} without dynamic descriptions */ -export const serpQueriesTypeSchema = z.object({ +export const searchQueriesTypeSchema = z.object({ queries: z.array( z.object({ query: z.string(), @@ -50,7 +51,7 @@ export const serpQueriesTypeSchema = z.object({ }); // take en user query, return a list of SERP queries -export function generateSerpQueries({ +export function generateSearchQueries({ query, numQueries = 3, learnings, @@ -92,11 +93,11 @@ export function generateSerpQueries({ }); } -export const serpResultTypeSchema = z.object({ +export const searchResultTypeSchema = z.object({ learnings: z.array(z.string()), followUpQuestions: z.array(z.string()), }); -function processSerpResult({ +function processSearchResult({ query, result, numLearnings = 3, @@ -170,112 +171,159 @@ export async function writeFinalReport({ return res.object.reportMarkdown + urlsSection; } +function childNodeId(parentNodeId: string, currentIndex: number) { + return `${parentNodeId}-${currentIndex}`; +} + export async function deepResearch({ query, breadth, - depth, + maxDepth, learnings = [], visitedUrls = [], onProgress, + currentDepth = 1, + nodeId = '0' }: { query: string; breadth: number; - depth: number; + maxDepth: number; learnings?: string[]; visitedUrls?: string[]; onProgress: (step: ResearchStep) => void; + currentDepth?: number; + nodeId?: string }): Promise { - onProgress({ type: 'start', message: `开始深度研究,深度:${depth},广度:${breadth}`, depth, breadth }); - try { - const serpQueriesResult = generateSerpQueries({ + const searchQueriesResult = generateSearchQueries({ query, learnings, numQueries: breadth, }); const limit = pLimit(ConcurrencyLimit); - let serpQueries: PartialSerpQueries = []; + let searchQueries: PartialSearchQuery[] = []; for await (const parsedQueries of parseStreamingJson( - serpQueriesResult.textStream, - serpQueriesTypeSchema, + searchQueriesResult.textStream, + searchQueriesTypeSchema, (value) => !!value.queries?.length && !!value.queries[0]?.query )) { if (parsedQueries.queries) { - serpQueries = parsedQueries.queries; - onProgress({ - type: 'generating_queries', - result: serpQueries, - depth, - breadth - }); + for (let i = 0; i < searchQueries.length; i++) { + onProgress({ + type: 'generating_query', + result: searchQueries[i], + depth: currentDepth, + breadth, + nodeIndex: i, + nodeId: childNodeId(nodeId, i) + }); + } + searchQueries = parsedQueries.queries; } } + for (let i = 0; i < searchQueries.length; i++) { + onProgress({ + type: 'generated_query', + query, + result: searchQueries[i], + depth: currentDepth, + breadth, + nodeIndex: i, + nodeId: childNodeId(nodeId, i) + }); + } + await Promise.all( - serpQueries.map(serpQuery => + searchQueries.map((searchQuery, nodeIndex) => limit(async () => { - if (!serpQuery?.query) return + if (!searchQuery?.query) return + onProgress({ + type: 'searching', + query: searchQuery.query, + depth: currentDepth, + breadth, + nodeIndex, + nodeId: childNodeId(nodeId, nodeIndex) + }) try { - // const result = await firecrawl.search(serpQuery.query, { + // const result = await firecrawl.search(searchQuery.query, { // timeout: 15000, // limit: 5, // scrapeOptions: { formats: ['markdown'] }, // }); - const result = await tvly.search(serpQuery.query, { + const result = await tvly.search(searchQuery.query, { maxResults: 5, }) - console.log(`Ran ${serpQuery.query}, found ${result.results.length} contents`); + console.log(`Ran ${searchQuery.query}, found ${result.results.length} contents`); // Collect URLs from this search const newUrls = compact(result.results.map(item => item.url)); - const newBreadth = Math.ceil(breadth / 2); - const newDepth = depth - 1; + // Breadth for the next search is half of the current breadth + const nextBreadth = Math.ceil(breadth / 2); - const serpResultGenerator = processSerpResult({ - query: serpQuery.query, + const searchResultGenerator = processSearchResult({ + query: searchQuery.query, result, - numFollowUpQuestions: newBreadth, + numFollowUpQuestions: nextBreadth, }); - let serpResult: PartialSearchResult = {}; + let searchResult: PartialSearchResult = {}; for await (const parsedLearnings of parseStreamingJson( - serpResultGenerator.textStream, - serpResultTypeSchema, + searchResultGenerator.textStream, + searchResultTypeSchema, (value) => !!value.learnings?.length )) { - serpResult = parsedLearnings; + searchResult = parsedLearnings; onProgress({ type: 'processing_serach_result', result: parsedLearnings, - depth, - breadth, - query: serpQuery.query, - queryIndex: serpQueries.indexOf(serpQuery), + depth: currentDepth, + breadth: breadth, + query: searchQuery.query, + nodeIndex: nodeIndex, + nodeId: childNodeId(nodeId, nodeIndex) }); } - console.log(`Processed serp result for ${serpQuery.query}`, serpResult); - const allLearnings = [...learnings, ...(serpResult.learnings ?? [])]; + console.log(`Processed search result for ${searchQuery.query}`, searchResult); + const allLearnings = [...learnings, ...(searchResult.learnings ?? [])]; const allUrls = [...visitedUrls, ...newUrls]; + const nextDepth = currentDepth + 1; - if (newDepth > 0 && serpResult.followUpQuestions?.length) { - console.log( - `Researching deeper, breadth: ${newBreadth}, depth: ${newDepth}`, + onProgress({ + type: 'processed_search_result', + result: { + learnings: allLearnings, + followUpQuestions: searchResult.followUpQuestions ?? [], + }, + depth: currentDepth, + breadth, + query: searchQuery.query, + nodeIndex: nodeIndex, + nodeId: childNodeId(nodeId, nodeIndex) + }) + + if (nextDepth < maxDepth && searchResult.followUpQuestions?.length) { + console.warn( + `Researching deeper, breadth: ${nextBreadth}, depth: ${nextDepth}`, ); const nextQuery = ` - Previous research goal: ${serpQuery.researchGoal} - Follow-up research directions: ${serpResult.followUpQuestions.map(q => `\n${q}`).join('')} + Previous research goal: ${searchQuery.researchGoal} + Follow-up research directions: ${searchResult.followUpQuestions.map(q => `\n${q}`).join('')} `.trim(); return deepResearch({ query: nextQuery, - breadth: newBreadth, - depth: newDepth, + breadth: nextBreadth, + maxDepth, learnings: allLearnings, visitedUrls: allUrls, onProgress, + currentDepth: nextDepth, + nodeId: childNodeId(nodeId, nodeIndex), }); } else { return { @@ -284,7 +332,7 @@ export async function deepResearch({ }; } } catch (e: any) { - throw new Error(`Error searching for ${serpQuery.query}, depth ${depth}\nMessage: ${e.message}`) + throw new Error(`Error searching for ${searchQuery.query}, depth ${currentDepth}\nMessage: ${e.message}`) } }), ), @@ -294,6 +342,8 @@ export async function deepResearch({ onProgress({ type: 'error', message: error?.message ?? 'Something went wrong', + depth: currentDepth, + nodeId, }) } diff --git a/package.json b/package.json index a95e768..58069d0 100644 --- a/package.json +++ b/package.json @@ -11,17 +11,15 @@ }, "dependencies": { "@ai-sdk/openai": "^1.1.9", - "@ai-sdk/openai-compatible": "^0.1.8", - "@ai-sdk/provider-utils": "^2.1.6", "@ai-sdk/ui-utils": "^1.1.11", "@ai-sdk/vue": "^1.1.11", + "@iconify-json/lucide": "^1.2.26", "@mendable/firecrawl-js": "^1.16.0", "@nuxt/ui": "3.0.0-alpha.12", "@tailwindcss/typography": "^0.5.16", "@tavily/core": "^0.0.3", "@types/lodash-es": "^4.17.12", "ai": "^4.1.28", - "d3": "^7.9.0", "js-tiktoken": "^1.0.18", "lodash-es": "^4.17.21", "marked": "^15.0.7", diff --git a/pages/index.vue b/pages/index.vue index 23c68e2..ef341fc 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -1,14 +1,12 @@ - - - Deep Research Assistant - - - - - + + Deep Research Assistant + + + + @@ -18,7 +16,6 @@ import type ResearchFeedback from '~/components/ResearchFeedback.vue' import type DeepResearch from '~/components/DeepResearch.vue' import type { ResearchInputData } from '~/components/ResearchForm.vue' - import type { SearchTree } from '~/components/DeepResearch.vue' import type { ResearchFeedbackResult } from '~/components/ResearchFeedback.vue' interface DeepResearchResult { @@ -39,7 +36,7 @@ const result = ref({ feedback: [], }) - const searchTree = ref({ + const searchTree = ref({ root: null, currentDepth: 0, maxDepth: 0, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8112e74..1d1efc8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,18 +11,15 @@ importers: '@ai-sdk/openai': specifier: ^1.1.9 version: 1.1.9(zod@3.24.1) - '@ai-sdk/openai-compatible': - specifier: ^0.1.8 - version: 0.1.8(zod@3.24.1) - '@ai-sdk/provider-utils': - specifier: ^2.1.6 - version: 2.1.6(zod@3.24.1) '@ai-sdk/ui-utils': specifier: ^1.1.11 version: 1.1.11(zod@3.24.1) '@ai-sdk/vue': specifier: ^1.1.11 version: 1.1.11(vue@3.5.13(typescript@5.7.3))(zod@3.24.1) + '@iconify-json/lucide': + specifier: ^1.2.26 + version: 1.2.26 '@mendable/firecrawl-js': specifier: ^1.16.0 version: 1.16.0(ws@8.18.0) @@ -41,9 +38,6 @@ importers: ai: specifier: ^4.1.28 version: 4.1.28(react@19.0.0)(zod@3.24.1) - d3: - specifier: ^7.9.0 - version: 7.9.0 js-tiktoken: specifier: ^1.0.18 version: 1.0.18 @@ -84,12 +78,6 @@ importers: packages: - '@ai-sdk/openai-compatible@0.1.8': - resolution: {integrity: sha512-o2WeZmkOgaaEHAIZfAdlAASotNemhWBzupUp7ql/vBKIrPDctbQS4K7XOvG7EZ1dshn0TxB+Ur7Q8HoWSeWPmA==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.0.0 - '@ai-sdk/openai@1.1.9': resolution: {integrity: sha512-t/CpC4TLipdbgBJTMX/otzzqzCMBSPQwUOkYPGbT/jyuC86F+YO9o+LS0Ty2pGUE1kyT+B3WmJ318B16ZCg4hw==} engines: {node: '>=18'} @@ -468,6 +456,9 @@ packages: '@floating-ui/vue@1.1.6': resolution: {integrity: sha512-XFlUzGHGv12zbgHNk5FN2mUB7ROul3oG2ENdTpWdE+qMFxyNxWSRmsoyhiEnpmabNm6WnUvR1OvJfUfN4ojC1A==} + '@iconify-json/lucide@1.2.26': + resolution: {integrity: sha512-arD/8mK0lRxFY2LgLf345NhWVWiOtV8sOxJuLnq4QRz3frMiOwVwGxEgp5Xe/bRGzxO2CxxCBok0bPRpCkYZQQ==} + '@iconify/collections@1.0.515': resolution: {integrity: sha512-4aJAgfv31fST8LYjuGy14ZQN8zIDQpKuHRQXZgilQMDh6SW2YFiIWMWKd7MSEmRXwRQdygwPrAydelBNHW+qqw==} @@ -1581,133 +1572,6 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - d3-array@3.2.4: - resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} - engines: {node: '>=12'} - - d3-axis@3.0.0: - resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} - engines: {node: '>=12'} - - d3-brush@3.0.0: - resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} - engines: {node: '>=12'} - - d3-chord@3.0.1: - resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} - engines: {node: '>=12'} - - d3-color@3.1.0: - resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} - engines: {node: '>=12'} - - d3-contour@4.0.2: - resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} - engines: {node: '>=12'} - - d3-delaunay@6.0.4: - resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} - engines: {node: '>=12'} - - d3-dispatch@3.0.1: - resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} - engines: {node: '>=12'} - - d3-drag@3.0.0: - resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} - engines: {node: '>=12'} - - d3-dsv@3.0.1: - resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} - engines: {node: '>=12'} - hasBin: true - - d3-ease@3.0.1: - resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} - engines: {node: '>=12'} - - d3-fetch@3.0.1: - resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} - engines: {node: '>=12'} - - d3-force@3.0.0: - resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} - engines: {node: '>=12'} - - d3-format@3.1.0: - resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} - engines: {node: '>=12'} - - d3-geo@3.1.1: - resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} - engines: {node: '>=12'} - - d3-hierarchy@3.1.2: - resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} - engines: {node: '>=12'} - - d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} - engines: {node: '>=12'} - - d3-path@3.1.0: - resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} - engines: {node: '>=12'} - - d3-polygon@3.0.1: - resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} - engines: {node: '>=12'} - - d3-quadtree@3.0.1: - resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} - engines: {node: '>=12'} - - d3-random@3.0.1: - resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} - engines: {node: '>=12'} - - d3-scale-chromatic@3.1.0: - resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} - engines: {node: '>=12'} - - d3-scale@4.0.2: - resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} - engines: {node: '>=12'} - - d3-selection@3.0.0: - resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} - engines: {node: '>=12'} - - d3-shape@3.2.0: - resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} - engines: {node: '>=12'} - - d3-time-format@4.1.0: - resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} - engines: {node: '>=12'} - - d3-time@3.1.0: - resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} - engines: {node: '>=12'} - - d3-timer@3.0.1: - resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} - engines: {node: '>=12'} - - d3-transition@3.0.1: - resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} - engines: {node: '>=12'} - peerDependencies: - d3-selection: 2 - 3 - - d3-zoom@3.0.0: - resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} - engines: {node: '>=12'} - - d3@7.9.0: - resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} - engines: {node: '>=12'} - db0@0.2.3: resolution: {integrity: sha512-PunuHESDNefmwVy1LDpY663uWwKt2ogLGoB6NOz2sflGREWqDreMwDgF8gfkXxgNXW+dqviyiJGm924H1BaGiw==} peerDependencies: @@ -1771,9 +1635,6 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delaunator@5.0.1: - resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -2172,10 +2033,6 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -2207,10 +2064,6 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - internmap@2.0.3: - resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} - engines: {node: '>=12'} - ioredis@5.5.0: resolution: {integrity: sha512-7CutT89g23FfSa8MDoIFs2GYYa0PaNiW/OrT+nRyjRXHDZd17HmIgy+reOQ/yhh72NznNjGuS8kbCAcA4Ro4mw==} engines: {node: '>=12.22.0'} @@ -3121,9 +2974,6 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - robust-predicates@3.0.2: - resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - rollup-plugin-visualizer@5.14.0: resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} engines: {node: '>=18'} @@ -3149,18 +2999,12 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - rw@1.3.3: - resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} - safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} @@ -3868,12 +3712,6 @@ packages: snapshots: - '@ai-sdk/openai-compatible@0.1.8(zod@3.24.1)': - dependencies: - '@ai-sdk/provider': 1.0.7 - '@ai-sdk/provider-utils': 2.1.6(zod@3.24.1) - zod: 3.24.1 - '@ai-sdk/openai@1.1.9(zod@3.24.1)': dependencies: '@ai-sdk/provider': 1.0.7 @@ -4238,6 +4076,10 @@ snapshots: - '@vue/composition-api' - vue + '@iconify-json/lucide@1.2.26': + dependencies: + '@iconify/types': 2.0.0 + '@iconify/collections@1.0.515': dependencies: '@iconify/types': 2.0.0 @@ -5730,158 +5572,6 @@ snapshots: csstype@3.1.3: {} - d3-array@3.2.4: - dependencies: - internmap: 2.0.3 - - d3-axis@3.0.0: {} - - d3-brush@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - - d3-chord@3.0.1: - dependencies: - d3-path: 3.1.0 - - d3-color@3.1.0: {} - - d3-contour@4.0.2: - dependencies: - d3-array: 3.2.4 - - d3-delaunay@6.0.4: - dependencies: - delaunator: 5.0.1 - - d3-dispatch@3.0.1: {} - - d3-drag@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-selection: 3.0.0 - - d3-dsv@3.0.1: - dependencies: - commander: 7.2.0 - iconv-lite: 0.6.3 - rw: 1.3.3 - - d3-ease@3.0.1: {} - - d3-fetch@3.0.1: - dependencies: - d3-dsv: 3.0.1 - - d3-force@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-quadtree: 3.0.1 - d3-timer: 3.0.1 - - d3-format@3.1.0: {} - - d3-geo@3.1.1: - dependencies: - d3-array: 3.2.4 - - d3-hierarchy@3.1.2: {} - - d3-interpolate@3.0.1: - dependencies: - d3-color: 3.1.0 - - d3-path@3.1.0: {} - - d3-polygon@3.0.1: {} - - d3-quadtree@3.0.1: {} - - d3-random@3.0.1: {} - - d3-scale-chromatic@3.1.0: - dependencies: - d3-color: 3.1.0 - d3-interpolate: 3.0.1 - - d3-scale@4.0.2: - dependencies: - d3-array: 3.2.4 - d3-format: 3.1.0 - d3-interpolate: 3.0.1 - d3-time: 3.1.0 - d3-time-format: 4.1.0 - - d3-selection@3.0.0: {} - - d3-shape@3.2.0: - dependencies: - d3-path: 3.1.0 - - d3-time-format@4.1.0: - dependencies: - d3-time: 3.1.0 - - d3-time@3.1.0: - dependencies: - d3-array: 3.2.4 - - d3-timer@3.0.1: {} - - d3-transition@3.0.1(d3-selection@3.0.0): - dependencies: - d3-color: 3.1.0 - d3-dispatch: 3.0.1 - d3-ease: 3.0.1 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-timer: 3.0.1 - - d3-zoom@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - - d3@7.9.0: - dependencies: - d3-array: 3.2.4 - d3-axis: 3.0.0 - d3-brush: 3.0.0 - d3-chord: 3.0.1 - d3-color: 3.1.0 - d3-contour: 4.0.2 - d3-delaunay: 6.0.4 - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-dsv: 3.0.1 - d3-ease: 3.0.1 - d3-fetch: 3.0.1 - d3-force: 3.0.0 - d3-format: 3.1.0 - d3-geo: 3.1.1 - d3-hierarchy: 3.1.2 - d3-interpolate: 3.0.1 - d3-path: 3.1.0 - d3-polygon: 3.0.1 - d3-quadtree: 3.0.1 - d3-random: 3.0.1 - d3-scale: 4.0.2 - d3-scale-chromatic: 3.1.0 - d3-selection: 3.0.0 - d3-shape: 3.2.0 - d3-time: 3.1.0 - d3-time-format: 4.1.0 - d3-timer: 3.0.1 - d3-transition: 3.0.1(d3-selection@3.0.0) - d3-zoom: 3.0.0 - db0@0.2.3: {} debug@2.6.9: @@ -5909,10 +5599,6 @@ snapshots: defu@6.1.4: {} - delaunator@5.0.1: - dependencies: - robust-predicates: 3.0.2 - delayed-stream@1.0.0: {} denque@2.1.0: {} @@ -6319,10 +6005,6 @@ snapshots: human-signals@5.0.0: {} - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - ieee754@1.2.1: {} ignore@7.0.3: {} @@ -6352,8 +6034,6 @@ snapshots: ini@4.1.1: {} - internmap@2.0.3: {} - ioredis@5.5.0: dependencies: '@ioredis/commands': 1.2.0 @@ -7392,8 +7072,6 @@ snapshots: dependencies: glob: 10.4.5 - robust-predicates@3.0.2: {} - rollup-plugin-visualizer@5.14.0(rollup@4.34.6): dependencies: open: 8.4.2 @@ -7434,14 +7112,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 - rw@1.3.3: {} - safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} - safer-buffer@2.1.2: {} - scule@1.3.0: {} secure-json-parse@2.7.0: {} diff --git a/server/api/deep-research.post.ts b/server/api/deep-research.post.ts index d18a3f4..d318026 100644 --- a/server/api/deep-research.post.ts +++ b/server/api/deep-research.post.ts @@ -1,3 +1,4 @@ +// This file is currently unused import { deepResearch, ResearchStep } from "~/lib/deep-research"; export default defineEventHandler(async event => {
Click a child node to view details
{{ hoveredNode.researchGoal }}