This view is limited to 50 files because it contains too many changes.  See the raw diff here.
Files changed (50) hide show
  1. .env.example +0 -4
  2. .github/workflows/deploy-prod.yml +0 -77
  3. .gitignore +1 -7
  4. Dockerfile +6 -9
  5. README.md +9 -10
  6. actions/mentions.ts +0 -31
  7. actions/projects.ts +0 -175
  8. app/(public)/layout.tsx +0 -14
  9. app/(public)/page.tsx +0 -25
  10. app/(public)/signin/page.tsx +0 -21
  11. app/[owner]/[repoId]/page.tsx +0 -35
  12. app/api/ask/route.ts +0 -183
  13. app/api/auth/[...nextauth]/route.ts +0 -6
  14. app/api/healthcheck/route.ts +0 -5
  15. app/api/projects/[repoId]/[commitId]/route.ts +0 -49
  16. app/api/projects/[repoId]/download/route.ts +0 -76
  17. app/api/projects/[repoId]/medias/route.ts +0 -87
  18. app/api/projects/[repoId]/rename/route.ts +0 -92
  19. app/api/projects/[repoId]/route.ts +0 -104
  20. app/api/projects/route.ts +0 -145
  21. app/api/redesign/route.ts +0 -73
  22. app/favicon.ico +0 -0
  23. app/layout.tsx +0 -108
  24. app/new/page.tsx +0 -18
  25. app/not-found.tsx +0 -17
  26. assets/deepseek.svg +0 -1
  27. {app → assets}/globals.css +19 -41
  28. assets/hf-logo.svg +0 -7
  29. assets/kimi.svg +0 -1
  30. assets/logo.svg +316 -0
  31. assets/minimax.svg +0 -1
  32. assets/pro.svg +0 -10
  33. assets/qwen.svg +0 -1
  34. assets/zai.svg +0 -13
  35. chart/Chart.yaml +0 -5
  36. chart/env/prod.yaml +0 -59
  37. chart/templates/_helpers.tpl +0 -22
  38. chart/templates/config.yaml +0 -10
  39. chart/templates/deployment.yaml +0 -81
  40. chart/templates/hpa.yaml +0 -45
  41. chart/templates/infisical.yaml +0 -24
  42. chart/templates/ingress-internal.yaml +0 -32
  43. chart/templates/ingress.yaml +0 -33
  44. chart/templates/network-policy.yaml +0 -36
  45. chart/templates/service-account.yaml +0 -13
  46. chart/templates/service-monitor.yaml +0 -17
  47. chart/templates/service.yaml +0 -21
  48. chart/values.yaml +0 -81
  49. components.json +3 -4
  50. components/ask-ai/ask-ai-landing.tsx +0 -75
.env.example DELETED
@@ -1,4 +0,0 @@
1
- AUTH_HUGGINGFACE_ID=
2
- AUTH_HUGGINGFACE_SECRET=
3
- NEXTAUTH_URL=http://localhost:3001
4
- AUTH_SECRET=
 
 
 
 
 
.github/workflows/deploy-prod.yml DELETED
@@ -1,77 +0,0 @@
1
- name: Deploy to k8s
2
- on:
3
- # run this workflow manually from the Actions tab
4
- workflow_dispatch:
5
-
6
- jobs:
7
- build-and-publish:
8
- runs-on:
9
- group: cpu-high
10
- steps:
11
- - name: Checkout
12
- uses: actions/checkout@v4
13
-
14
- - name: Login to Registry
15
- uses: docker/login-action@v3
16
- with:
17
- registry: registry.internal.huggingface.tech
18
- username: ${{ secrets.DOCKER_INTERNAL_USERNAME }}
19
- password: ${{ secrets.DOCKER_INTERNAL_PASSWORD }}
20
-
21
- - name: Docker metadata
22
- id: meta
23
- uses: docker/metadata-action@v5
24
- with:
25
- images: |
26
- registry.internal.huggingface.tech/deepsite/deepsite
27
- tags: |
28
- type=raw,value=latest,enable={{is_default_branch}}
29
- type=sha,enable=true,prefix=sha-,format=short,sha-len=8
30
-
31
- - name: Set up Docker Buildx
32
- uses: docker/setup-buildx-action@v3
33
-
34
- - name: Inject slug/short variables
35
- uses: rlespinasse/github-slug-action@v4
36
-
37
- - name: Build and Publish image
38
- uses: docker/build-push-action@v5
39
- with:
40
- context: .
41
- file: Dockerfile
42
- push: ${{ github.event_name != 'pull_request' }}
43
- tags: ${{ steps.meta.outputs.tags }}
44
- labels: ${{ steps.meta.outputs.labels }}
45
- platforms: linux/amd64
46
- cache-to: type=gha,mode=max,scope=amd64
47
- cache-from: type=gha,scope=amd64
48
- provenance: false
49
-
50
- deploy:
51
- name: Deploy on prod
52
- runs-on: ubuntu-latest
53
- needs: ["build-and-publish"]
54
- steps:
55
- - name: Inject slug/short variables
56
- uses: rlespinasse/github-slug-action@v4
57
-
58
- - name: Gen values
59
- run: |
60
- VALUES=$(cat <<-END
61
- image:
62
- tag: "sha-${{ env.GITHUB_SHA_SHORT }}"
63
- END
64
- )
65
- echo "VALUES=$(echo "$VALUES" | yq -o=json | jq tostring)" >> $GITHUB_ENV
66
-
67
- - name: Deploy on infra-deployments
68
- uses: the-actions-org/workflow-dispatch@v2
69
- with:
70
- workflow: Update application single value
71
- repo: huggingface/infra-deployments
72
- wait-for-completion: true
73
- wait-for-completion-interval: 10s
74
- display-workflow-run-url-interval: 10s
75
- ref: refs/heads/main
76
- token: ${{ secrets.GIT_TOKEN_INFRA_DEPLOYMENT }}
77
- inputs: '{"path": "hub/deepsite/deepsite.yaml", "value": ${{ env.VALUES }}, "url": "${{ github.event.head_commit.url }}"}'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore CHANGED
@@ -31,7 +31,7 @@ yarn-error.log*
31
  .pnpm-debug.log*
32
 
33
  # env files (can opt-in for committing if needed)
34
- .env
35
 
36
  # vercel
37
  .vercel
@@ -39,9 +39,3 @@ yarn-error.log*
39
  # typescript
40
  *.tsbuildinfo
41
  next-env.d.ts
42
-
43
- .idea
44
-
45
- # binary assets (hosted on CDN)
46
- assets/assistant.jpg
47
- .gitattributes
 
31
  .pnpm-debug.log*
32
 
33
  # env files (can opt-in for committing if needed)
34
+ .env*
35
 
36
  # vercel
37
  .vercel
 
39
  # typescript
40
  *.tsbuildinfo
41
  next-env.d.ts
 
 
 
 
 
 
Dockerfile CHANGED
@@ -1,22 +1,19 @@
1
  FROM node:20-alpine
2
  USER root
3
 
4
- # Install pnpm
5
- RUN corepack enable && corepack prepare pnpm@latest --activate
6
-
7
  USER 1000
8
  WORKDIR /usr/src/app
9
- # Copy package.json and pnpm-lock.yaml to the container
10
- COPY --chown=1000 package.json pnpm-lock.yaml ./
11
 
12
  # Copy the rest of the application files to the container
13
  COPY --chown=1000 . .
14
 
15
- RUN pnpm install
16
- RUN pnpm run build
17
 
18
  # Expose the application port (assuming your app runs on port 3000)
19
- EXPOSE 3001
20
 
21
  # Start the application
22
- CMD ["pnpm", "start"]
 
1
  FROM node:20-alpine
2
  USER root
3
 
 
 
 
4
  USER 1000
5
  WORKDIR /usr/src/app
6
+ # Copy package.json and package-lock.json to the container
7
+ COPY --chown=1000 package.json package-lock.json ./
8
 
9
  # Copy the rest of the application files to the container
10
  COPY --chown=1000 . .
11
 
12
+ RUN npm install
13
+ RUN npm run build
14
 
15
  # Expose the application port (assuming your app runs on port 3000)
16
+ EXPOSE 3000
17
 
18
  # Start the application
19
+ CMD ["npm", "start"]
README.md CHANGED
@@ -1,23 +1,22 @@
1
  ---
2
- title: DeepSite v4
3
  emoji: 🐳
4
  colorFrom: blue
5
  colorTo: blue
6
  sdk: docker
7
  pinned: true
8
- app_port: 3001
9
  license: mit
10
- failure_strategy: rollback
11
- short_description: Generate any application by Vibe Coding it
12
  models:
13
  - deepseek-ai/DeepSeek-V3-0324
14
- - deepseek-ai/DeepSeek-V3.2
15
- - Qwen/Qwen3-Coder-30B-A3B-Instruct
16
- - moonshotai/Kimi-K2-Instruct-0905
17
- - zai-org/GLM-4.7
18
- - MiniMaxAI/MiniMax-M2.1
19
  ---
20
 
21
  # DeepSite 🐳
22
 
23
- DeepSite is a Vibe Coding Platform designed to make coding smarter and more efficient. Tailored for developers, data scientists, and AI engineers, it integrates generative AI into your coding projects to enhance creativity and productivity.
 
 
 
 
 
1
  ---
2
+ title: DeepSite v2
3
  emoji: 🐳
4
  colorFrom: blue
5
  colorTo: blue
6
  sdk: docker
7
  pinned: true
8
+ app_port: 3000
9
  license: mit
10
+ short_description: Generate any application with DeepSeek
 
11
  models:
12
  - deepseek-ai/DeepSeek-V3-0324
13
+ - deepseek-ai/DeepSeek-R1-0528
 
 
 
 
14
  ---
15
 
16
  # DeepSite 🐳
17
 
