feat: add dynamic file structure context in AI chat
- Improved file structure formatting with tree-like visualization - Added filtering for ignored files and folders - Added scripts section to template context - Fixed folder hierarchy display with proper indentation - Maintains sorting with folders first, then files alphabetically - Now uses actual project files instead of template structure Example output: ├── app/ │ ├── api/ │ └── page.tsx ├── components/ └── package.json
This commit is contained in:
parent
e384607d24
commit
534b148b86
@ -2,11 +2,44 @@ import { currentUser } from "@clerk/nextjs"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { TIERS } from "@/lib/tiers"
|
||||
import { templateConfigs } from "@/lib/templates"
|
||||
import { TFile, TFolder } from "@/lib/types"
|
||||
import { ignoredFiles, ignoredFolders } from "@/components/editor/AIChat/lib/ignored-paths"
|
||||
|
||||
const anthropic = new Anthropic({
|
||||
apiKey: process.env.ANTHROPIC_API_KEY!,
|
||||
})
|
||||
|
||||
// Format file structure for context
|
||||
function formatFileStructure(items: (TFile | TFolder)[] | undefined, prefix = ""): string {
|
||||
if (!items || !Array.isArray(items)) {
|
||||
return "No files available"
|
||||
}
|
||||
|
||||
// Sort items to show folders first, then files
|
||||
const sortedItems = [...items].sort((a, b) => {
|
||||
if (a.type === b.type) return a.name.localeCompare(b.name)
|
||||
return a.type === "folder" ? -1 : 1
|
||||
})
|
||||
|
||||
return sortedItems
|
||||
.map((item) => {
|
||||
if (item.type === "file" && !ignoredFiles.some(
|
||||
(pattern) => item.name.endsWith(pattern.replace("*", "")) || item.name === pattern
|
||||
)) {
|
||||
return `${prefix}├── ${item.name}`
|
||||
} else if (
|
||||
item.type === "folder" &&
|
||||
!ignoredFolders.some((folder) => folder === item.name)
|
||||
) {
|
||||
const folderContent = formatFileStructure(item.children, `${prefix}│ `)
|
||||
return `${prefix}├── ${item.name}/\n${folderContent}`
|
||||
}
|
||||
return null
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const user = await currentUser()
|
||||
@ -60,6 +93,7 @@ export async function POST(request: Request) {
|
||||
fileName,
|
||||
line,
|
||||
templateType,
|
||||
files,
|
||||
} = await request.json()
|
||||
|
||||
// Get template configuration
|
||||
@ -70,16 +104,17 @@ export async function POST(request: Request) {
|
||||
? `
|
||||
Project Template: ${templateConfig.name}
|
||||
|
||||
File Structure:
|
||||
${Object.entries(templateConfig.fileStructure)
|
||||
.map(([path, info]) => `${path} - ${info.description}`)
|
||||
.join("\n")}
|
||||
Current File Structure:
|
||||
${files ? formatFileStructure(files) : "No files available"}
|
||||
|
||||
Conventions:
|
||||
${templateConfig.conventions.join("\n")}
|
||||
|
||||
Dependencies:
|
||||
${JSON.stringify(templateConfig.dependencies, null, 2)}
|
||||
|
||||
Scripts:
|
||||
${JSON.stringify(templateConfig.scripts, null, 2)}
|
||||
`
|
||||
: ""
|
||||
|
||||
|
@ -148,7 +148,8 @@ export default function AIChat({
|
||||
abortControllerRef,
|
||||
activeFileContent,
|
||||
false,
|
||||
templateType
|
||||
templateType,
|
||||
files
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { TFolder, TFile } from "@/lib/types"
|
||||
import React from "react"
|
||||
|
||||
// Stringify content for chat message component
|
||||
@ -91,7 +92,8 @@ export const handleSend = async (
|
||||
abortControllerRef: React.MutableRefObject<AbortController | null>,
|
||||
activeFileContent: string,
|
||||
isEditMode: boolean = false,
|
||||
templateType: string
|
||||
templateType: string,
|
||||
files: (TFile | TFolder)[]
|
||||
) => {
|
||||
// Return if input is empty and context is null
|
||||
if (input.trim() === "" && !context) return
|
||||
@ -142,6 +144,7 @@ export const handleSend = async (
|
||||
activeFileContent: activeFileContent,
|
||||
isEditMode: isEditMode,
|
||||
templateType: templateType,
|
||||
files: files,
|
||||
}),
|
||||
signal: abortControllerRef.current.signal,
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user