mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(ai): add configuration files support for AI template generation
- Enhance template generation with configFiles feature - Update StepTwo and StepThree components to display and edit configuration files - Modify AI router and schemas to support configuration file mounting - Refine AI service prompt to provide stricter guidelines for config file usage
This commit is contained in:
@@ -85,6 +85,22 @@ export const StepThree = ({ templateInfo }: StepProps) => {
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold">Configuration Files</h3>
|
||||
<ul className="list-disc pl-5">
|
||||
{templateInfo?.details?.configFiles.map((file, index) => (
|
||||
<li key={index}>
|
||||
<strong className="text-sm font-semibold">
|
||||
{file.filePath}
|
||||
</strong>
|
||||
:
|
||||
<span className="text-sm ml-2 text-muted-foreground">
|
||||
{file.content}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,11 +24,7 @@ export interface StepProps {
|
||||
setTemplateInfo: React.Dispatch<React.SetStateAction<TemplateInfo>>;
|
||||
}
|
||||
|
||||
export const StepTwo = ({
|
||||
stepper,
|
||||
templateInfo,
|
||||
setTemplateInfo,
|
||||
}: StepProps) => {
|
||||
export const StepTwo = ({ templateInfo, setTemplateInfo }: StepProps) => {
|
||||
const suggestions = templateInfo.suggestions || [];
|
||||
const selectedVariant = templateInfo.details;
|
||||
const [showValues, setShowValues] = useState<Record<string, boolean>>({});
|
||||
@@ -52,7 +48,9 @@ export const StepTwo = ({
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
toast.error("Error generating suggestions");
|
||||
toast.error("Error generating suggestions", {
|
||||
description: error.message,
|
||||
});
|
||||
});
|
||||
}, [templateInfo.userInput]);
|
||||
|
||||
@@ -434,6 +432,78 @@ export const StepTwo = ({
|
||||
</ScrollArea>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="mounts">
|
||||
<AccordionTrigger>Configuration Files</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<ScrollArea className="w-full rounded-md border">
|
||||
<div className="p-4 space-y-4">
|
||||
{selectedVariant?.configFiles?.length > 0 ? (
|
||||
<>
|
||||
<div className="text-sm text-muted-foreground mb-4">
|
||||
This template requires the following
|
||||
configuration files to be mounted:
|
||||
</div>
|
||||
{selectedVariant.configFiles.map(
|
||||
(config, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="space-y-2 border rounded-lg p-4"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-primary">
|
||||
{config.filePath}
|
||||
</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Will be mounted as: ../files
|
||||
{config.filePath}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<CodeEditor
|
||||
value={config.content}
|
||||
className="font-mono"
|
||||
onChange={(value) => {
|
||||
if (!selectedVariant?.configFiles)
|
||||
return;
|
||||
const updatedConfigFiles = [
|
||||
...selectedVariant.configFiles,
|
||||
];
|
||||
updatedConfigFiles[index] = {
|
||||
filePath: config.filePath,
|
||||
content: value,
|
||||
};
|
||||
setTemplateInfo({
|
||||
...templateInfo,
|
||||
...(templateInfo.details && {
|
||||
details: {
|
||||
...templateInfo.details,
|
||||
configFiles: updatedConfigFiles,
|
||||
},
|
||||
}),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="text-center text-muted-foreground py-8">
|
||||
<p>
|
||||
This template doesn't require any configuration
|
||||
files.
|
||||
</p>
|
||||
<p className="text-sm mt-2">
|
||||
All necessary configurations are handled through
|
||||
environment variables.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</ScrollArea>
|
||||
</>
|
||||
|
||||
@@ -47,7 +47,14 @@ interface Details {
|
||||
envVariables: EnvVariable[];
|
||||
shortDescription: string;
|
||||
domains: Domain[];
|
||||
configFiles: Mount[];
|
||||
}
|
||||
|
||||
interface Mount {
|
||||
filePath: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface TemplateInfo {
|
||||
userInput: string;
|
||||
details?: Details | null;
|
||||
@@ -126,6 +133,7 @@ export const TemplateGenerator = ({ projectId }: Props) => {
|
||||
...(templateInfo.server?.serverId && {
|
||||
serverId: templateInfo.server?.serverId || "",
|
||||
}),
|
||||
configFiles: templateInfo?.details?.configFiles || [],
|
||||
})
|
||||
.then(async () => {
|
||||
toast.success("Compose Created");
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
apiUpdateAi,
|
||||
deploySuggestionSchema,
|
||||
} from "@dokploy/server/db/schema/ai";
|
||||
import { createDomain } from "@dokploy/server/index";
|
||||
import { createDomain, createMount } from "@dokploy/server/index";
|
||||
import {
|
||||
deleteAiSettings,
|
||||
getAiSettingById,
|
||||
@@ -126,8 +126,6 @@ export const aiRouter = createTRPCRouter({
|
||||
|
||||
const projectName = slugify(`${project.name} ${input.id}`);
|
||||
|
||||
console.log(input);
|
||||
|
||||
const compose = await createComposeByTemplate({
|
||||
...input,
|
||||
composeFile: input.dockerCompose,
|
||||
@@ -136,6 +134,7 @@ export const aiRouter = createTRPCRouter({
|
||||
name: input.name,
|
||||
sourceType: "raw",
|
||||
appName: `${projectName}-${generatePassword(6)}`,
|
||||
isolatedDeployment: true,
|
||||
});
|
||||
|
||||
if (input.domains && input.domains?.length > 0) {
|
||||
@@ -148,6 +147,18 @@ export const aiRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
}
|
||||
if (input.configFiles && input.configFiles?.length > 0) {
|
||||
for (const mount of input.configFiles) {
|
||||
await createMount({
|
||||
filePath: mount.filePath,
|
||||
mountPath: "",
|
||||
content: mount.content,
|
||||
serviceId: compose.composeId,
|
||||
serviceType: "compose",
|
||||
type: "file",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.user.rol === "member") {
|
||||
await addNewService(
|
||||
|
||||
Reference in New Issue
Block a user