18
+ DeepSite is a coding platform powered by DeepSeek AI, designed to make coding smarter and more efficient. Tailored for developers, data scientists, and AI engineers, it integrates generative AI into your coding projects to enhance creativity and productivity.
19
+
20
+ ## How to use it locally
21
+
22
+ Follow [this discussion](https://huggingface.co/spaces/enzostvs/deepsite/discussions/74)
actions/mentions.ts DELETED
@@ -1,31 +0,0 @@
1
- "use client";
2
-
3
- import { File } from "@/lib/type";
4
-
5
- export const searchMentions = async (query: string) => {
6
- const promises = [searchModels(query), searchDatasets(query)];
7
- const results = await Promise.all(promises);
8
- return { models: results[0], datasets: results[1] };
9
- };
10
-
11
- const searchModels = async (query: string) => {
12
- const response = await fetch(
13
- `https://huggingface.co/api/quicksearch?q=${query}&type=model&limit=3`
14
- );
15
- const data = await response.json();
16
- return data?.models ?? [];
17
- };
18
-
19
- const searchDatasets = async (query: string) => {
20
- const response = await fetch(
21
- `https://huggingface.co/api/quicksearch?q=${query}&type=dataset&limit=3`
22
- );
23
- const data = await response.json();
24
- return data?.datasets ?? [];
25
- };
26
-
27
- export const searchFilesMentions = async (query: string, files: File[]) => {
28
- if (!query) return files;
29
- const lowerQuery = query.toLowerCase();
30
- return files.filter((file) => file.path.toLowerCase().includes(lowerQuery));
31
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
actions/projects.ts DELETED
@@ -1,175 +0,0 @@
1
- "use server";
2
- import {
3
- downloadFile,
4
- listCommits,
5
- listFiles,
6
- listSpaces,
7
- RepoDesignation,
8
- SpaceEntry,
9
- spaceInfo,
10
- } from "@huggingface/hub";
11
-
12
- import { auth } from "@/lib/auth";
13
- import { Commit, File } from "@/lib/type";
14
-
15
- export interface ProjectWithCommits extends SpaceEntry {
16
- commits?: Commit[];
17
- medias?: string[];
18
- }
19
-
20
- const IGNORED_PATHS = ["README.md", ".gitignore", ".gitattributes"];
21
- const IGNORED_FORMATS = [
22
- ".png",
23
- ".jpg",
24
- ".jpeg",
25
- ".gif",
26
- ".svg",
27
- ".webp",
28
- ".mp4",
29
- ".mp3",
30
- ".wav",
31
- ];
32
-
33
- export const getProjects = async () => {
34
- const projects: SpaceEntry[] = [];
35
- const session = await auth();
36
- if (!session?.user) {
37
- return projects;
38
- }
39
- const token = session.accessToken;
40
- for await (const space of listSpaces({
41
- accessToken: token,
42
- additionalFields: ["author", "cardData"],
43
- search: {
44
- owner: session.user.username,
45
- },
46
- })) {
47
- if (
48
- space.sdk === "static" &&
49
- Array.isArray((space.cardData as { tags?: string[] })?.tags) &&
50
- (space.cardData as { tags?: string[] })?.tags?.some((tag) =>
51
- tag.includes("deepsite")
52
- )
53
- ) {
54
- projects.push(space);
55
- }
56
- }
57
- return projects;
58
- };
59
- export const getProject = async (id: string, commitId?: string) => {
60
- const session = await auth();
61
- if (!session?.user) {
62
- return null;
63
- }
64
- const token = session.accessToken;
65
- try {
66
- const project: ProjectWithCommits | null = await spaceInfo({
67
- name: id,
68
- accessToken: token,
69
- additionalFields: ["author", "cardData"],
70
- });
71
- const repo: RepoDesignation = {
72
- type: "space",
73
- name: id,
74
- };
75
- const files: File[] = [];
76
- const medias: string[] = [];
77
- const params = { repo, accessToken: token };
78
- if (commitId) {
79
- Object.assign(params, { revision: commitId });
80
- }
81
- for await (const fileInfo of listFiles(params)) {
82
- if (IGNORED_PATHS.includes(fileInfo.path)) continue;
83
- if (IGNORED_FORMATS.some((format) => fileInfo.path.endsWith(format))) {
84
- medias.push(
85
- `https://huggingface.co/spaces/${id}/resolve/main/${fileInfo.path}`
86
- );
87
- continue;
88
- }
89
-
90
- if (fileInfo.type === "directory") {
91
- for await (const subFile of listFiles({
92
- repo,
93
- accessToken: token,
94
- path: fileInfo.path,
95
- })) {
96
- if (IGNORED_FORMATS.some((format) => subFile.path.endsWith(format))) {
97
- medias.push(
98
- `https://huggingface.co/spaces/${id}/resolve/main/${subFile.path}`
99
- );
100
- }
101
- const blob = await downloadFile({
102
- repo,
103
- accessToken: token,
104
- path: subFile.path,
105
- raw: true,
106
- ...(commitId ? { revision: commitId } : {}),
107
- }).catch((_) => {
108
- return null;
109
- });
110
- if (!blob) {
111
- continue;
112
- }
113
- const html = await blob?.text();
114
- if (!html) {
115
- continue;
116
- }
117
- files[subFile.path === "index.html" ? "unshift" : "push"]({
118
- path: subFile.path,
119
- content: html,
120
- });
121
- }
122
- } else {
123
- const blob = await downloadFile({
124
- repo,
125
- accessToken: token,
126
- path: fileInfo.path,
127
- raw: true,
128
- ...(commitId ? { revision: commitId } : {}),
129
- }).catch((_) => {
130
- return null;
131
- });
132
- if (!blob) {
133
- continue;
134
- }
135
- const html = await blob?.text();
136
- if (!html) {
137
- continue;
138
- }
139
- files[fileInfo.path === "index.html" ? "unshift" : "push"]({
140
- path: fileInfo.path,
141
- content: html,
142
- });
143
- }
144
- }
145
- const commits: Commit[] = [];
146
- const commitIterator = listCommits({ repo, accessToken: token });
147
- for await (const commit of commitIterator) {
148
- if (
149
- commit.title?.toLowerCase() === "initial commit" ||
150
- commit.title
151
- ?.toLowerCase()
152
- ?.includes("upload media files through deepsite")
153
- )
154
- continue;
155
- commits.push({
156
- title: commit.title,
157
- oid: commit.oid,
158
- date: commit.date,
159
- });
160
- if (commits.length >= 20) {
161
- break;
162
- }
163
- }
164
-
165
- project.commits = commits;
166
- project.medias = medias;
167
-
168
- return { project, files };
169
- } catch (error) {
170
- return {
171
- project: null,
172
- files: [],
173
- };
174
- }
175
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/(public)/layout.tsx DELETED
@@ -1,14 +0,0 @@
1
- import { Navigation } from "@/components/public/navigation";
2
-
3
- export default function PublicLayout({
4
- children,
5
- }: Readonly<{
6
- children: React.ReactNode;
7
- }>) {
8
- return (
9
- <div className="min-h-screen font-sans">
10
- <Navigation />
11
- {children}
12
- </div>
13
- );
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/(public)/page.tsx DELETED
@@ -1,25 +0,0 @@
1
- import { AnimatedDotsBackground } from "@/components/public/animated-dots-background";
2
- import { HeroHeader } from "@/components/public/hero-header";
3
- import { UserProjects } from "@/components/projects/user-projects";
4
- import { AskAiLanding } from "@/components/ask-ai/ask-ai-landing";
5
- import { Bento } from "@/components/public/bento";
6
-
7
- export const dynamic = "force-dynamic";
8
-
9
- export default async function Homepage() {
10
- return (
11
- <>
12
- <section className="container mx-auto relative z-10">
13
- <HeroHeader />
14
- <div className="absolute inset-0 -z-10">
15
- <AnimatedDotsBackground />
16
- </div>
17
- <div className="max-w-xl mx-auto px-6">
18
- <AskAiLanding />
19
- </div>
20
- </section>
21
- <UserProjects />
22
- <Bento />
23
- </>
24
- );
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/(public)/signin/page.tsx DELETED
@@ -1,21 +0,0 @@
1
- import { LoginButtons } from "@/components/login/login-buttons";
2
-
3
- export default async function SignInPage({
4
- searchParams,
5
- }: {
6
- searchParams: Promise<{ callbackUrl: string }>;
7
- }) {
8
- const { callbackUrl } = await searchParams;
9
- console.log(callbackUrl);
10
- return (
11
- <section className="min-h-screen font-sans">
12
- <div className="px-6 py-16 max-w-5xl mx-auto text-center">
13
- <h1 className="text-5xl font-bold mb-5">You shall not pass 🧙</h1>
14
- <p className="text-lg text-muted-foreground mb-8">
15
- You can&apos;t access this resource without being signed in.
16
- </p>
17
- <LoginButtons callbackUrl={callbackUrl ?? "/"} />
18
- </div>
19
- </section>
20
- );
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/[owner]/[repoId]/page.tsx DELETED
@@ -1,35 +0,0 @@
1
- import { getProject } from "@/actions/projects";
2
- import { AppEditor } from "@/components/editor";
3
- import { auth } from "@/lib/auth";
4
- import { notFound, redirect } from "next/navigation";
5
-
6
- export default async function ProjectPage({
7
- params,
8
- searchParams,
9
- }: {
10
- params: Promise<{ owner: string; repoId: string }>;
11
- searchParams: Promise<{ commit?: string }>;
12
- }) {
13
- const session = await auth();
14
-
15
- const { owner, repoId } = await params;
16
- const { commit } = await searchParams;
17
- if (!session) {
18
- redirect(
19
- `/api/auth/signin?callbackUrl=/${owner}/${repoId}${
20
- commit ? `?commit=${commit}` : ""
21
- }`
22
- );
23
- }
24
- const datas = await getProject(`${owner}/${repoId}`, commit);
25
- if (!datas?.project) {
26
- return notFound();
27
- }
28
- return (
29
- <AppEditor
30
- project={datas.project}
31
- files={datas.files ?? []}
32
- isHistoryView={!!commit}
33
- />
34
- );
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/ask/route.ts DELETED
@@ -1,183 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { InferenceClient } from "@huggingface/inference";
3
-
4
- import { FOLLOW_UP_SYSTEM_PROMPT, INITIAL_SYSTEM_PROMPT } from "@/lib/prompts";
5
- import { auth } from "@/lib/auth";
6
- import { File, Message } from "@/lib/type";
7
- import { DEFAULT_MODEL, MODELS } from "@/lib/providers";
8
-
9
- export async function POST(request: Request) {
10
- const session = await auth();
11
- if (!session) {
12
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
13
- }
14
- const token = session.accessToken;
15
-
16
- const body = await request.json();
17
- const {
18
- prompt,
19
- previousMessages = [],
20
- files = [],
21
- provider,
22
- model,
23
- redesignMd,
24
- medias,
25
- } = body;
26
-
27
- if (!prompt) {
28
- return NextResponse.json({ error: "Prompt is required" }, { status: 400 });
29
- }
30
- if (!model || !MODELS.find((m: (typeof MODELS)[0]) => m.value === model)) {
31
- return NextResponse.json({ error: "Model is required" }, { status: 400 });
32
- }
33
-
34
- const client = new InferenceClient(token);
35
-
36
- try {
37
- const encoder = new TextEncoder();
38
- const stream = new TransformStream();
39
- const writer = stream.writable.getWriter();
40
-
41
- const response = new NextResponse(stream.readable, {
42
- headers: {
43
- "Content-Type": "text/plain; charset=utf-8",
44
- "Cache-Control": "no-cache",
45
- Connection: "keep-alive",
46
- },
47
- });
48
- (async () => {
49
- let hasRetried = false;
50
- let currentModel = model;
51
-
52
- const tryGeneration = async (): Promise<void> => {
53
- try {
54
- const chatCompletion = client.chatCompletionStream({
55
- model: currentModel + (provider !== "auto" ? `:${provider}` : ""),
56
- messages: [
57
- {
58
- role: "system",
59
- content:
60
- files.length > 0
61
- ? FOLLOW_UP_SYSTEM_PROMPT
62
- : INITIAL_SYSTEM_PROMPT,
63
- },
64
- ...previousMessages.map((message: Message) => ({
65
- role: message.role,
66
- content: message.content,
67
- })),
68
- ...(files?.length > 0
69
- ? [
70
- {
71
- role: "user",
72
- content: `Here are the files that the user has provider:${files
73
- .map(
74
- (file: File) =>
75
- `File: ${file.path}\nContent: ${file.content}`
76
- )
77
- .join("\n")}\n\n${prompt}`,
78
- },
79
- ]
80
- : []),
81
- {
82
- role: "user",
83
- content: `${
84
- redesignMd?.url &&
85
- `Redesign the following website ${redesignMd.url}, try to use the same images and content, but you can still improve it if needed. Do the best version possibile. Here is the markdown:\n ${redesignMd.md} \n\n`
86
- }${prompt} ${
87
- medias && medias.length > 0
88
- ? `\nHere is the list of my media files: ${medias.join(
89
- ", "
90
- )}\n`
91
- : ""
92
- }`,
93
- }
94
- ],
95
- stream: true,
96
- max_tokens: 16_000,
97
- });
98
- while (true) {
99
- const { done, value } = await chatCompletion.next();
100
- if (done) {
101
- break;
102
- }
103
-
104
- const chunk = value.choices[0]?.delta?.content;
105
- if (chunk) {
106
- await writer.write(encoder.encode(chunk));
107
- }
108
- }
109
-
110
- await writer.close();
111
- } catch (error) {
112
- const errorMessage =
113
- error instanceof Error
114
- ? error.message
115
- : "An error occurred while processing your request";
116
-
117
- if (
118
- !hasRetried &&
119
- errorMessage?.includes(
120
- "Failed to perform inference: Model not found"
121
- )
122
- ) {
123
- hasRetried = true;
124
- if (model === DEFAULT_MODEL) {
125
- const availableFallbackModels = MODELS.filter(
126
- (m) => m.value !== model
127
- );
128
- const randomIndex = Math.floor(
129
- Math.random() * availableFallbackModels.length
130
- );
131
- currentModel = availableFallbackModels[randomIndex];
132
- } else {
133
- currentModel = DEFAULT_MODEL;
134
- }
135
- const switchMessage = `\n\n_Note: The selected model was not available. Switched to \`${currentModel}\`._\n\n`;
136
- await writer.write(encoder.encode(switchMessage));
137
-
138
- return tryGeneration();
139
- }
140
-
141
- try {
142
- let errorPayload = "";
143
- if (
144
- errorMessage?.includes("exceeded your monthly included credits") ||
145
- errorMessage?.includes("reached the free monthly usage limit")
146
- ) {
147
- errorPayload = JSON.stringify({
148
- messageError: errorMessage,
149
- showProMessage: true,
150
- isError: true,
151
- });
152
- } else {
153
- errorPayload = JSON.stringify({
154
- messageError: errorMessage,
155
- isError: true,
156
- });
157
- }
158
- await writer.write(encoder.encode(`\n\n__ERROR__:${errorPayload}`));
159
- await writer.close();
160
- } catch (closeError) {
161
- console.error("Failed to send error message:", closeError);
162
- try {
163
- await writer.abort(error);
164
- } catch (abortError) {
165
- console.error("Failed to abort writer:", abortError);
166
- }
167
- }
168
- }
169
- };
170
-
171
- await tryGeneration();
172
- })();
173
-
174
- return response;
175
- } catch (error) {
176
- return NextResponse.json(
177
- {
178
- error: error instanceof Error ? error.message : "Internal Server Error",
179
- },
180
- { status: 500 }
181
- );
182
- }
183
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/auth/[...nextauth]/route.ts DELETED
@@ -1,6 +0,0 @@
1
- import NextAuth from "next-auth";
2
- import { authOptions } from "@/lib/auth";
3
-
4
- const handler = NextAuth(authOptions);
5
-
6
- export { handler as GET, handler as POST };
 
 
 
 
 
 
 
app/api/healthcheck/route.ts DELETED
@@ -1,5 +0,0 @@
1
- import { NextResponse } from "next/server";
2
-
3
- export async function GET() {
4
- return NextResponse.json({ status: "ok" }, { status: 200 });
5
- }
 
 
 
 
 
 
app/api/projects/[repoId]/[commitId]/route.ts DELETED
@@ -1,49 +0,0 @@
1
- import { auth } from "@/lib/auth";
2
- import { createBranch, RepoDesignation } from "@huggingface/hub";
3
- import { format } from "date-fns";
4
- import { NextResponse } from "next/server";
5
-
6
- export async function POST(
7
- request: Request,
8
- { params }: { params: Promise<{ repoId: string; commitId: string }> }
9
- ) {
10
- const { repoId, commitId }: { repoId: string; commitId: string } =
11
- await params;
12
- const session = await auth();
13
- if (!session) {
14
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
15
- }
16
- const token = session.accessToken;
17
-
18
- const repo: RepoDesignation = {
19
- type: "space",
20
- name: session.user?.username + "/" + repoId,
21
- };
22
-
23
- const commitTitle = `🔖 ${format(new Date(), "dd/MM")} - ${format(
24
- new Date(),
25
- "HH:mm"
26
- )} - Set commit ${commitId} as default.`;
27
-
28
- await fetch(
29
- `https://huggingface.co/api/spaces/${session.user?.username}/${repoId}/branch/main`,
30
- {
31
- method: "POST",
32
- headers: {
33
- Authorization: `Bearer ${token}`,
34
- "Content-Type": "application/json",
35
- },
36
- body: JSON.stringify({
37
- startingPoint: commitId,
38
- overwrite: true,
39
- }),
40
- }
41
- ).catch((error) => {
42
- return NextResponse.json(
43
- { error: error ?? "Failed to create branch" },
44
- { status: 500 }
45
- );
46
- });
47
-
48
- return NextResponse.json({ success: true }, { status: 200 });
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/projects/[repoId]/download/route.ts DELETED
@@ -1,76 +0,0 @@
1
- import { auth } from "@/lib/auth";
2
- import { downloadFile, listFiles, RepoDesignation } from "@huggingface/hub";
3
- import { NextResponse } from "next/server";
4
- import JSZip from "jszip";
5
-
6
- export async function GET(
7
- request: Request,
8
- { params }: { params: Promise<{ repoId: string }> }
9
- ) {
10
- const { repoId }: { repoId: string } = await params;
11
- const session = await auth();
12
- if (!session) {
13
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
14
- }
15
- const token = session.accessToken;
16
- const repo: RepoDesignation = {
17
- type: "space",
18
- name: session.user?.username + "/" + repoId,
19
- };
20
-
21
- try {
22
- const zip = new JSZip();
23
- for await (const fileInfo of listFiles({
24
- repo,
25
- accessToken: token as string,
26
- recursive: true,
27
- })) {
28
- if (fileInfo.type === "directory" || fileInfo.path.startsWith(".")) {
29
- continue;
30
- }
31
-
32
- try {
33
- const blob = await downloadFile({
34
- repo,
35
- accessToken: token as string,
36
- path: fileInfo.path,
37
- raw: true
38
- }).catch((error) => {
39
- return null;
40
- });
41
- if (!blob) {
42
- continue;
43
- }
44
-
45
- if (blob) {
46
- const arrayBuffer = await blob.arrayBuffer();
47
- zip.file(fileInfo.path, arrayBuffer);
48
- }
49
- } catch (error) {
50
- console.error(`Error downloading file ${fileInfo.path}:`, error);
51
- }
52
- }
53
-
54
- const zipBlob = await zip.generateAsync({
55
- type: "blob",
56
- compression: "DEFLATE",
57
- compressionOptions: {
58
- level: 6
59
- }
60
- });
61
-
62
- const projectName = `${session.user?.username}-${repoId}`.replace(/[^a-zA-Z0-9-_]/g, '_');
63
- const filename = `${projectName}.zip`;
64
-
65
- return new NextResponse(zipBlob, {
66
- headers: {
67
- "Content-Type": "application/zip",
68
- "Content-Disposition": `attachment; filename="${filename}"`,
69
- "Content-Length": zipBlob.size.toString(),
70
- },
71
- });
72
- } catch (error) {
73
- console.error("Error downloading project:", error);
74
- return NextResponse.json({ error: "Failed to download project" }, { status: 500 });
75
- }
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/projects/[repoId]/medias/route.ts DELETED
@@ -1,87 +0,0 @@
1
- import { auth } from "@/lib/auth";
2
- import { RepoDesignation, uploadFiles } from "@huggingface/hub";
3
- import { NextResponse } from "next/server";
4
-
5
- export async function POST(
6
- request: Request,
7
- { params }: { params: Promise<{ repoId: string }> }
8
- ) {
9
- const { repoId }: { repoId: string } = await params;
10
- const session = await auth();
11
- if (!session) {
12
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
13
- }
14
- const token = session.accessToken;
15
-
16
- const repo: RepoDesignation = {
17
- type: "space",
18
- name: session.user?.username + "/" + repoId,
19
- };
20
-
21
- const formData = await request.formData();
22
- const newMedias = formData.getAll("images") as File[];
23
-
24
- const filesToUpload: File[] = [];
25
-
26
- if (!newMedias || newMedias.length === 0) {
27
- return NextResponse.json(
28
- {
29
- ok: false,
30
- error: "At least one media file is required under the 'images' key",
31
- },
32
- { status: 400 }
33
- );
34
- }
35
-
36
- try {
37
- for (const media of newMedias) {
38
- const isImage = media.type.startsWith("image/");
39
- const isVideo = media.type.startsWith("video/");
40
- const isAudio = media.type.startsWith("audio/");
41
-
42
- const folderPath = isImage
43
- ? "images/"
44
- : isVideo
45
- ? "videos/"
46
- : isAudio
47
- ? "audios/"
48
- : null;
49
-
50
- if (!folderPath) {
51
- return NextResponse.json(
52
- { ok: false, error: "Unsupported media type: " + media.type },
53
- { status: 400 }
54
- );
55
- }
56
-
57
- const mediaName = `${folderPath}${media.name}`;
58
- const processedFile = new File([media], mediaName, { type: media.type });
59
- filesToUpload.push(processedFile);
60
- }
61
-
62
- await uploadFiles({
63
- repo,
64
- files: filesToUpload,
65
- accessToken: token,
66
- commitTitle: `📁 Upload media files through DeepSite`,
67
- });
68
-
69
- return NextResponse.json(
70
- {
71
- success: true,
72
- medias: filesToUpload.map(
73
- (file) =>
74
- `https://huggingface.co/spaces/${session.user?.username}/${repoId}/resolve/main/${file.name}`
75
- ),
76
- },
77
- { status: 200 }
78
- );
79
- } catch (error) {
80
- return NextResponse.json(
81
- { ok: false, error: error ?? "Failed to upload media files" },
82
- { status: 500 }
83
- );
84
- }
85
-
86
- return NextResponse.json({ success: true }, { status: 200 });
87
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/projects/[repoId]/rename/route.ts DELETED
@@ -1,92 +0,0 @@
1
- import { auth } from "@/lib/auth";
2
- import { downloadFile, RepoDesignation, uploadFile } from "@huggingface/hub";
3
- import { format } from "date-fns";
4
- import { NextResponse } from "next/server";
5
-
6
- export async function PUT(
7
- request: Request,
8
- { params }: { params: Promise<{ repoId: string }> }
9
- ) {
10
- const { repoId }: { repoId: string } = await params;
11
- const session = await auth();
12
- if (!session) {
13
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
14
- }
15
- const token = session.accessToken;
16
-
17
- const body = await request.json();
18
- const { newTitle } = body;
19
-
20
- if (!newTitle) {
21
- return NextResponse.json(
22
- { error: "newTitle is required" },
23
- { status: 400 }
24
- );
25
- }
26
-
27
- const repo: RepoDesignation = {
28
- type: "space",
29
- name: session.user?.username + "/" + repoId,
30
- };
31
-
32
- const blob = await downloadFile({
33
- repo,
34
- accessToken: token,
35
- path: "README.md",
36
- raw: true,
37
- }).catch((_) => {
38
- return null;
39
- });
40
-
41
- if (!blob) {
42
- return NextResponse.json(
43
- { error: "Could not fetch README.md" },
44
- { status: 500 }
45
- );
46
- }
47
-
48
- const readmeFile = await blob?.text();
49
- if (!readmeFile) {
50
- return NextResponse.json(
51
- { error: "Could not read README.md content" },
52
- { status: 500 }
53
- );
54
- }
55
-
56
- // Escape YAML values to prevent injection attacks
57
- const escapeYamlValue = (value: string): string => {
58
- if (/[:|>]|^[-*#]|^\s|['"]/.test(value) || value.includes("\n")) {
59
- return `"${value.replace(/"/g, '\\"')}"`;
60
- }
61
- return value;
62
- };
63
-
64
- // Escape commit message to prevent injection
65
- const escapeCommitMessage = (message: string): string => {
66
- return message.replace(/[\r\n]/g, " ").slice(0, 200);
67
- };
68
-
69
- const updatedReadmeFile = readmeFile.replace(
70
- /^title:\s*(.*)$/m,
71
- `title: ${escapeYamlValue(newTitle)}`
72
- );
73
-
74
- await uploadFile({
75
- repo,
76
- accessToken: token,
77
- file: new File([updatedReadmeFile], "README.md", { type: "text/markdown" }),
78
- commitTitle: escapeCommitMessage(
79
- `🐳 ${format(new Date(), "dd/MM")} - ${format(
80
- new Date(),
81
- "HH:mm"
82
- )} - Rename project to "${newTitle}"`
83
- ),
84
- });
85
-
86
- return NextResponse.json(
87
- {
88
- success: true,
89
- },
90
- { status: 200 }
91
- );
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/projects/[repoId]/route.ts DELETED
@@ -1,104 +0,0 @@
1
- import { auth } from "@/lib/auth";
2
- import { RepoDesignation, deleteRepo, uploadFiles } from "@huggingface/hub";
3
- import { format } from "date-fns";
4
- import { NextResponse } from "next/server";
5
-
6
- export async function PUT(
7
- request: Request,
8
- { params }: { params: Promise<{ repoId: string }> }
9
- ) {
10
- const { repoId }: { repoId: string } = await params;
11
- const session = await auth();
12
- if (!session) {
13
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
14
- }
15
- const token = session.accessToken;
16
-
17
- const body = await request.json();
18
- const { files, prompt, isManualChanges } = body;
19
-
20
- if (!files) {
21
- return NextResponse.json({ error: "Files are required" }, { status: 400 });
22
- }
23
-
24
- if (!prompt) {
25
- return NextResponse.json({ error: "Prompt is required" }, { status: 400 });
26
- }
27
-
28
- const repo: RepoDesignation = {
29
- type: "space",
30
- name: session.user?.username + "/" + repoId,
31
- };
32
-
33
- const filesToUpload: File[] = [];
34
- for (const file of files) {
35
- let mimeType = "text/x-python";
36
- if (file.path.endsWith(".txt")) {
37
- mimeType = "text/plain";
38
- } else if (file.path.endsWith(".md")) {
39
- mimeType = "text/markdown";
40
- } else if (file.path.endsWith(".json")) {
41
- mimeType = "application/json";
42
- }
43
- filesToUpload.push(new File([file.content], file.path, { type: mimeType }));
44
- }
45
- // Escape commit title to prevent injection
46
- const escapeCommitTitle = (title: string): string => {
47
- return title.replace(/[\r\n]/g, " ").slice(0, 200);
48
- };
49
-
50
- const baseTitle = isManualChanges
51
- ? ""
52
- : `🐳 ${format(new Date(), "dd/MM")} - ${format(new Date(), "HH:mm")} - `;
53
- const commitTitle = escapeCommitTitle(
54
- baseTitle + (prompt ?? "Follow-up DeepSite commit")
55
- );
56
- const response = await uploadFiles({
57
- repo,
58
- files: filesToUpload,
59
- accessToken: token,
60
- commitTitle,
61
- });
62
-
63
- return NextResponse.json(
64
- {
65
- success: true,
66
- commit: {
67
- oid: response.commit,
68
- title: commitTitle,
69
- date: new Date(),
70
- },
71
- },
72
- { status: 200 }
73
- );
74
- }
75
-
76
- export async function DELETE(
77
- request: Request,
78
- { params }: { params: Promise<{ repoId: string }> }
79
- ) {
80
- const { repoId }: { repoId: string } = await params;
81
- const session = await auth();
82
- if (!session) {
83
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
84
- }
85
- const token = session.accessToken;
86
-
87
- const repo: RepoDesignation = {
88
- type: "space",
89
- name: session.user?.username + "/" + repoId,
90
- };
91
-
92
- try {
93
- await deleteRepo({
94
- repo,
95
- accessToken: token as string,
96
- });
97
-
98
- return NextResponse.json({ success: true }, { status: 200 });
99
- } catch (error) {
100
- const errMsg =
101
- error instanceof Error ? error.message : "Failed to delete project";
102
- return NextResponse.json({ error: errMsg }, { status: 500 });
103
- }
104
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/projects/route.ts DELETED
@@ -1,145 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { RepoDesignation, createRepo, uploadFiles } from "@huggingface/hub";
3
-
4
- import { auth } from "@/lib/auth";
5
- import {
6
- COLORS,
7
- EMOJIS_FOR_SPACE,
8
- injectDeepSiteBadge,
9
- isIndexPage,
10
- } from "@/lib/utils";
11
-
12
- // todo: catch error while publishing project, and return the error to the user
13
- // if space has been created, but can't push, try again or catch well the error and return the error to the user
14
-
15
- export async function POST(request: Request) {
16
- const session = await auth();
17
- if (!session) {
18
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
19
- }
20
- const token = session.accessToken;
21
-
22
- const body = await request.json();
23
- const { projectTitle, files, prompt } = body;
24
-
25
- if (!files) {
26
- return NextResponse.json(
27
- { error: "Project title and files are required" },
28
- { status: 400 }
29
- );
30
- }
31
-
32
- const title =
33
- projectTitle || projectTitle !== "" ? projectTitle : "DeepSite Project";
34
-
35
- let formattedTitle = title
36
- .toLowerCase()
37
- .replace(/[^a-z0-9]+/g, "-")
38
- .split("-")
39
- .filter(Boolean)
40
- .join("-")
41
- .slice(0, 75);
42
-
43
- formattedTitle =
44
- formattedTitle + "-" + Math.random().toString(36).substring(2, 7);
45
-
46
- const repo: RepoDesignation = {
47
- type: "space",
48
- name: session.user?.username + "/" + formattedTitle,
49
- };
50
-
51
- // Escape YAML values to prevent injection attacks
52
- const escapeYamlValue = (value: string): string => {
53
- if (/[:|>]|^[-*#]|^\s|['"]/.test(value) || value.includes("\n")) {
54
- return `"${value.replace(/"/g, '\\"')}"`;
55
- }
56
- return value;
57
- };
58
-
59
- // Escape markdown headers to prevent injection
60
- const escapeMarkdownHeader = (value: string): string => {
61
- return value.replace(/^#+\s*/g, "").replace(/\n/g, " ");
62
- };
63
-
64
- const colorFrom = COLORS[Math.floor(Math.random() * COLORS.length)];
65
- const colorTo = COLORS[Math.floor(Math.random() * COLORS.length)];
66
- const emoji =
67
- EMOJIS_FOR_SPACE[Math.floor(Math.random() * EMOJIS_FOR_SPACE.length)];
68
- const README = `---
69
- title: ${escapeYamlValue(projectTitle)}
70
- colorFrom: ${colorFrom}
71
- colorTo: ${colorTo}
72
- sdk: static
73
- emoji: ${emoji}
74
- tags:
75
- - deepsite-v4
76
- ---
77
-
78
- # ${escapeMarkdownHeader(title)}
79
-
80
- This project has been created with [DeepSite](https://deepsite.hf.co) AI Vibe Coding.
81
- `;
82
-
83
- const filesToUpload: File[] = [
84
- new File([README], "README.md", { type: "text/markdown" }),
85
- ];
86
- for (const file of files) {
87
- let mimeType = "text/html";
88
- if (file.path.endsWith(".css")) {
89
- mimeType = "text/css";
90
- } else if (file.path.endsWith(".js")) {
91
- mimeType = "text/javascript";
92
- }
93
- const content =
94
- mimeType === "text/html" && isIndexPage(file.path)
95
- ? injectDeepSiteBadge(file.content)
96
- : file.content;
97
-
98
- filesToUpload.push(new File([content], file.path, { type: mimeType }));
99
- }
100
-
101
- let repoUrl: string | undefined;
102
-
103
- try {
104
- // Create the space first
105
- const createResult = await createRepo({
106
- accessToken: token as string,
107
- repo: repo,
108
- sdk: "static",
109
- });
110
- repoUrl = createResult.repoUrl;
111
-
112
- // Escape commit message to prevent injection
113
- const escapeCommitMessage = (message: string): string => {
114
- return message.replace(/[\r\n]/g, " ").slice(0, 200);
115
- };
116
- const commitMessage = escapeCommitMessage(prompt ?? "Initial DeepSite commit");
117
-
118
- // Upload files to the created space
119
- await uploadFiles({
120
- repo,
121
- files: filesToUpload,
122
- accessToken: token as string,
123
- commitTitle: commitMessage,
124
- });
125
-
126
- const path = repoUrl.split("/").slice(-2).join("/");
127
-
128
- return NextResponse.json({ repoUrl: path }, { status: 200 });
129
- } catch (error) {
130
- const errMsg =
131
- error instanceof Error ? error.message : "Failed to create or upload to space";
132
-
133
- // If space was created but upload failed, include the repo URL in the error
134
- if (repoUrl) {
135
- const path = repoUrl.split("/").slice(-2).join("/");
136
- return NextResponse.json({
137
- error: `${errMsg}. Space was created at ${path} but files could not be uploaded.`,
138
- repoUrl: path,
139
- partialSuccess: true
140
- }, { status: 500 });
141
- }
142
-
143
- return NextResponse.json({ error: errMsg }, { status: 500 });
144
- }
145
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/redesign/route.ts DELETED
@@ -1,73 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { NextRequest, NextResponse } from "next/server";
3
-
4
- const FETCH_TIMEOUT = 30_000;
5
- export const maxDuration = 60;
6
-
7
- export async function PUT(request: NextRequest) {
8
- const body = await request.json();
9
- const { url } = body;
10
-
11
- if (!url) {
12
- return NextResponse.json({ error: "URL is required" }, { status: 400 });
13
- }
14
-
15
- try {
16
- const controller = new AbortController();
17
- const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT);
18
-
19
- try {
20
- const response = await fetch(
21
- `https://r.jina.ai/${encodeURIComponent(url)}`,
22
- {
23
- method: "POST",
24
- signal: controller.signal,
25
- }
26
- );
27
-
28
- clearTimeout(timeoutId);
29
-
30
- if (!response.ok) {
31
- return NextResponse.json(
32
- { error: "Failed to fetch redesign" },
33
- { status: 500 }
34
- );
35
- }
36
- const markdown = await response.text();
37
- return NextResponse.json(
38
- {
39
- ok: true,
40
- markdown,
41
- },
42
- { status: 200 }
43
- );
44
- } catch (fetchError: any) {
45
- clearTimeout(timeoutId);
46
-
47
- if (fetchError.name === "AbortError") {
48
- return NextResponse.json(
49
- {
50
- error:
51
- "Request timeout: The external service took too long to respond. Please try again.",
52
- },
53
- { status: 504 }
54
- );
55
- }
56
- throw fetchError;
57
- }
58
- } catch (error: any) {
59
- if (error.name === "AbortError" || error.message?.includes("timeout")) {
60
- return NextResponse.json(
61
- {
62
- error:
63
- "Request timeout: The external service took too long to respond. Please try again.",
64
- },
65
- { status: 504 }
66
- );
67
- }
68
- return NextResponse.json(
69
- { error: error.message || "An error occurred" },
70
- { status: 500 }
71
- );
72
- }
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/favicon.ico DELETED
Binary file (25.9 kB)
 
app/layout.tsx DELETED
@@ -1,108 +0,0 @@
1
- import type { Metadata, Viewport } from "next";
2
- import { Geist, Geist_Mono } from "next/font/google";
3
- import { NextStepProvider } from "nextstepjs";
4
- import Script from "next/script";
5
-
6
- import "@/app/globals.css";
7
- import { ThemeProvider } from "@/components/providers/theme";
8
- import { AuthProvider } from "@/components/providers/session";
9
- import { Toaster } from "@/components/ui/sonner";
10
- import { ReactQueryProvider } from "@/components/providers/react-query";
11
- import { generateSEO, generateStructuredData } from "@/lib/seo";
12
- import { NotAuthorizedDomain } from "@/components/not-authorized";
13
-
14
- const geistSans = Geist({
15
- variable: "--font-geist-sans",
16
- subsets: ["latin"],
17
- });
18
-
19
- const geistMono = Geist_Mono({
20
- variable: "--font-geist-mono",
21
- subsets: ["latin"],
22
- });
23
-
24
- export const metadata: Metadata = {
25
- ...generateSEO({
26
- title: "DeepSite | Build with AI ✨",
27
- description:
28
- "DeepSite is a web development tool that helps you build websites with AI, no code required. Let's deploy your website with DeepSite and enjoy the magic of AI.",
29
- path: "/",
30
- }),
31
- appleWebApp: {
32
- capable: true,
33
- title: "DeepSite",
34
- statusBarStyle: "black-translucent",
35
- },
36
- icons: {
37
- icon: "/logo.svg",
38
- shortcut: "/logo.svg",
39
- apple: "/logo.svg",
40
- },
41
- verification: {
42
- google: process.env.GOOGLE_SITE_VERIFICATION,
43
- },
44
- };
45
-
46
- export const viewport: Viewport = {
47
- initialScale: 1,
48
- maximumScale: 1,
49
- themeColor: "#4f46e5",
50
- };
51
-
52
- export default async function RootLayout({
53
- children,
54
- }: Readonly<{
55
- children: React.ReactNode;
56
- }>) {
57
- const structuredData = generateStructuredData("WebApplication", {
58
- name: "DeepSite",
59
- description: "Build websites with AI, no code required",
60
- url: "https://deepsite.hf.co",
61
- });
62
- const organizationData = generateStructuredData("Organization", {
63
- name: "DeepSite",
64
- url: "https://deepsite.hf.co",
65
- });
66
-
67
- return (
68
- <html lang="en" suppressHydrationWarning>
69
- <body
70
- className={`${geistSans.variable} ${geistMono.variable} antialiased`}
71
- >
72
- <script
73
- type="application/ld+json"
74
- dangerouslySetInnerHTML={{
75
- __html: JSON.stringify(structuredData),
76
- }}
77
- />
78
- <script
79
- type="application/ld+json"
80
- dangerouslySetInnerHTML={{
81
- __html: JSON.stringify(organizationData),
82
- }}
83
- />
84
- <Script
85
- defer
86
- data-domain="deepsite.hf.co"
87
- src="https://plausible.io/js/script.js"
88
- />
89
- <Toaster richColors />
90
- <AuthProvider>
91
- <ReactQueryProvider>
92
- <ThemeProvider
93
- attribute="class"
94
- defaultTheme="dark"
95
- enableSystem
96
- disableTransitionOnChange
97
- >
98
- <NextStepProvider>
99
- {children}
100
- <NotAuthorizedDomain />
101
- </NextStepProvider>
102
- </ThemeProvider>
103
- </ReactQueryProvider>
104
- </AuthProvider>
105
- </body>
106
- </html>
107
- );
108
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/new/page.tsx DELETED
@@ -1,18 +0,0 @@
1
- import { AppEditor } from "@/components/editor";
2
- import { auth } from "@/lib/auth";
3
- import { redirect } from "next/navigation";
4
-
5
- export default async function NewProjectPage({
6
- searchParams,
7
- }: {
8
- searchParams: Promise<{ prompt: string }>;
9
- }) {
10
- const session = await auth();
11
-
12
- if (!session) {
13
- redirect("/api/auth/signin?callbackUrl=/new");
14
- }
15
-
16
- const { prompt } = await searchParams;
17
- return <AppEditor isNew={true} initialPrompt={prompt} />;
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/not-found.tsx DELETED
@@ -1,17 +0,0 @@
1
- import { NotFoundButtons } from "@/components/not-found/buttons";
2
- import { Navigation } from "@/components/public/navigation";
3
-
4
- export default function NotFound() {
5
- return (
6
- <div className="min-h-screen font-sans">
7
- <Navigation />
8
- <div className="px-6 py-16 max-w-5xl mx-auto text-center">
9
- <h1 className="text-5xl font-bold mb-5">Oh no! Page not found.</h1>
10
- <p className="text-lg text-muted-foreground mb-8">
11
- The page you are looking for does not exist.
12
- </p>
13
- <NotFoundButtons />
14
- </div>
15
- </div>
16
- );
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/deepseek.svg DELETED
{app → assets}/globals.css RENAMED
@@ -6,8 +6,8 @@
6
  @theme inline {
7
  --color-background: var(--background);
8
  --color-foreground: var(--foreground);
9
- --font-sans: var(--font-geist-sans);
10
- --font-mono: var(--font-geist-mono);
11
  --color-sidebar-ring: var(--sidebar-ring);
12
  --color-sidebar-border: var(--sidebar-border);
13
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
@@ -44,7 +44,7 @@
44
  }
45
 
46
  :root {
47
- --radius: 0.65rem;
48
  --background: oklch(1 0 0);
49
  --foreground: oklch(0.145 0 0);
50
  --card: oklch(1 0 0);
@@ -68,7 +68,6 @@
68
  --chart-3: oklch(0.398 0.07 227.392);
69
  --chart-4: oklch(0.828 0.189 84.429);
70
  --chart-5: oklch(0.769 0.188 70.08);
71
- --radius: 0.625rem;
72
  --sidebar: oklch(0.985 0 0);
73
  --sidebar-foreground: oklch(0.145 0 0);
74
  --sidebar-primary: oklch(0.205 0 0);
@@ -120,49 +119,28 @@
120
  body {
121
  @apply bg-background text-foreground;
122
  }
 
 
 
 
 
 
 
 
 
 
123
  }
124
 
125
  .monaco-editor .margin {
126
- @apply bg-background!;
127
  }
128
  .monaco-editor .monaco-editor-background {
129
- @apply bg-background!;
130
- }
131
- .monaco-editor .decorationsOverviewRuler {
132
- @apply opacity-0!;
133
- }
134
- .monaco-editor .view-line {
135
- /* @apply bg-primary/50!; */
136
  }
137
- .monaco-editor .scroll-decoration {
138
- @apply opacity-0!;
139
- }
140
- .monaco-editor .cursors-layer .cursor {
141
- @apply bg-primary!;
142
- }
143
-
144
- .content-placeholder::before {
145
- content: attr(data-placeholder);
146
- position: absolute;
147
- pointer-events: none;
148
- opacity: 0.5;
149
- @apply top-5 left-6;
150
  }
151
 
152
- .sp-layout
153
- .sp-file-explorer
154
- .sp-file-explorer-list
155
- .sp-explorer[data-active="true"] {
156
- @apply text-indigo-500!;
157
- }
158
-
159
- .sp-layout
160
- .sp-stack
161
- .sp-tabs
162
- .sp-tab-container[aria-selected="true"]
163
- .sp-tab-button {
164
- @apply text-indigo-500!;
165
- }
166
- .sp-layout .sp-stack .sp-tabs .sp-tab-container:has(button:focus) {
167
- @apply outline-none! border-none!;
168
  }
 
6
  @theme inline {
7
  --color-background: var(--background);
8
  --color-foreground: var(--foreground);
9
+ --font-sans: var(--font-inter-sans);
10
+ --font-mono: var(--font-ptSans-mono);
11
  --color-sidebar-ring: var(--sidebar-ring);
12
  --color-sidebar-border: var(--sidebar-border);
13
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
 
44
  }
45
 
46
  :root {
47
+ --radius: 0.625rem;
48
  --background: oklch(1 0 0);
49
  --foreground: oklch(0.145 0 0);
50
  --card: oklch(1 0 0);
 
68
  --chart-3: oklch(0.398 0.07 227.392);
69
  --chart-4: oklch(0.828 0.189 84.429);
70
  --chart-5: oklch(0.769 0.188 70.08);
 
71
  --sidebar: oklch(0.985 0 0);
72
  --sidebar-foreground: oklch(0.145 0 0);
73
  --sidebar-primary: oklch(0.205 0 0);
 
119
  body {
120
  @apply bg-background text-foreground;
121
  }
122
+ html {
123
+ @apply scroll-smooth;
124
+ }
125
+ }
126
+
127
+ .background__noisy {
128
+ @apply bg-blend-normal pointer-events-none opacity-90;
129
+ background-size: 25ww auto;
130
+ background-image: url("/background_noisy.webp");
131
+ @apply fixed w-screen h-screen -z-1 top-0 left-0;
132
  }
133
 
134
  .monaco-editor .margin {
135
+ @apply !bg-neutral-900;
136
  }
137
  .monaco-editor .monaco-editor-background {
138
+ @apply !bg-neutral-900;
 
 
 
 
 
 
139
  }
140
+ .monaco-editor .line-numbers {
141
+ @apply !text-neutral-500;
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
 
144
+ .matched-line {
145
+ @apply bg-sky-500/30;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  }
assets/hf-logo.svg DELETED
assets/kimi.svg DELETED
assets/logo.svg ADDED
assets/minimax.svg DELETED
assets/pro.svg DELETED
assets/qwen.svg DELETED
assets/zai.svg DELETED
chart/Chart.yaml DELETED
@@ -1,5 +0,0 @@
1
- apiVersion: v2
2
- name: deepsite
3
- version: 0.0.0-latest
4
- type: application
5
- icon: https://huggingface.co/front/assets/huggingface_logo-noborder.svg
 
 
 
 
 
 
chart/env/prod.yaml DELETED
@@ -1,59 +0,0 @@
1
- nodeSelector:
2
- role-deepsite: "true"
3
-
4
- tolerations:
5
- - key: "huggingface.co/deepsite"
6
- operator: "Equal"
7
- value: "true"
8
- effect: "NoSchedule"
9
-
10
- serviceAccount:
11
- enabled: true
12
- create: true
13
- name: deepsite-prod
14
-
15
- ingress:
16
- path: "/"
17
- annotations:
18
- alb.ingress.kubernetes.io/healthcheck-path: "/api/healthcheck"
19
- alb.ingress.kubernetes.io/listen-ports: "[{\"HTTP\": 80}, {\"HTTPS\": 443}]"
20
- alb.ingress.kubernetes.io/load-balancer-name: "hub-utils-prod-cloudfront"
21
- alb.ingress.kubernetes.io/group.name: "hub-utils-prod-cloudfront"
22
- alb.ingress.kubernetes.io/scheme: "internal"
23
- alb.ingress.kubernetes.io/ssl-redirect: "443"
24
- alb.ingress.kubernetes.io/tags: "Env=prod,Project=hub,Terraform=true"
25
- alb.ingress.kubernetes.io/target-group-attributes: deregistration_delay.timeout_seconds=30
26
- alb.ingress.kubernetes.io/target-type: "ip"
27
- alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:707930574880:certificate/5b25b145-75db-4837-b9f3-7f238ba8a9c7,arn:aws:acm:us-east-1:707930574880:certificate/bfdf509c-f44b-400f-b9e1-6f7a861abe91"
28
- kubernetes.io/ingress.class: "alb"
29
-
30
- networkPolicy:
31
- enabled: true
32
- allowedBlocks:
33
- - 10.0.0.0/16
34
-
35
-
36
- ingressInternal:
37
- enabled: false
38
-
39
- envVars:
40
- NEXTAUTH_URL: https://deepsite.hf.co/api/auth
41
-
42
- infisical:
43
- enabled: true
44
- env: "prod-us-east-1"
45
-
46
- autoscaling:
47
- enabled: true
48
- minReplicas: 1
49
- maxReplicas: 10
50
- targetMemoryUtilizationPercentage: "50"
51
- targetCPUUtilizationPercentage: "50"
52
-
53
- resources:
54
- requests:
55
- cpu: 2
56
- memory: 4Gi
57
- limits:
58
- cpu: 4
59
- memory: 8Gi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/_helpers.tpl DELETED
@@ -1,22 +0,0 @@
1
- {{- define "name" -}}
2
- {{- default $.Release.Name | trunc 63 | trimSuffix "-" -}}
3
- {{- end -}}
4
-
5
- {{- define "app.name" -}}
6
- chat-ui
7
- {{- end -}}
8
-
9
- {{- define "labels.standard" -}}
10
- release: {{ $.Release.Name | quote }}
11
- heritage: {{ $.Release.Service | quote }}
12
- chart: "{{ include "name" . }}"
13
- app: "{{ include "app.name" . }}"
14
- {{- end -}}
15
-
16
- {{- define "labels.resolver" -}}
17
- release: {{ $.Release.Name | quote }}
18
- heritage: {{ $.Release.Service | quote }}
19
- chart: "{{ include "name" . }}"
20
- app: "{{ include "app.name" . }}-resolver"
21
- {{- end -}}
22
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/config.yaml DELETED
@@ -1,10 +0,0 @@
1
- apiVersion: v1
2
- kind: ConfigMap
3
- metadata:
4
- labels: {{ include "labels.standard" . | nindent 4 }}
5
- name: {{ include "name" . }}
6
- namespace: {{ .Release.Namespace }}
7
- data:
8
- {{- range $key, $value := $.Values.envVars }}
9
- {{ $key }}: {{ $value | quote }}
10
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
chart/templates/deployment.yaml DELETED
@@ -1,81 +0,0 @@
1
- apiVersion: apps/v1
2
- kind: Deployment
3
- metadata:
4
- labels: {{ include "labels.standard" . | nindent 4 }}
5
- name: {{ include "name" . }}
6
- namespace: {{ .Release.Namespace }}
7
- {{- if .Values.infisical.enabled }}
8
- annotations:
9
- secrets.infisical.com/auto-reload: "true"
10
- {{- end }}
11
- spec:
12
- progressDeadlineSeconds: 600
13
- {{- if not $.Values.autoscaling.enabled }}
14
- replicas: {{ .Values.replicas }}
15
- {{- end }}
16
- revisionHistoryLimit: 10
17
- selector:
18
- matchLabels: {{ include "labels.standard" . | nindent 6 }}
19
- strategy:
20
- rollingUpdate:
21
- maxSurge: 25%
22
- maxUnavailable: 25%
23
- type: RollingUpdate
24
- template:
25
- metadata:
26
- labels: {{ include "labels.standard" . | nindent 8 }}
27
- annotations:
28
- checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
29
- {{- if $.Values.envVars.NODE_LOG_STRUCTURED_DATA }}
30
- co.elastic.logs/json.expand_keys: "true"
31
- {{- end }}
32
- spec:
33
- {{- if .Values.serviceAccount.enabled }}
34
- serviceAccountName: "{{ .Values.serviceAccount.name | default (include "name" .) }}"
35
- {{- end }}
36
- containers:
37
- - name: chat-ui
38
- image: "{{ .Values.image.repository }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
39
- imagePullPolicy: {{ .Values.image.pullPolicy }}
40
- readinessProbe:
41
- failureThreshold: 30
42
- periodSeconds: 10
43
- httpGet:
44
- path: {{ $.Values.envVars.APP_BASE | default "" }}/api/healthcheck
45
- port: {{ $.Values.envVars.APP_PORT | default 3001 | int }}
46
- livenessProbe:
47
- failureThreshold: 30
48
- periodSeconds: 10
49
- httpGet:
50
- path: {{ $.Values.envVars.APP_BASE | default "" }}/api/healthcheck
51
- port: {{ $.Values.envVars.APP_PORT | default 3001 | int }}
52
- ports:
53
- - containerPort: {{ $.Values.envVars.APP_PORT | default 3001 | int }}
54
- name: http
55
- protocol: TCP
56
- {{- if eq "true" $.Values.envVars.METRICS_ENABLED }}
57
- - containerPort: {{ $.Values.envVars.METRICS_PORT | default 5565 | int }}
58
- name: metrics
59
- protocol: TCP
60
- {{- end }}
61
- resources: {{ toYaml .Values.resources | nindent 12 }}
62
- {{- with $.Values.extraEnv }}
63
- env:
64
- {{- toYaml . | nindent 14 }}
65
- {{- end }}
66
- envFrom:
67
- - configMapRef:
68
- name: {{ include "name" . }}
69
- {{- if $.Values.infisical.enabled }}
70
- - secretRef:
71
- name: {{ include "name" $ }}-secs
72
- {{- end }}
73
- {{- with $.Values.extraEnvFrom }}
74
- {{- toYaml . | nindent 14 }}
75
- {{- end }}
76
- nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }}
77
- tolerations: {{ toYaml .Values.tolerations | nindent 8 }}
78
- volumes:
79
- - name: config
80
- configMap:
81
- name: {{ include "name" . }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/hpa.yaml DELETED
@@ -1,45 +0,0 @@
1
- {{- if $.Values.autoscaling.enabled }}
2
- apiVersion: autoscaling/v2
3
- kind: HorizontalPodAutoscaler
4
- metadata:
5
- labels: {{ include "labels.standard" . | nindent 4 }}
6
- name: {{ include "name" . }}
7
- namespace: {{ .Release.Namespace }}
8
- spec:
9
- scaleTargetRef:
10
- apiVersion: apps/v1
11
- kind: Deployment
12
- name: {{ include "name" . }}
13
- minReplicas: {{ $.Values.autoscaling.minReplicas }}
14
- maxReplicas: {{ $.Values.autoscaling.maxReplicas }}
15
- metrics:
16
- {{- if ne "" $.Values.autoscaling.targetMemoryUtilizationPercentage }}
17
- - type: Resource
18
- resource:
19
- name: memory
20
- target:
21
- type: Utilization
22
- averageUtilization: {{ $.Values.autoscaling.targetMemoryUtilizationPercentage | int }}
23
- {{- end }}
24
- {{- if ne "" $.Values.autoscaling.targetCPUUtilizationPercentage }}
25
- - type: Resource
26
- resource:
27
- name: cpu
28
- target:
29
- type: Utilization
30
- averageUtilization: {{ $.Values.autoscaling.targetCPUUtilizationPercentage | int }}
31
- {{- end }}
32
- behavior:
33
- scaleDown:
34
- stabilizationWindowSeconds: 600
35
- policies:
36
- - type: Percent
37
- value: 10
38
- periodSeconds: 60
39
- scaleUp:
40
- stabilizationWindowSeconds: 0
41
- policies:
42
- - type: Pods
43
- value: 1
44
- periodSeconds: 30
45
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/infisical.yaml DELETED
@@ -1,24 +0,0 @@
1
- {{- if .Values.infisical.enabled }}
2
- apiVersion: secrets.infisical.com/v1alpha1
3
- kind: InfisicalSecret
4
- metadata:
5
- name: {{ include "name" $ }}-infisical-secret
6
- namespace: {{ $.Release.Namespace }}
7
- spec:
8
- authentication:
9
- universalAuth:
10
- credentialsRef:
11
- secretName: {{ .Values.infisical.operatorSecretName | quote }}
12
- secretNamespace: {{ .Values.infisical.operatorSecretNamespace | quote }}
13
- secretsScope:
14
- envSlug: {{ .Values.infisical.env | quote }}
15
- projectSlug: {{ .Values.infisical.project | quote }}
16
- secretsPath: /
17
- hostAPI: {{ .Values.infisical.url | quote }}
18
- managedSecretReference:
19
- creationPolicy: Owner
20
- secretName: {{ include "name" $ }}-secs
21
- secretNamespace: {{ .Release.Namespace | quote }}
22
- secretType: Opaque
23
- resyncInterval: {{ .Values.infisical.resyncInterval }}
24
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/ingress-internal.yaml DELETED
@@ -1,32 +0,0 @@
1
- {{- if $.Values.ingressInternal.enabled }}
2
- apiVersion: networking.k8s.io/v1
3
- kind: Ingress
4
- metadata:
5
- annotations: {{ toYaml .Values.ingressInternal.annotations | nindent 4 }}
6
- labels: {{ include "labels.standard" . | nindent 4 }}
7
- name: {{ include "name" . }}-internal
8
- namespace: {{ .Release.Namespace }}
9
- spec:
10
- {{ if $.Values.ingressInternal.className }}
11
- ingressClassName: {{ .Values.ingressInternal.className }}
12
- {{ end }}
13
- {{- with .Values.ingressInternal.tls }}
14
- tls:
15
- - hosts:
16
- - {{ $.Values.domain | quote }}
17
- {{- with .secretName }}
18
- secretName: {{ . }}
19
- {{- end }}
20
- {{- end }}
21
- rules:
22
- - host: {{ .Values.domain }}
23
- http:
24
- paths:
25
- - backend:
26
- service:
27
- name: {{ include "name" . }}
28
- port:
29
- name: http
30
- path: {{ $.Values.ingressInternal.path | default "/" }}
31
- pathType: Prefix
32
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/ingress.yaml DELETED
@@ -1,33 +0,0 @@
1
- {{- if $.Values.ingress.enabled }}
2
- apiVersion: networking.k8s.io/v1
3
- kind: Ingress
4
- metadata:
5
- annotations: {{ toYaml .Values.ingress.annotations | nindent 4 }}
6
- labels: {{ include "labels.standard" . | nindent 4 }}
7
- name: {{ include "name" . }}
8
- namespace: {{ .Release.Namespace }}
9
- spec:
10
- {{ if $.Values.ingress.className }}
11
- ingressClassName: {{ .Values.ingress.className }}
12
- {{ end }}
13
- {{- with .Values.ingress.tls }}
14
- tls:
15
- - hosts:
16
- - {{ $.Values.domain | quote }}
17
- {{- with .secretName }}
18
- secretName: {{ . }}
19
- {{- end }}
20
- {{- end }}
21
- rules:
22
- - host: {{ .Values.domain }}
23
- http:
24
- paths:
25
- - backend:
26
- service:
27
- name: {{ include "name" . }}
28
- port:
29
- name: http
30
- path: {{ $.Values.ingress.path | default "/" }}
31
- pathType: Prefix
32
-
33
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/network-policy.yaml DELETED
@@ -1,36 +0,0 @@
1
- {{- if $.Values.networkPolicy.enabled }}
2
- apiVersion: networking.k8s.io/v1
3
- kind: NetworkPolicy
4
- metadata:
5
- name: {{ include "name" . }}
6
- namespace: {{ .Release.Namespace }}
7
- spec:
8
- egress:
9
- - ports:
10
- - port: 53
11
- protocol: UDP
12
- to:
13
- - namespaceSelector:
14
- matchLabels:
15
- kubernetes.io/metadata.name: kube-system
16
- podSelector:
17
- matchLabels:
18
- k8s-app: kube-dns
19
- - to:
20
- {{- range $ip := .Values.networkPolicy.allowedBlocks }}
21
- - ipBlock:
22
- cidr: {{ $ip | quote }}
23
- {{- end }}
24
- - to:
25
- - ipBlock:
26
- cidr: 0.0.0.0/0
27
- except:
28
- - 10.0.0.0/8
29
- - 172.16.0.0/12
30
- - 192.168.0.0/16
31
- - 169.254.169.254/32
32
- podSelector:
33
- matchLabels: {{ include "labels.standard" . | nindent 6 }}
34
- policyTypes:
35
- - Egress
36
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/service-account.yaml DELETED
@@ -1,13 +0,0 @@
1
- {{- if and .Values.serviceAccount.enabled .Values.serviceAccount.create }}
2
- apiVersion: v1
3
- kind: ServiceAccount
4
- automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
5
- metadata:
6
- name: "{{ .Values.serviceAccount.name | default (include "name" .) }}"
7
- namespace: {{ .Release.Namespace }}
8
- labels: {{ include "labels.standard" . | nindent 4 }}
9
- {{- with .Values.serviceAccount.annotations }}
10
- annotations:
11
- {{- toYaml . | nindent 4 }}
12
- {{- end }}
13
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/service-monitor.yaml DELETED
@@ -1,17 +0,0 @@
1
- {{- if eq "true" $.Values.envVars.METRICS_ENABLED }}
2
- apiVersion: monitoring.coreos.com/v1
3
- kind: ServiceMonitor
4
- metadata:
5
- labels: {{ include "labels.standard" . | nindent 4 }}
6
- name: {{ include "name" . }}
7
- namespace: {{ .Release.Namespace }}
8
- spec:
9
- selector:
10
- matchLabels: {{ include "labels.standard" . | nindent 6 }}
11
- endpoints:
12
- - port: metrics
13
- path: /metrics
14
- interval: 10s
15
- scheme: http
16
- scrapeTimeout: 10s
17
- {{- end }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/templates/service.yaml DELETED
@@ -1,21 +0,0 @@
1
- apiVersion: v1
2
- kind: Service
3
- metadata:
4
- name: "{{ include "name" . }}"
5
- annotations: {{ toYaml .Values.service.annotations | nindent 4 }}
6
- namespace: {{ .Release.Namespace }}
7
- labels: {{ include "labels.standard" . | nindent 4 }}
8
- spec:
9
- ports:
10
- - name: http
11
- port: 80
12
- protocol: TCP
13
- targetPort: http
14
- {{- if eq "true" $.Values.envVars.METRICS_ENABLED }}
15
- - name: metrics
16
- port: {{ $.Values.envVars.METRICS_PORT | default 5565 | int }}
17
- protocol: TCP
18
- targetPort: metrics
19
- {{- end }}
20
- selector: {{ include "labels.standard" . | nindent 4 }}
21
- type: {{.Values.service.type}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chart/values.yaml DELETED
@@ -1,81 +0,0 @@
1
- image:
2
- repository: registry.internal.huggingface.tech/deepsite
3
- name: deepsite
4
- tag: 0.0.0-latest
5
- pullPolicy: IfNotPresent
6
-
7
- replicas: 1
8
-
9
- domain: deepsite.hf.co
10
-
11
- networkPolicy:
12
- enabled: true
13
- allowedBlocks: []
14
- # allowedBlocks:
15
- # - 10.0.240.0/24
16
- # - 10.0.241.0/24
17
- # - 10.0.242.0/24
18
- # - 10.0.243.0/24
19
- # - 10.0.244.0/24
20
- # - 10.240.0.0/24
21
- # - 10.16.0.0/16
22
-
23
- service:
24
- type: NodePort
25
- annotations: { }
26
-
27
- serviceAccount:
28
- enabled: false
29
- create: false
30
- name: ""
31
- automountServiceAccountToken: true
32
- annotations: { }
33
-
34
- ingress:
35
- enabled: true
36
- path: "/"
37
- annotations: { }
38
- # className: "nginx"
39
- tls: { }
40
- # secretName: XXX
41
-
42
- ingressInternal:
43
- enabled: false
44
- path: "/"
45
- annotations: { }
46
- # className: "nginx"
47
- tls: { }
48
-
49
- resources:
50
- requests:
51
- cpu: 2
52
- memory: 4Gi
53
- limits:
54
- cpu: 2
55
- memory: 4Gi
56
- nodeSelector: {}
57
- tolerations: []
58
-
59
- envVars: { }
60
-
61
- infisical:
62
- enabled: false
63
- env: ""
64
- project: "deepsite-f-hvj"
65
- url: ""
66
- resyncInterval: 60
67
- operatorSecretName: "deepsite-operator-secrets"
68
- operatorSecretNamespace: "hub-utils"
69
-
70
- # Allow to environment injections on top or instead of infisical
71
- extraEnvFrom: []
72
- extraEnv: []
73
-
74
- autoscaling:
75
- enabled: false
76
- minReplicas: 1
77
- maxReplicas: 2
78
- targetMemoryUtilizationPercentage: ""
79
- targetCPUUtilizationPercentage: ""
80
-
81
- ## Metrics removed; monitoring configuration no longer used
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
components.json CHANGED
@@ -6,11 +6,10 @@
6
  "tailwind": {
7
  "config": "",
8
  "css": "app/globals.css",
9
- "baseColor": "zinc",
10
  "cssVariables": true,
11
  "prefix": ""
12
  },
13
- "iconLibrary": "lucide",
14
  "aliases": {
15
  "components": "@/components",
16
  "utils": "@/lib/utils",
@@ -18,5 +17,5 @@
18
  "lib": "@/lib",
19
  "hooks": "@/hooks"
20
  },
21
- "registries": {}
22
- }
 
6
  "tailwind": {
7
  "config": "",
8
  "css": "app/globals.css",
9
+ "baseColor": "neutral",
10
  "cssVariables": true,
11
  "prefix": ""
12
  },
 
13
  "aliases": {
14
  "components": "@/components",
15
  "utils": "@/lib/utils",
 
17
  "lib": "@/lib",
18
  "hooks": "@/hooks"
19
  },
20
+ "iconLibrary": "lucide"
21
+ }
components/ask-ai/ask-ai-landing.tsx DELETED
@@ -1,75 +0,0 @@
1
- "use client";
2
- import { ArrowUp } from "lucide-react";
3
- import { useState } from "react";
4
- import { useLocalStorage, useMount } from "react-use";
5
- import { useRouter } from "next/navigation";
6
-
7
- import { Button } from "@/components/ui/button";
8
- import { ProviderType } from "@/lib/type";
9
- import { Models } from "./models";
10
- import { DEFAULT_MODEL } from "@/lib/providers";
11
- import { cn } from "@/lib/utils";
12
-
13
- export function AskAiLanding({ className }: { className?: string }) {
14
- const [model = DEFAULT_MODEL, setModel] = useLocalStorage<string>(
15
- "deepsite-model",
16
- DEFAULT_MODEL
17
- );
18
- const [provider, setProvider] = useLocalStorage<ProviderType>(
19
- "deepsite-provider",
20
- "auto" as ProviderType
21
- );
22
- const router = useRouter();
23
- const [prompt, setPrompt] = useState<string>("");
24
- const [mounted, setMounted] = useState<boolean>(false);
25
-
26
- useMount(() => {
27
- setMounted(true);
28
- });
29
-
30
- return (
31
- <div
32
- className={cn(
33
- "dark:bg-[#222222] bg-accent border border-border-muted rounded-xl p-3 block relative",
34
- className
35
- )}
36
- >
37
- <textarea
38
- id="prompt-input"
39
- className="w-full h-full resize-none outline-none text-primary text-sm"
40
- placeholder="Ask me anything..."
41
- value={prompt}
42
- onChange={(e) => setPrompt(e.target.value)}
43
- onKeyDown={(e) => {
44
- if (e.key === "Enter" && !e.shiftKey) {
45
- e.preventDefault();
46
- router.push(`/new?prompt=${prompt}`);
47
- }
48
- }}
49
- />
50
- <footer className="flex items-center justify-between">
51
- <div className="flex items-center gap-2">
52
- {mounted && (
53
- <Models
54
- model={model}
55
- setModel={setModel}
56
- provider={provider as ProviderType}
57
- setProvider={setProvider}
58
- />
59
- )}
60
- </div>
61
- <div>
62
- <Button
63
- size="icon-sm"
64
- className="rounded-full!"
65
- onClick={() => {
66
- router.push(`/new?prompt=${prompt}`);
67
- }}
68
- >
69
- <ArrowUp />
70
- </Button>
71
- </div>
72
- </footer>
73
- </div>
74
- );
75
- }