Spaces:
Sleeping
Sleeping
Deploy Perplexica to Hugging Face with nginx basic auth
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .assets/demo.gif +3 -0
- .assets/manifest.json +0 -0
- .assets/perplexica-screenshot.png +3 -0
- .assets/sponsers/exa.png +0 -0
- .assets/sponsers/warp.png +3 -0
- .dockerignore +1 -0
- .eslintrc.json +3 -0
- .gitattributes +7 -0
- .github/ISSUE_TEMPLATE/bug_report.md +27 -0
- .github/ISSUE_TEMPLATE/custom.md +7 -0
- .github/ISSUE_TEMPLATE/feature_request.md +19 -0
- .github/workflows/docker-build.yaml +217 -0
- .gitignore +41 -0
- .prettierignore +41 -0
- .prettierrc.js +11 -0
- CONTRIBUTING.md +82 -0
- Dockerfile +78 -0
- Dockerfile.slim +35 -0
- LICENSE +21 -0
- README.md +271 -5
- data/.gitignore +2 -0
- docker-compose.yaml +14 -0
- docs/API/SEARCH.md +190 -0
- docs/architecture/README.md +38 -0
- docs/architecture/WORKING.md +72 -0
- docs/installation/UPDATING.md +81 -0
- drizzle.config.ts +11 -0
- drizzle/0000_fuzzy_randall.sql +16 -0
- drizzle/0001_wise_rockslide.sql +1 -0
- drizzle/0002_daffy_wrecker.sql +1 -0
- drizzle/meta/0000_snapshot.json +116 -0
- drizzle/meta/0001_snapshot.json +125 -0
- drizzle/meta/0002_snapshot.json +132 -0
- drizzle/meta/_journal.json +27 -0
- entrypoint-hf.sh +59 -0
- entrypoint.sh +32 -0
- hf.nginx.conf +30 -0
- next-env.d.ts +6 -0
- next.config.mjs +26 -0
- package.json +76 -0
- postcss.config.js +6 -0
- public/fonts/pp-ed-ul.otf +0 -0
- public/icon-100.png +0 -0
- public/icon-50.png +0 -0
- public/icon.png +0 -0
- public/next.svg +1 -0
- public/screenshots/p1.png +3 -0
- public/screenshots/p1_small.png +3 -0
- public/screenshots/p2.png +3 -0
- public/screenshots/p2_small.png +3 -0
.assets/demo.gif
ADDED
|
Git LFS Details
|
.assets/manifest.json
ADDED
|
File without changes
|
.assets/perplexica-screenshot.png
ADDED
|
Git LFS Details
|
.assets/sponsers/exa.png
ADDED
|
.assets/sponsers/warp.png
ADDED
|
Git LFS Details
|
.dockerignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
**/node_modules
|
.eslintrc.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"extends": "next/core-web-vitals"
|
| 3 |
+
}
|
.gitattributes
CHANGED
|
@@ -33,3 +33,10 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
.assets/demo.gif filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
.assets/perplexica-screenshot.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
.assets/sponsers/warp.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
public/screenshots/p1.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
public/screenshots/p1_small.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
public/screenshots/p2.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
public/screenshots/p2_small.png filter=lfs diff=lfs merge=lfs -text
|
.github/ISSUE_TEMPLATE/bug_report.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Bug report
|
| 3 |
+
about: Create an issue to help us fix bugs
|
| 4 |
+
title: ''
|
| 5 |
+
labels: bug
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
**Describe the bug**
|
| 10 |
+
A clear and concise description of what the bug is.
|
| 11 |
+
|
| 12 |
+
**To Reproduce**
|
| 13 |
+
Steps to reproduce the behavior:
|
| 14 |
+
|
| 15 |
+
1. Go to '...'
|
| 16 |
+
2. Click on '....'
|
| 17 |
+
3. Scroll down to '....'
|
| 18 |
+
4. See error
|
| 19 |
+
|
| 20 |
+
**Expected behavior**
|
| 21 |
+
A clear and concise description of what you expected to happen.
|
| 22 |
+
|
| 23 |
+
**Screenshots**
|
| 24 |
+
If applicable, add screenshots to help explain your problem.
|
| 25 |
+
|
| 26 |
+
**Additional context**
|
| 27 |
+
Add any other context about the problem here.
|
.github/ISSUE_TEMPLATE/custom.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Custom issue template
|
| 3 |
+
about: Describe this issue template's purpose here.
|
| 4 |
+
title: ''
|
| 5 |
+
labels: ''
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
.github/ISSUE_TEMPLATE/feature_request.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Feature request
|
| 3 |
+
about: Suggest an idea for this project
|
| 4 |
+
title: ''
|
| 5 |
+
labels: enhancement
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
**Is your feature request related to a problem? Please describe.**
|
| 10 |
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
| 11 |
+
|
| 12 |
+
**Describe the solution you'd like**
|
| 13 |
+
A clear and concise description of what you want to happen.
|
| 14 |
+
|
| 15 |
+
**Describe alternatives you've considered**
|
| 16 |
+
A clear and concise description of any alternative solutions or features you've considered.
|
| 17 |
+
|
| 18 |
+
**Additional context**
|
| 19 |
+
Add any other context or screenshots about the feature request here.
|
.github/workflows/docker-build.yaml
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Build & Push Docker Images
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
push:
|
| 5 |
+
branches:
|
| 6 |
+
- master
|
| 7 |
+
- canary
|
| 8 |
+
release:
|
| 9 |
+
types: [published]
|
| 10 |
+
|
| 11 |
+
jobs:
|
| 12 |
+
build-amd64:
|
| 13 |
+
runs-on: ubuntu-latest
|
| 14 |
+
strategy:
|
| 15 |
+
matrix:
|
| 16 |
+
variant:
|
| 17 |
+
- name: full
|
| 18 |
+
dockerfile: Dockerfile
|
| 19 |
+
- name: slim
|
| 20 |
+
dockerfile: Dockerfile.slim
|
| 21 |
+
steps:
|
| 22 |
+
- name: Checkout code
|
| 23 |
+
uses: actions/checkout@v3
|
| 24 |
+
|
| 25 |
+
- name: Set up Docker Buildx
|
| 26 |
+
uses: docker/setup-buildx-action@v2
|
| 27 |
+
with:
|
| 28 |
+
install: true
|
| 29 |
+
|
| 30 |
+
- name: Log in to DockerHub
|
| 31 |
+
uses: docker/login-action@v2
|
| 32 |
+
with:
|
| 33 |
+
username: ${{ secrets.DOCKER_USERNAME }}
|
| 34 |
+
password: ${{ secrets.DOCKER_PASSWORD }}
|
| 35 |
+
|
| 36 |
+
- name: Extract version from release tag
|
| 37 |
+
if: github.event_name == 'release'
|
| 38 |
+
id: version
|
| 39 |
+
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
| 40 |
+
|
| 41 |
+
- name: Build and push AMD64 Docker image (master)
|
| 42 |
+
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
| 43 |
+
run: |
|
| 44 |
+
DOCKERFILE=${{ matrix.variant.dockerfile }}
|
| 45 |
+
VARIANT=${{ matrix.variant.name }}
|
| 46 |
+
docker buildx build --platform linux/amd64 \
|
| 47 |
+
--cache-from=type=registry,ref=itzcrazykns1337/perplexica:${VARIANT}-amd64 \
|
| 48 |
+
--cache-to=type=inline \
|
| 49 |
+
--provenance false \
|
| 50 |
+
-f $DOCKERFILE \
|
| 51 |
+
-t itzcrazykns1337/perplexica:${VARIANT}-amd64 \
|
| 52 |
+
--push .
|
| 53 |
+
|
| 54 |
+
- name: Build and push AMD64 Canary Docker image
|
| 55 |
+
if: github.ref == 'refs/heads/canary' && github.event_name == 'push'
|
| 56 |
+
run: |
|
| 57 |
+
DOCKERFILE=${{ matrix.variant.dockerfile }}
|
| 58 |
+
VARIANT=${{ matrix.variant.name }}
|
| 59 |
+
docker buildx build --platform linux/amd64 \
|
| 60 |
+
--cache-from=type=registry,ref=itzcrazykns1337/perplexica:${VARIANT}-canary-amd64 \
|
| 61 |
+
--cache-to=type=inline \
|
| 62 |
+
--provenance false \
|
| 63 |
+
-f $DOCKERFILE \
|
| 64 |
+
-t itzcrazykns1337/perplexica:${VARIANT}-canary-amd64 \
|
| 65 |
+
--push .
|
| 66 |
+
|
| 67 |
+
- name: Build and push AMD64 release Docker image
|
| 68 |
+
if: github.event_name == 'release'
|
| 69 |
+
run: |
|
| 70 |
+
DOCKERFILE=${{ matrix.variant.dockerfile }}
|
| 71 |
+
VARIANT=${{ matrix.variant.name }}
|
| 72 |
+
docker buildx build --platform linux/amd64 \
|
| 73 |
+
--cache-from=type=registry,ref=itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-amd64 \
|
| 74 |
+
--cache-to=type=inline \
|
| 75 |
+
--provenance false \
|
| 76 |
+
-f $DOCKERFILE \
|
| 77 |
+
-t itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-amd64 \
|
| 78 |
+
--push .
|
| 79 |
+
|
| 80 |
+
build-arm64:
|
| 81 |
+
runs-on: ubuntu-24.04-arm
|
| 82 |
+
strategy:
|
| 83 |
+
matrix:
|
| 84 |
+
variant:
|
| 85 |
+
- name: full
|
| 86 |
+
dockerfile: Dockerfile
|
| 87 |
+
- name: slim
|
| 88 |
+
dockerfile: Dockerfile.slim
|
| 89 |
+
steps:
|
| 90 |
+
- name: Checkout code
|
| 91 |
+
uses: actions/checkout@v3
|
| 92 |
+
|
| 93 |
+
- name: Set up Docker Buildx
|
| 94 |
+
uses: docker/setup-buildx-action@v2
|
| 95 |
+
with:
|
| 96 |
+
install: true
|
| 97 |
+
|
| 98 |
+
- name: Log in to DockerHub
|
| 99 |
+
uses: docker/login-action@v2
|
| 100 |
+
with:
|
| 101 |
+
username: ${{ secrets.DOCKER_USERNAME }}
|
| 102 |
+
password: ${{ secrets.DOCKER_PASSWORD }}
|
| 103 |
+
|
| 104 |
+
- name: Extract version from release tag
|
| 105 |
+
if: github.event_name == 'release'
|
| 106 |
+
id: version
|
| 107 |
+
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
| 108 |
+
|
| 109 |
+
- name: Build and push ARM64 Docker image (master)
|
| 110 |
+
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
| 111 |
+
run: |
|
| 112 |
+
DOCKERFILE=${{ matrix.variant.dockerfile }}
|
| 113 |
+
VARIANT=${{ matrix.variant.name }}
|
| 114 |
+
docker buildx build --platform linux/arm64 \
|
| 115 |
+
--cache-from=type=registry,ref=itzcrazykns1337/perplexica:${VARIANT}-arm64 \
|
| 116 |
+
--cache-to=type=inline \
|
| 117 |
+
--provenance false \
|
| 118 |
+
-f $DOCKERFILE \
|
| 119 |
+
-t itzcrazykns1337/perplexica:${VARIANT}-arm64 \
|
| 120 |
+
--push .
|
| 121 |
+
|
| 122 |
+
- name: Build and push ARM64 Canary Docker image
|
| 123 |
+
if: github.ref == 'refs/heads/canary' && github.event_name == 'push'
|
| 124 |
+
run: |
|
| 125 |
+
DOCKERFILE=${{ matrix.variant.dockerfile }}
|
| 126 |
+
VARIANT=${{ matrix.variant.name }}
|
| 127 |
+
docker buildx build --platform linux/arm64 \
|
| 128 |
+
--cache-from=type=registry,ref=itzcrazykns1337/perplexica:${VARIANT}-canary-arm64 \
|
| 129 |
+
--cache-to=type=inline \
|
| 130 |
+
--provenance false \
|
| 131 |
+
-f $DOCKERFILE \
|
| 132 |
+
-t itzcrazykns1337/perplexica:${VARIANT}-canary-arm64 \
|
| 133 |
+
--push .
|
| 134 |
+
|
| 135 |
+
- name: Build and push ARM64 release Docker image
|
| 136 |
+
if: github.event_name == 'release'
|
| 137 |
+
run: |
|
| 138 |
+
DOCKERFILE=${{ matrix.variant.dockerfile }}
|
| 139 |
+
VARIANT=${{ matrix.variant.name }}
|
| 140 |
+
docker buildx build --platform linux/arm64 \
|
| 141 |
+
--cache-from=type=registry,ref=itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-arm64 \
|
| 142 |
+
--cache-to=type=inline \
|
| 143 |
+
--provenance false \
|
| 144 |
+
-f $DOCKERFILE \
|
| 145 |
+
-t itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-arm64 \
|
| 146 |
+
--push .
|
| 147 |
+
|
| 148 |
+
manifest:
|
| 149 |
+
needs: [build-amd64, build-arm64]
|
| 150 |
+
runs-on: ubuntu-latest
|
| 151 |
+
strategy:
|
| 152 |
+
matrix:
|
| 153 |
+
variant: [full, slim]
|
| 154 |
+
steps:
|
| 155 |
+
- name: Log in to DockerHub
|
| 156 |
+
uses: docker/login-action@v2
|
| 157 |
+
with:
|
| 158 |
+
username: ${{ secrets.DOCKER_USERNAME }}
|
| 159 |
+
password: ${{ secrets.DOCKER_PASSWORD }}
|
| 160 |
+
|
| 161 |
+
- name: Extract version from release tag
|
| 162 |
+
if: github.event_name == 'release'
|
| 163 |
+
id: version
|
| 164 |
+
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
| 165 |
+
|
| 166 |
+
- name: Create and push manifest for main
|
| 167 |
+
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
| 168 |
+
run: |
|
| 169 |
+
VARIANT=${{ matrix.variant }}
|
| 170 |
+
docker manifest create itzcrazykns1337/perplexica:${VARIANT}-latest \
|
| 171 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-amd64 \
|
| 172 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-arm64
|
| 173 |
+
docker manifest push itzcrazykns1337/perplexica:${VARIANT}-latest
|
| 174 |
+
|
| 175 |
+
if [ "$VARIANT" = "full" ]; then
|
| 176 |
+
docker manifest create itzcrazykns1337/perplexica:latest \
|
| 177 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-amd64 \
|
| 178 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-arm64
|
| 179 |
+
docker manifest push itzcrazykns1337/perplexica:latest
|
| 180 |
+
|
| 181 |
+
docker manifest create itzcrazykns1337/perplexica:main \
|
| 182 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-amd64 \
|
| 183 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-arm64
|
| 184 |
+
docker manifest push itzcrazykns1337/perplexica:main
|
| 185 |
+
fi
|
| 186 |
+
|
| 187 |
+
- name: Create and push manifest for canary
|
| 188 |
+
if: github.ref == 'refs/heads/canary' && github.event_name == 'push'
|
| 189 |
+
run: |
|
| 190 |
+
VARIANT=${{ matrix.variant }}
|
| 191 |
+
docker manifest create itzcrazykns1337/perplexica:${VARIANT}-canary \
|
| 192 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-canary-amd64 \
|
| 193 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-canary-arm64
|
| 194 |
+
docker manifest push itzcrazykns1337/perplexica:${VARIANT}-canary
|
| 195 |
+
|
| 196 |
+
if [ "$VARIANT" = "full" ]; then
|
| 197 |
+
docker manifest create itzcrazykns1337/perplexica:canary \
|
| 198 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-canary-amd64 \
|
| 199 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-canary-arm64
|
| 200 |
+
docker manifest push itzcrazykns1337/perplexica:canary
|
| 201 |
+
fi
|
| 202 |
+
|
| 203 |
+
- name: Create and push manifest for releases
|
| 204 |
+
if: github.event_name == 'release'
|
| 205 |
+
run: |
|
| 206 |
+
VARIANT=${{ matrix.variant }}
|
| 207 |
+
docker manifest create itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }} \
|
| 208 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-amd64 \
|
| 209 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-arm64
|
| 210 |
+
docker manifest push itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}
|
| 211 |
+
|
| 212 |
+
if [ "$VARIANT" = "full" ]; then
|
| 213 |
+
docker manifest create itzcrazykns1337/perplexica:${{ env.RELEASE_VERSION }} \
|
| 214 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-amd64 \
|
| 215 |
+
--amend itzcrazykns1337/perplexica:${VARIANT}-${{ env.RELEASE_VERSION }}-arm64
|
| 216 |
+
docker manifest push itzcrazykns1337/perplexica:${{ env.RELEASE_VERSION }}
|
| 217 |
+
fi
|
.gitignore
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Node.js
|
| 2 |
+
node_modules/
|
| 3 |
+
npm-debug.log
|
| 4 |
+
yarn-error.log
|
| 5 |
+
|
| 6 |
+
# Build output
|
| 7 |
+
.next/
|
| 8 |
+
out/
|
| 9 |
+
dist/
|
| 10 |
+
|
| 11 |
+
# IDE/Editor specific
|
| 12 |
+
.vscode/
|
| 13 |
+
.idea/
|
| 14 |
+
*.iml
|
| 15 |
+
|
| 16 |
+
# Environment variables
|
| 17 |
+
.env
|
| 18 |
+
.env.local
|
| 19 |
+
.env.development.local
|
| 20 |
+
.env.test.local
|
| 21 |
+
.env.production.local
|
| 22 |
+
|
| 23 |
+
# Config files
|
| 24 |
+
config.toml
|
| 25 |
+
|
| 26 |
+
# Log files
|
| 27 |
+
logs/
|
| 28 |
+
*.log
|
| 29 |
+
|
| 30 |
+
# Testing
|
| 31 |
+
/coverage/
|
| 32 |
+
|
| 33 |
+
# Miscellaneous
|
| 34 |
+
.DS_Store
|
| 35 |
+
Thumbs.db
|
| 36 |
+
|
| 37 |
+
# Db
|
| 38 |
+
db.sqlite
|
| 39 |
+
/searxng
|
| 40 |
+
|
| 41 |
+
certificates
|
.prettierignore
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Ignore all files in the node_modules directory
|
| 2 |
+
node_modules
|
| 3 |
+
|
| 4 |
+
# Ignore all files in the .next directory (Next.js build output)
|
| 5 |
+
.next
|
| 6 |
+
|
| 7 |
+
# Ignore all files in the .out directory (TypeScript build output)
|
| 8 |
+
.out
|
| 9 |
+
|
| 10 |
+
# Ignore all files in the .cache directory (Prettier cache)
|
| 11 |
+
.cache
|
| 12 |
+
|
| 13 |
+
# Ignore all files in the .vscode directory (Visual Studio Code settings)
|
| 14 |
+
.vscode
|
| 15 |
+
|
| 16 |
+
# Ignore all files in the .idea directory (IntelliJ IDEA settings)
|
| 17 |
+
.idea
|
| 18 |
+
|
| 19 |
+
# Ignore all files in the dist directory (build output)
|
| 20 |
+
dist
|
| 21 |
+
|
| 22 |
+
# Ignore all files in the build directory (build output)
|
| 23 |
+
build
|
| 24 |
+
|
| 25 |
+
# Ignore all files in the coverage directory (test coverage reports)
|
| 26 |
+
coverage
|
| 27 |
+
|
| 28 |
+
# Ignore all files with the .log extension
|
| 29 |
+
*.log
|
| 30 |
+
|
| 31 |
+
# Ignore all files with the .tmp extension
|
| 32 |
+
*.tmp
|
| 33 |
+
|
| 34 |
+
# Ignore all files with the .swp extension
|
| 35 |
+
*.swp
|
| 36 |
+
|
| 37 |
+
# Ignore all files with the .DS_Store extension (macOS specific)
|
| 38 |
+
.DS_Store
|
| 39 |
+
|
| 40 |
+
# Ignore all files in uploads directory
|
| 41 |
+
uploads
|
.prettierrc.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** @type {import("prettier").Config} */
|
| 2 |
+
|
| 3 |
+
const config = {
|
| 4 |
+
printWidth: 80,
|
| 5 |
+
trailingComma: 'all',
|
| 6 |
+
endOfLine: 'auto',
|
| 7 |
+
singleQuote: true,
|
| 8 |
+
tabWidth: 2,
|
| 9 |
+
};
|
| 10 |
+
|
| 11 |
+
module.exports = config;
|
CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# How to Contribute to Perplexica
|
| 2 |
+
|
| 3 |
+
Thanks for your interest in contributing to Perplexica! Your help makes this project better. This guide explains how to contribute effectively.
|
| 4 |
+
|
| 5 |
+
Perplexica is a modern AI chat application with advanced search capabilities.
|
| 6 |
+
|
| 7 |
+
## Project Structure
|
| 8 |
+
|
| 9 |
+
Perplexica's codebase is organized as follows:
|
| 10 |
+
|
| 11 |
+
- **UI Components and Pages**:
|
| 12 |
+
- **Components (`src/components`)**: Reusable UI components.
|
| 13 |
+
- **Pages and Routes (`src/app`)**: Next.js app directory structure with page components.
|
| 14 |
+
- Main app routes include: home (`/`), chat (`/c`), discover (`/discover`), and library (`/library`).
|
| 15 |
+
- **API Routes (`src/app/api`)**: Server endpoints implemented with Next.js route handlers.
|
| 16 |
+
- **Backend Logic (`src/lib`)**: Contains all the backend functionality including search, database, and API logic.
|
| 17 |
+
- The search system lives in `src/lib/agents/search`.
|
| 18 |
+
- The search pipeline is split into classification, research, widgets, and writing.
|
| 19 |
+
- Database functionality is in `src/lib/db`.
|
| 20 |
+
- Chat model and embedding model providers are in `src/lib/models/providers`, and models are loaded via `src/lib/models/registry.ts`.
|
| 21 |
+
- Prompt templates are in `src/lib/prompts`.
|
| 22 |
+
- SearXNG integration is in `src/lib/searxng.ts`.
|
| 23 |
+
- Upload search lives in `src/lib/uploads`.
|
| 24 |
+
|
| 25 |
+
### Where to make changes
|
| 26 |
+
|
| 27 |
+
If you are not sure where to start, use this section as a map.
|
| 28 |
+
|
| 29 |
+
- **Search behavior and reasoning**
|
| 30 |
+
|
| 31 |
+
- `src/lib/agents/search` contains the core chat and search pipeline.
|
| 32 |
+
- `classifier.ts` decides whether research is needed and what should run.
|
| 33 |
+
- `researcher/` gathers information in the background.
|
| 34 |
+
|
| 35 |
+
- **Add or change a search capability**
|
| 36 |
+
|
| 37 |
+
- Research tools (web, academic, discussions, uploads, scraping) live in `src/lib/agents/search/researcher/actions`.
|
| 38 |
+
- Tools are registered in `src/lib/agents/search/researcher/actions/index.ts`.
|
| 39 |
+
|
| 40 |
+
- **Add or change widgets**
|
| 41 |
+
|
| 42 |
+
- Widgets live in `src/lib/agents/search/widgets`.
|
| 43 |
+
- Widgets run in parallel with research and show structured results in the UI.
|
| 44 |
+
|
| 45 |
+
- **Model integrations**
|
| 46 |
+
|
| 47 |
+
- Providers live in `src/lib/models/providers`.
|
| 48 |
+
- Add new providers there and wire them into the model registry so they show up in the app.
|
| 49 |
+
|
| 50 |
+
- **Architecture docs**
|
| 51 |
+
- High level overview: `docs/architecture/README.md`
|
| 52 |
+
- High level flow: `docs/architecture/WORKING.md`
|
| 53 |
+
|
| 54 |
+
## API Documentation
|
| 55 |
+
|
| 56 |
+
Perplexica includes API documentation for programmatic access.
|
| 57 |
+
|
| 58 |
+
- **Search API**: For detailed documentation, see `docs/API/SEARCH.md`.
|
| 59 |
+
|
| 60 |
+
## Setting Up Your Environment
|
| 61 |
+
|
| 62 |
+
Before diving into coding, setting up your local environment is key. Here's what you need to do:
|
| 63 |
+
|
| 64 |
+
1. Run `npm install` to install all dependencies.
|
| 65 |
+
2. Use `npm run dev` to start the application in development mode.
|
| 66 |
+
3. Open http://localhost:3000 and complete the setup in the UI (API keys, models, search backend URL, etc.).
|
| 67 |
+
|
| 68 |
+
Database migrations are applied automatically on startup.
|
| 69 |
+
|
| 70 |
+
For full installation options (Docker and non Docker), see the installation guide in the repository README.
|
| 71 |
+
|
| 72 |
+
**Please note**: Docker configurations are present for setting up production environments, whereas `npm run dev` is used for development purposes.
|
| 73 |
+
|
| 74 |
+
## Coding and Contribution Practices
|
| 75 |
+
|
| 76 |
+
Before committing changes:
|
| 77 |
+
|
| 78 |
+
1. Ensure that your code functions correctly by thorough testing.
|
| 79 |
+
2. Always run `npm run format:write` to format your code according to the project's coding standards. This helps maintain consistency and code quality.
|
| 80 |
+
3. We currently do not have a code of conduct, but it is in the works. In the meantime, please be mindful of how you engage with the project and its community.
|
| 81 |
+
|
| 82 |
+
Following these steps will help maintain the integrity of Perplexica's codebase and facilitate a smoother integration of your valuable contributions. Thank you for your support and commitment to improving Perplexica.
|
Dockerfile
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM node:24.5.0-slim AS builder
|
| 2 |
+
|
| 3 |
+
RUN apt-get update && apt-get install -y python3 python3-pip sqlite3 && rm -rf /var/lib/apt/lists/*
|
| 4 |
+
|
| 5 |
+
WORKDIR /home/perplexica
|
| 6 |
+
|
| 7 |
+
COPY package.json yarn.lock ./
|
| 8 |
+
RUN yarn install --frozen-lockfile --network-timeout 600000
|
| 9 |
+
|
| 10 |
+
COPY tsconfig.json next.config.mjs next-env.d.ts postcss.config.js drizzle.config.ts tailwind.config.ts ./
|
| 11 |
+
COPY src ./src
|
| 12 |
+
COPY public ./public
|
| 13 |
+
COPY drizzle ./drizzle
|
| 14 |
+
|
| 15 |
+
RUN mkdir -p /home/perplexica/data
|
| 16 |
+
RUN yarn build
|
| 17 |
+
|
| 18 |
+
FROM node:24.5.0-slim
|
| 19 |
+
|
| 20 |
+
RUN apt-get update && apt-get install -y \
|
| 21 |
+
python3-dev python3-babel python3-venv python-is-python3 \
|
| 22 |
+
uwsgi uwsgi-plugin-python3 \
|
| 23 |
+
git build-essential libxslt-dev zlib1g-dev libffi-dev libssl-dev \
|
| 24 |
+
curl sudo nginx openssl \
|
| 25 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 26 |
+
|
| 27 |
+
WORKDIR /home/perplexica
|
| 28 |
+
|
| 29 |
+
COPY --from=builder /home/perplexica/public ./public
|
| 30 |
+
COPY --from=builder /home/perplexica/.next/static ./public/_next/static
|
| 31 |
+
COPY --from=builder /home/perplexica/.next/standalone ./
|
| 32 |
+
COPY --from=builder /home/perplexica/data ./data
|
| 33 |
+
COPY drizzle ./drizzle
|
| 34 |
+
|
| 35 |
+
RUN mkdir /home/perplexica/uploads
|
| 36 |
+
|
| 37 |
+
RUN useradd --shell /bin/bash --system \
|
| 38 |
+
--home-dir "/usr/local/searxng" \
|
| 39 |
+
--comment 'Privacy-respecting metasearch engine' \
|
| 40 |
+
searxng
|
| 41 |
+
|
| 42 |
+
RUN mkdir "/usr/local/searxng"
|
| 43 |
+
RUN mkdir -p /etc/searxng
|
| 44 |
+
RUN chown -R "searxng:searxng" "/usr/local/searxng"
|
| 45 |
+
|
| 46 |
+
COPY searxng/settings.yml /etc/searxng/settings.yml
|
| 47 |
+
COPY searxng/limiter.toml /etc/searxng/limiter.toml
|
| 48 |
+
COPY searxng/uwsgi.ini /etc/searxng/uwsgi.ini
|
| 49 |
+
RUN chown -R searxng:searxng /etc/searxng
|
| 50 |
+
|
| 51 |
+
USER searxng
|
| 52 |
+
|
| 53 |
+
RUN git clone "https://github.com/searxng/searxng" \
|
| 54 |
+
"/usr/local/searxng/searxng-src"
|
| 55 |
+
|
| 56 |
+
RUN python3 -m venv "/usr/local/searxng/searx-pyenv"
|
| 57 |
+
RUN "/usr/local/searxng/searx-pyenv/bin/pip" install --upgrade pip setuptools wheel pyyaml msgspec
|
| 58 |
+
RUN cd "/usr/local/searxng/searxng-src" && \
|
| 59 |
+
"/usr/local/searxng/searx-pyenv/bin/pip" install --use-pep517 --no-build-isolation -e .
|
| 60 |
+
|
| 61 |
+
USER root
|
| 62 |
+
|
| 63 |
+
WORKDIR /home/perplexica
|
| 64 |
+
COPY entrypoint.sh ./entrypoint.sh
|
| 65 |
+
COPY entrypoint-hf.sh ./entrypoint-hf.sh
|
| 66 |
+
COPY hf.nginx.conf ./hf.nginx.conf
|
| 67 |
+
RUN chmod +x ./entrypoint.sh
|
| 68 |
+
RUN chmod +x ./entrypoint-hf.sh
|
| 69 |
+
RUN sed -i 's/\r$//' ./entrypoint.sh || true
|
| 70 |
+
RUN sed -i 's/\r$//' ./entrypoint-hf.sh || true
|
| 71 |
+
|
| 72 |
+
RUN echo "searxng ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
| 73 |
+
|
| 74 |
+
EXPOSE 7860 8080
|
| 75 |
+
|
| 76 |
+
ENV SEARXNG_API_URL=http://localhost:8080
|
| 77 |
+
|
| 78 |
+
CMD ["/home/perplexica/entrypoint-hf.sh"]
|
Dockerfile.slim
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM node:24.5.0-slim AS builder
|
| 2 |
+
|
| 3 |
+
RUN apt-get update && apt-get install -y python3 python3-pip sqlite3 && rm -rf /var/lib/apt/lists/*
|
| 4 |
+
|
| 5 |
+
WORKDIR /home/perplexica
|
| 6 |
+
|
| 7 |
+
COPY package.json yarn.lock ./
|
| 8 |
+
RUN yarn install --frozen-lockfile --network-timeout 600000
|
| 9 |
+
|
| 10 |
+
COPY tsconfig.json next.config.mjs next-env.d.ts postcss.config.js drizzle.config.ts tailwind.config.ts ./
|
| 11 |
+
COPY src ./src
|
| 12 |
+
COPY public ./public
|
| 13 |
+
COPY drizzle ./drizzle
|
| 14 |
+
|
| 15 |
+
RUN mkdir -p /home/perplexica/data
|
| 16 |
+
RUN yarn build
|
| 17 |
+
|
| 18 |
+
FROM node:24.5.0-slim
|
| 19 |
+
|
| 20 |
+
RUN apt-get update && apt-get install -y python3 python3-pip sqlite3 && rm -rf /var/lib/apt/lists/*
|
| 21 |
+
|
| 22 |
+
WORKDIR /home/perplexica
|
| 23 |
+
|
| 24 |
+
COPY --from=builder /home/perplexica/public ./public
|
| 25 |
+
COPY --from=builder /home/perplexica/.next/static ./public/_next/static
|
| 26 |
+
|
| 27 |
+
COPY --from=builder /home/perplexica/.next/standalone ./
|
| 28 |
+
COPY --from=builder /home/perplexica/data ./data
|
| 29 |
+
COPY drizzle ./drizzle
|
| 30 |
+
|
| 31 |
+
RUN mkdir /home/perplexica/uploads
|
| 32 |
+
|
| 33 |
+
EXPOSE 3000
|
| 34 |
+
|
| 35 |
+
CMD ["node", "server.js"]
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 ItzCrazyKns
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
CHANGED
|
@@ -1,10 +1,276 @@
|
|
| 1 |
---
|
| 2 |
-
title: Perplexica
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: docker
|
|
|
|
| 7 |
pinned: false
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Perplexica
|
| 3 |
+
emoji: "🔍"
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: indigo
|
| 6 |
sdk: docker
|
| 7 |
+
app_port: 7860
|
| 8 |
pinned: false
|
| 9 |
---
|
| 10 |
|
| 11 |
+
# Perplexica 🔍
|
| 12 |
+
|
| 13 |
+
[](https://github.com/ItzCrazyKns/Perplexica/stargazers)
|
| 14 |
+
[](https://github.com/ItzCrazyKns/Perplexica/network/members)
|
| 15 |
+
[](https://github.com/ItzCrazyKns/Perplexica/watchers)
|
| 16 |
+
[](https://hub.docker.com/r/itzcrazykns1337/perplexica)
|
| 17 |
+
[](https://github.com/ItzCrazyKns/Perplexica/blob/master/LICENSE)
|
| 18 |
+
[](https://github.com/ItzCrazyKns/Perplexica/commits/master)
|
| 19 |
+
[](https://discord.gg/26aArMy8tT)
|
| 20 |
+
|
| 21 |
+
Perplexica is a **privacy-focused AI answering engine** that runs entirely on your own hardware. It combines knowledge from the vast internet with support for **local LLMs** (Ollama) and cloud providers (OpenAI, Claude, Groq), delivering accurate answers with **cited sources** while keeping your searches completely private.
|
| 22 |
+
|
| 23 |
+

|
| 24 |
+
|
| 25 |
+
Want to know more about its architecture and how it works? You can read it [here](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/architecture/README.md).
|
| 26 |
+
|
| 27 |
+
## ✨ Features
|
| 28 |
+
|
| 29 |
+
🤖 **Support for all major AI providers** - Use local LLMs through Ollama or connect to OpenAI, Anthropic Claude, Google Gemini, Groq, and more. Mix and match models based on your needs.
|
| 30 |
+
|
| 31 |
+
⚡ **Smart search modes** - Choose Speed Mode when you need quick answers, Balanced Mode for everyday searches, or Quality Mode for deep research.
|
| 32 |
+
|
| 33 |
+
🧭 **Pick your sources** - Search the web, discussions, or academic papers. More sources and integrations are in progress.
|
| 34 |
+
|
| 35 |
+
🧩 **Widgets** - Helpful UI cards that show up when relevant, like weather, calculations, stock prices, and other quick lookups.
|
| 36 |
+
|
| 37 |
+
🔍 **Web search powered by SearxNG** - Access multiple search engines while keeping your identity private. Support for Tavily and Exa coming soon for even better results.
|
| 38 |
+
|
| 39 |
+
📷 **Image and video search** - Find visual content alongside text results. Search isn't limited to just articles anymore.
|
| 40 |
+
|
| 41 |
+
📄 **File uploads** - Upload documents and ask questions about them. PDFs, text files, images - Perplexica understands them all.
|
| 42 |
+
|
| 43 |
+
🌐 **Search specific domains** - Limit your search to specific websites when you know where to look. Perfect for technical documentation or research papers.
|
| 44 |
+
|
| 45 |
+
💡 **Smart suggestions** - Get intelligent search suggestions as you type, helping you formulate better queries.
|
| 46 |
+
|
| 47 |
+
📚 **Discover** - Browse interesting articles and trending content throughout the day. Stay informed without even searching.
|
| 48 |
+
|
| 49 |
+
🕒 **Search history** - Every search is saved locally so you can revisit your discoveries anytime. Your research is never lost.
|
| 50 |
+
|
| 51 |
+
✨ **More coming soon** - We're actively developing new features based on community feedback. Join our Discord to help shape Perplexica's future!
|
| 52 |
+
|
| 53 |
+
## Sponsors
|
| 54 |
+
|
| 55 |
+
Perplexica's development is powered by the generous support of our sponsors. Their contributions help keep this project free, open-source, and accessible to everyone.
|
| 56 |
+
|
| 57 |
+
<div align="center">
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
<a href="https://www.warp.dev/perplexica">
|
| 61 |
+
<img alt="Warp Terminal" src=".assets/sponsers/warp.png" width="100%">
|
| 62 |
+
</a>
|
| 63 |
+
|
| 64 |
+
### **✨ [Try Warp - The AI-Powered Terminal →](https://www.warp.dev/perplexica)**
|
| 65 |
+
|
| 66 |
+
Warp is revolutionizing development workflows with AI-powered features, modern UX, and blazing-fast performance. Used by developers at top companies worldwide.
|
| 67 |
+
|
| 68 |
+
</div>
|
| 69 |
+
|
| 70 |
+
---
|
| 71 |
+
|
| 72 |
+
We'd also like to thank the following partners for their generous support:
|
| 73 |
+
|
| 74 |
+
<table>
|
| 75 |
+
<tr>
|
| 76 |
+
<td width="100" align="center">
|
| 77 |
+
<a href="https://dashboard.exa.ai" target="_blank">
|
| 78 |
+
<img src=".assets/sponsers/exa.png" alt="Exa" width="80" height="80" style="border-radius: .75rem;" />
|
| 79 |
+
</a>
|
| 80 |
+
</td>
|
| 81 |
+
<td>
|
| 82 |
+
<a href="https://dashboard.exa.ai">Exa</a> • The Perfect Web Search API for LLMs - web search, crawling, deep research, and answer APIs
|
| 83 |
+
</td>
|
| 84 |
+
</tr>
|
| 85 |
+
</table>
|
| 86 |
+
|
| 87 |
+
## Installation
|
| 88 |
+
|
| 89 |
+
There are mainly 2 ways of installing Perplexica - With Docker, Without Docker. Using Docker is highly recommended.
|
| 90 |
+
|
| 91 |
+
### Getting Started with Docker (Recommended)
|
| 92 |
+
|
| 93 |
+
Perplexica can be easily run using Docker. Simply run the following command:
|
| 94 |
+
|
| 95 |
+
```bash
|
| 96 |
+
docker run -d -p 3000:3000 -v perplexica-data:/home/perplexica/data --name perplexica itzcrazykns1337/perplexica:latest
|
| 97 |
+
```
|
| 98 |
+
|
| 99 |
+
This will pull and start the Perplexica container with the bundled SearxNG search engine. Once running, open your browser and navigate to http://localhost:3000. You can then configure your settings (API keys, models, etc.) directly in the setup screen.
|
| 100 |
+
|
| 101 |
+
**Note**: The image includes both Perplexica and SearxNG, so no additional setup is required. The `-v` flags create persistent volumes for your data and uploaded files.
|
| 102 |
+
|
| 103 |
+
#### Using Perplexica with Your Own SearxNG Instance
|
| 104 |
+
|
| 105 |
+
If you already have SearxNG running, you can use the slim version of Perplexica:
|
| 106 |
+
|
| 107 |
+
```bash
|
| 108 |
+
docker run -d -p 3000:3000 -e SEARXNG_API_URL=http://your-searxng-url:8080 -v perplexica-data:/home/perplexica/data --name perplexica itzcrazykns1337/perplexica:slim-latest
|
| 109 |
+
```
|
| 110 |
+
|
| 111 |
+
**Important**: Make sure your SearxNG instance has:
|
| 112 |
+
|
| 113 |
+
- JSON format enabled in the settings
|
| 114 |
+
- Wolfram Alpha search engine enabled
|
| 115 |
+
|
| 116 |
+
Replace `http://your-searxng-url:8080` with your actual SearxNG URL. Then configure your AI provider settings in the setup screen at http://localhost:3000.
|
| 117 |
+
|
| 118 |
+
#### Advanced Setup (Building from Source)
|
| 119 |
+
|
| 120 |
+
If you prefer to build from source or need more control:
|
| 121 |
+
|
| 122 |
+
1. Ensure Docker is installed and running on your system.
|
| 123 |
+
2. Clone the Perplexica repository:
|
| 124 |
+
|
| 125 |
+
```bash
|
| 126 |
+
git clone https://github.com/ItzCrazyKns/Perplexica.git
|
| 127 |
+
```
|
| 128 |
+
|
| 129 |
+
3. After cloning, navigate to the directory containing the project files.
|
| 130 |
+
|
| 131 |
+
4. Build and run using Docker:
|
| 132 |
+
|
| 133 |
+
```bash
|
| 134 |
+
docker build -t perplexica .
|
| 135 |
+
docker run -d -p 3000:3000 -v perplexica-data:/home/perplexica/data --name perplexica perplexica
|
| 136 |
+
```
|
| 137 |
+
|
| 138 |
+
5. Access Perplexica at http://localhost:3000 and configure your settings in the setup screen.
|
| 139 |
+
|
| 140 |
+
**Note**: After the containers are built, you can start Perplexica directly from Docker without having to open a terminal.
|
| 141 |
+
|
| 142 |
+
### Non-Docker Installation
|
| 143 |
+
|
| 144 |
+
1. Install SearXNG and allow `JSON` format in the SearXNG settings. Make sure Wolfram Alpha search engine is also enabled.
|
| 145 |
+
2. Clone the repository:
|
| 146 |
+
|
| 147 |
+
```bash
|
| 148 |
+
git clone https://github.com/ItzCrazyKns/Perplexica.git
|
| 149 |
+
cd Perplexica
|
| 150 |
+
```
|
| 151 |
+
|
| 152 |
+
3. Install dependencies:
|
| 153 |
+
|
| 154 |
+
```bash
|
| 155 |
+
npm i
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
4. Build the application:
|
| 159 |
+
|
| 160 |
+
```bash
|
| 161 |
+
npm run build
|
| 162 |
+
```
|
| 163 |
+
|
| 164 |
+
5. Start the application:
|
| 165 |
+
|
| 166 |
+
```bash
|
| 167 |
+
npm run start
|
| 168 |
+
```
|
| 169 |
+
|
| 170 |
+
6. Open your browser and navigate to http://localhost:3000 to complete the setup and configure your settings (API keys, models, SearxNG URL, etc.) in the setup screen.
|
| 171 |
+
|
| 172 |
+
**Note**: Using Docker is recommended as it simplifies the setup process, especially for managing environment variables and dependencies.
|
| 173 |
+
|
| 174 |
+
See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information like updating, etc.
|
| 175 |
+
|
| 176 |
+
### Troubleshooting
|
| 177 |
+
|
| 178 |
+
#### Local OpenAI-API-Compliant Servers
|
| 179 |
+
|
| 180 |
+
If Perplexica tells you that you haven't configured any chat model providers, ensure that:
|
| 181 |
+
|
| 182 |
+
1. Your server is running on `0.0.0.0` (not `127.0.0.1`) and on the same port you put in the API URL.
|
| 183 |
+
2. You have specified the correct model name loaded by your local LLM server.
|
| 184 |
+
3. You have specified the correct API key, or if one is not defined, you have put _something_ in the API key field and not left it empty.
|
| 185 |
+
|
| 186 |
+
#### Ollama Connection Errors
|
| 187 |
+
|
| 188 |
+
If you're encountering an Ollama connection error, it is likely due to the backend being unable to connect to Ollama's API. To fix this issue you can:
|
| 189 |
+
|
| 190 |
+
1. **Check your Ollama API URL:** Ensure that the API URL is correctly set in the settings menu.
|
| 191 |
+
2. **Update API URL Based on OS:**
|
| 192 |
+
|
| 193 |
+
- **Windows:** Use `http://host.docker.internal:11434`
|
| 194 |
+
- **Mac:** Use `http://host.docker.internal:11434`
|
| 195 |
+
- **Linux:** Use `http://<private_ip_of_host>:11434`
|
| 196 |
+
|
| 197 |
+
Adjust the port number if you're using a different one.
|
| 198 |
+
|
| 199 |
+
3. **Linux Users - Expose Ollama to Network:**
|
| 200 |
+
|
| 201 |
+
- Inside `/etc/systemd/system/ollama.service`, you need to add `Environment="OLLAMA_HOST=0.0.0.0:11434"`. (Change the port number if you are using a different one.) Then reload the systemd manager configuration with `systemctl daemon-reload`, and restart Ollama by `systemctl restart ollama`. For more information see [Ollama docs](https://github.com/ollama/ollama/blob/main/docs/faq.md#setting-environment-variables-on-linux)
|
| 202 |
+
|
| 203 |
+
- Ensure that the port (default is 11434) is not blocked by your firewall.
|
| 204 |
+
|
| 205 |
+
#### Lemonade Connection Errors
|
| 206 |
+
|
| 207 |
+
If you're encountering a Lemonade connection error, it is likely due to the backend being unable to connect to Lemonade's API. To fix this issue you can:
|
| 208 |
+
|
| 209 |
+
1. **Check your Lemonade API URL:** Ensure that the API URL is correctly set in the settings menu.
|
| 210 |
+
2. **Update API URL Based on OS:**
|
| 211 |
+
|
| 212 |
+
- **Windows:** Use `http://host.docker.internal:8000`
|
| 213 |
+
- **Mac:** Use `http://host.docker.internal:8000`
|
| 214 |
+
- **Linux:** Use `http://<private_ip_of_host>:8000`
|
| 215 |
+
|
| 216 |
+
Adjust the port number if you're using a different one.
|
| 217 |
+
|
| 218 |
+
3. **Ensure Lemonade Server is Running:**
|
| 219 |
+
|
| 220 |
+
- Make sure your Lemonade server is running and accessible on the configured port (default is 8000).
|
| 221 |
+
- Verify that Lemonade is configured to accept connections from all interfaces (`0.0.0.0`), not just localhost (`127.0.0.1`).
|
| 222 |
+
- Ensure that the port (default is 8000) is not blocked by your firewall.
|
| 223 |
+
|
| 224 |
+
## Using as a Search Engine
|
| 225 |
+
|
| 226 |
+
If you wish to use Perplexica as an alternative to traditional search engines like Google or Bing, or if you want to add a shortcut for quick access from your browser's search bar, follow these steps:
|
| 227 |
+
|
| 228 |
+
1. Open your browser's settings.
|
| 229 |
+
2. Navigate to the 'Search Engines' section.
|
| 230 |
+
3. Add a new site search with the following URL: `http://localhost:3000/?q=%s`. Replace `localhost` with your IP address or domain name, and `3000` with the port number if Perplexica is not hosted locally.
|
| 231 |
+
4. Click the add button. Now, you can use Perplexica directly from your browser's search bar.
|
| 232 |
+
|
| 233 |
+
## Using Perplexica's API
|
| 234 |
+
|
| 235 |
+
Perplexica also provides an API for developers looking to integrate its powerful search engine into their own applications. You can run searches, use multiple models and get answers to your queries.
|
| 236 |
+
|
| 237 |
+
For more details, check out the full documentation [here](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/API/SEARCH.md).
|
| 238 |
+
|
| 239 |
+
## Expose Perplexica to network
|
| 240 |
+
|
| 241 |
+
Perplexica runs on Next.js and handles all API requests. It works right away on the same network and stays accessible even with port forwarding.
|
| 242 |
+
|
| 243 |
+
## One-Click Deployment
|
| 244 |
+
|
| 245 |
+
[](https://usw.sealos.io/?openapp=system-template%3FtemplateName%3Dperplexica)
|
| 246 |
+
[](https://repocloud.io/details/?app_id=267)
|
| 247 |
+
[](https://template.run.claw.cloud/?referralCode=U11MRQ8U9RM4&openapp=system-fastdeploy%3FtemplateName%3Dperplexica)
|
| 248 |
+
[](https://www.hostinger.com/vps/docker-hosting?compose_url=https://raw.githubusercontent.com/ItzCrazyKns/Perplexica/refs/heads/master/docker-compose.yaml)
|
| 249 |
+
|
| 250 |
+
## Upcoming Features
|
| 251 |
+
|
| 252 |
+
- [ ] Adding more widgets, integrations, search sources
|
| 253 |
+
- [ ] Adding ability to create custom agents (name T.B.D.)
|
| 254 |
+
- [ ] Adding authentication
|
| 255 |
+
|
| 256 |
+
## Support Us
|
| 257 |
+
|
| 258 |
+
If you find Perplexica useful, consider giving us a star on GitHub. This helps more people discover Perplexica and supports the development of new features. Your support is greatly appreciated.
|
| 259 |
+
|
| 260 |
+
### Donations
|
| 261 |
+
|
| 262 |
+
We also accept donations to help sustain our project. If you would like to contribute, you can use the following options to donate. Thank you for your support!
|
| 263 |
+
|
| 264 |
+
| Ethereum |
|
| 265 |
+
| ----------------------------------------------------- |
|
| 266 |
+
| Address: `0xB025a84b2F269570Eb8D4b05DEdaA41D8525B6DD` |
|
| 267 |
+
|
| 268 |
+
## Contribution
|
| 269 |
+
|
| 270 |
+
Perplexica is built on the idea that AI and large language models should be easy for everyone to use. If you find bugs or have ideas, please share them in via GitHub Issues. For more information on contributing to Perplexica you can read the [CONTRIBUTING.md](CONTRIBUTING.md) file to learn more about Perplexica and how you can contribute to it.
|
| 271 |
+
|
| 272 |
+
## Help and Support
|
| 273 |
+
|
| 274 |
+
If you have any questions or feedback, please feel free to reach out to us. You can create an issue on GitHub or join our Discord server. There, you can connect with other users, share your experiences and reviews, and receive more personalized help. [Click here](https://discord.gg/EFwsmQDgAu) to join the Discord server. To discuss matters outside of regular support, feel free to contact me on Discord at `itzcrazykns`.
|
| 275 |
+
|
| 276 |
+
Thank you for exploring Perplexica, the AI-powered search engine designed to enhance your search experience. We are constantly working to improve Perplexica and expand its capabilities. We value your feedback and contributions which help us make Perplexica even better. Don't forget to check back for updates and new features!
|
data/.gitignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*
|
| 2 |
+
!.gitignore
|
docker-compose.yaml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
perplexica:
|
| 3 |
+
image: itzcrazykns1337/perplexica:latest
|
| 4 |
+
build:
|
| 5 |
+
context: .
|
| 6 |
+
ports:
|
| 7 |
+
- '3000:3000'
|
| 8 |
+
volumes:
|
| 9 |
+
- data:/home/perplexica/data
|
| 10 |
+
restart: unless-stopped
|
| 11 |
+
|
| 12 |
+
volumes:
|
| 13 |
+
data:
|
| 14 |
+
name: 'perplexica-data'
|
docs/API/SEARCH.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Perplexica Search API Documentation
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
Perplexica’s Search API makes it easy to use our AI-powered search engine. You can run different types of searches, pick the models you want to use, and get the most recent info. Follow the following headings to learn more about Perplexica's search API.
|
| 6 |
+
|
| 7 |
+
## Endpoints
|
| 8 |
+
|
| 9 |
+
### Get Available Providers and Models
|
| 10 |
+
|
| 11 |
+
Before making search requests, you'll need to get the available providers and their models.
|
| 12 |
+
|
| 13 |
+
#### **GET** `/api/providers`
|
| 14 |
+
|
| 15 |
+
**Full URL**: `http://localhost:3000/api/providers`
|
| 16 |
+
|
| 17 |
+
Returns a list of all active providers with their available chat and embedding models.
|
| 18 |
+
|
| 19 |
+
**Response Example:**
|
| 20 |
+
|
| 21 |
+
```json
|
| 22 |
+
{
|
| 23 |
+
"providers": [
|
| 24 |
+
{
|
| 25 |
+
"id": "550e8400-e29b-41d4-a716-446655440000",
|
| 26 |
+
"name": "OpenAI",
|
| 27 |
+
"chatModels": [
|
| 28 |
+
{
|
| 29 |
+
"name": "GPT 4 Omni Mini",
|
| 30 |
+
"key": "gpt-4o-mini"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"name": "GPT 4 Omni",
|
| 34 |
+
"key": "gpt-4o"
|
| 35 |
+
}
|
| 36 |
+
],
|
| 37 |
+
"embeddingModels": [
|
| 38 |
+
{
|
| 39 |
+
"name": "Text Embedding 3 Large",
|
| 40 |
+
"key": "text-embedding-3-large"
|
| 41 |
+
}
|
| 42 |
+
]
|
| 43 |
+
}
|
| 44 |
+
]
|
| 45 |
+
}
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
Use the `id` field as the `providerId` and the `key` field from the models arrays when making search requests.
|
| 49 |
+
|
| 50 |
+
### Search Query
|
| 51 |
+
|
| 52 |
+
#### **POST** `/api/search`
|
| 53 |
+
|
| 54 |
+
**Full URL**: `http://localhost:3000/api/search`
|
| 55 |
+
|
| 56 |
+
**Note**: Replace `localhost:3000` with your Perplexica instance URL if running on a different host or port
|
| 57 |
+
|
| 58 |
+
### Request
|
| 59 |
+
|
| 60 |
+
The API accepts a JSON object in the request body, where you define the enabled search `sources`, chat models, embedding models, and your query.
|
| 61 |
+
|
| 62 |
+
#### Request Body Structure
|
| 63 |
+
|
| 64 |
+
```json
|
| 65 |
+
{
|
| 66 |
+
"chatModel": {
|
| 67 |
+
"providerId": "550e8400-e29b-41d4-a716-446655440000",
|
| 68 |
+
"key": "gpt-4o-mini"
|
| 69 |
+
},
|
| 70 |
+
"embeddingModel": {
|
| 71 |
+
"providerId": "550e8400-e29b-41d4-a716-446655440000",
|
| 72 |
+
"key": "text-embedding-3-large"
|
| 73 |
+
},
|
| 74 |
+
"optimizationMode": "speed",
|
| 75 |
+
"sources": ["web"],
|
| 76 |
+
"query": "What is Perplexica",
|
| 77 |
+
"history": [
|
| 78 |
+
["human", "Hi, how are you?"],
|
| 79 |
+
["assistant", "I am doing well, how can I help you today?"]
|
| 80 |
+
],
|
| 81 |
+
"systemInstructions": "Focus on providing technical details about Perplexica's architecture.",
|
| 82 |
+
"stream": false
|
| 83 |
+
}
|
| 84 |
+
```
|
| 85 |
+
|
| 86 |
+
**Note**: The `providerId` must be a valid UUID obtained from the `/api/providers` endpoint. The example above uses a sample UUID for demonstration.
|
| 87 |
+
|
| 88 |
+
### Request Parameters
|
| 89 |
+
|
| 90 |
+
- **`chatModel`** (object, required): Defines the chat model to be used for the query. To get available providers and models, send a GET request to `http://localhost:3000/api/providers`.
|
| 91 |
+
|
| 92 |
+
- `providerId` (string): The UUID of the provider. You can get this from the `/api/providers` endpoint response.
|
| 93 |
+
- `key` (string): The model key/identifier (e.g., `gpt-4o-mini`, `llama3.1:latest`). Use the `key` value from the provider's `chatModels` array, not the display name.
|
| 94 |
+
|
| 95 |
+
- **`embeddingModel`** (object, required): Defines the embedding model for similarity-based searching. To get available providers and models, send a GET request to `http://localhost:3000/api/providers`.
|
| 96 |
+
|
| 97 |
+
- `providerId` (string): The UUID of the embedding provider. You can get this from the `/api/providers` endpoint response.
|
| 98 |
+
- `key` (string): The embedding model key (e.g., `text-embedding-3-large`, `nomic-embed-text`). Use the `key` value from the provider's `embeddingModels` array, not the display name.
|
| 99 |
+
|
| 100 |
+
- **`sources`** (array, required): Which search sources to enable. Available values:
|
| 101 |
+
|
| 102 |
+
- `web`, `academic`, `discussions`.
|
| 103 |
+
|
| 104 |
+
- **`optimizationMode`** (string, optional): Specifies the optimization mode to control the balance between performance and quality. Available modes:
|
| 105 |
+
|
| 106 |
+
- `speed`: Prioritize speed and return the fastest answer.
|
| 107 |
+
- `balanced`: Provide a balanced answer with good speed and reasonable quality.
|
| 108 |
+
- `quality`: Prioritize answer quality (may be slower).
|
| 109 |
+
|
| 110 |
+
- **`query`** (string, required): The search query or question.
|
| 111 |
+
|
| 112 |
+
- **`systemInstructions`** (string, optional): Custom instructions provided by the user to guide the AI's response. These instructions are treated as user preferences and have lower priority than the system's core instructions. For example, you can specify a particular writing style, format, or focus area.
|
| 113 |
+
|
| 114 |
+
- **`history`** (array, optional): An array of message pairs representing the conversation history. Each pair consists of a role (either 'human' or 'assistant') and the message content. This allows the system to use the context of the conversation to refine results. Example:
|
| 115 |
+
|
| 116 |
+
```json
|
| 117 |
+
[
|
| 118 |
+
["human", "What is Perplexica?"],
|
| 119 |
+
["assistant", "Perplexica is an AI-powered search engine..."]
|
| 120 |
+
]
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
- **`stream`** (boolean, optional): When set to `true`, enables streaming responses. Default is `false`.
|
| 124 |
+
|
| 125 |
+
### Response
|
| 126 |
+
|
| 127 |
+
The response from the API includes both the final message and the sources used to generate that message.
|
| 128 |
+
|
| 129 |
+
#### Standard Response (stream: false)
|
| 130 |
+
|
| 131 |
+
```json
|
| 132 |
+
{
|
| 133 |
+
"message": "Perplexica is an innovative, open-source AI-powered search engine designed to enhance the way users search for information online. Here are some key features and characteristics of Perplexica:\n\n- **AI-Powered Technology**: It utilizes advanced machine learning algorithms to not only retrieve information but also to understand the context and intent behind user queries, providing more relevant results [1][5].\n\n- **Open-Source**: Being open-source, Perplexica offers flexibility and transparency, allowing users to explore its functionalities without the constraints of proprietary software [3][10].",
|
| 134 |
+
"sources": [
|
| 135 |
+
{
|
| 136 |
+
"content": "Perplexica is an innovative, open-source AI-powered search engine designed to enhance the way users search for information online.",
|
| 137 |
+
"metadata": {
|
| 138 |
+
"title": "What is Perplexica, and how does it function as an AI-powered search ...",
|
| 139 |
+
"url": "https://askai.glarity.app/search/What-is-Perplexica--and-how-does-it-function-as-an-AI-powered-search-engine"
|
| 140 |
+
}
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
"content": "Perplexica is an open-source AI-powered search tool that dives deep into the internet to find precise answers.",
|
| 144 |
+
"metadata": {
|
| 145 |
+
"title": "Sahar Mor's Post",
|
| 146 |
+
"url": "https://www.linkedin.com/posts/sahar-mor_a-new-open-source-project-called-perplexica-activity-7204489745668694016-ncja"
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
....
|
| 150 |
+
]
|
| 151 |
+
}
|
| 152 |
+
```
|
| 153 |
+
|
| 154 |
+
#### Streaming Response (stream: true)
|
| 155 |
+
|
| 156 |
+
When streaming is enabled, the API returns a stream of newline-delimited JSON objects using Server-Sent Events (SSE). Each line contains a complete, valid JSON object. The response has `Content-Type: text/event-stream`.
|
| 157 |
+
|
| 158 |
+
Example of streamed response objects:
|
| 159 |
+
|
| 160 |
+
```
|
| 161 |
+
{"type":"init","data":"Stream connected"}
|
| 162 |
+
{"type":"sources","data":[{"content":"...","metadata":{"title":"...","url":"..."}},...]}
|
| 163 |
+
{"type":"response","data":"Perplexica is an "}
|
| 164 |
+
{"type":"response","data":"innovative, open-source "}
|
| 165 |
+
{"type":"response","data":"AI-powered search engine..."}
|
| 166 |
+
{"type":"done"}
|
| 167 |
+
```
|
| 168 |
+
|
| 169 |
+
Clients should process each line as a separate JSON object. The different message types include:
|
| 170 |
+
|
| 171 |
+
- **`init`**: Initial connection message
|
| 172 |
+
- **`sources`**: All sources used for the response
|
| 173 |
+
- **`response`**: Chunks of the generated answer text
|
| 174 |
+
- **`done`**: Indicates the stream is complete
|
| 175 |
+
|
| 176 |
+
### Fields in the Response
|
| 177 |
+
|
| 178 |
+
- **`message`** (string): The search result, generated based on the query and enabled `sources`.
|
| 179 |
+
- **`sources`** (array): A list of sources that were used to generate the search result. Each source includes:
|
| 180 |
+
- `content`: A snippet of the relevant content from the source.
|
| 181 |
+
- `metadata`: Metadata about the source, including:
|
| 182 |
+
- `title`: The title of the webpage.
|
| 183 |
+
- `url`: The URL of the webpage.
|
| 184 |
+
|
| 185 |
+
### Error Handling
|
| 186 |
+
|
| 187 |
+
If an error occurs during the search process, the API will return an appropriate error message with an HTTP status code.
|
| 188 |
+
|
| 189 |
+
- **400**: If the request is malformed or missing required fields (e.g., no `sources` or `query`).
|
| 190 |
+
- **500**: If an internal server error occurs during the search.
|
docs/architecture/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Perplexica Architecture
|
| 2 |
+
|
| 3 |
+
Perplexica is a Next.js application that combines an AI chat experience with search.
|
| 4 |
+
|
| 5 |
+
For a high level flow, see [WORKING.md](WORKING.md). For deeper implementation details, see [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
| 6 |
+
|
| 7 |
+
## Key components
|
| 8 |
+
|
| 9 |
+
1. **User Interface**
|
| 10 |
+
|
| 11 |
+
- A web based UI that lets users chat, search, and view citations.
|
| 12 |
+
|
| 13 |
+
2. **API Routes**
|
| 14 |
+
|
| 15 |
+
- `POST /api/chat` powers the chat UI.
|
| 16 |
+
- `POST /api/search` provides a programmatic search endpoint.
|
| 17 |
+
- `GET /api/providers` lists available providers and model keys.
|
| 18 |
+
|
| 19 |
+
3. **Agents and Orchestration**
|
| 20 |
+
|
| 21 |
+
- The system classifies the question first.
|
| 22 |
+
- It can run research and widgets in parallel.
|
| 23 |
+
- It generates the final answer and includes citations.
|
| 24 |
+
|
| 25 |
+
4. **Search Backend**
|
| 26 |
+
|
| 27 |
+
- A meta search backend is used to fetch relevant web results when research is enabled.
|
| 28 |
+
|
| 29 |
+
5. **LLMs (Large Language Models)**
|
| 30 |
+
|
| 31 |
+
- Used for classification, writing answers, and producing citations.
|
| 32 |
+
|
| 33 |
+
6. **Embedding Models**
|
| 34 |
+
|
| 35 |
+
- Used for semantic search over user uploaded files.
|
| 36 |
+
|
| 37 |
+
7. **Storage**
|
| 38 |
+
- Chats and messages are stored so conversations can be reloaded.
|
docs/architecture/WORKING.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# How Perplexica Works
|
| 2 |
+
|
| 3 |
+
This is a high level overview of how Perplexica answers a question.
|
| 4 |
+
|
| 5 |
+
If you want a component level overview, see [README.md](README.md).
|
| 6 |
+
|
| 7 |
+
If you want implementation details, see [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
| 8 |
+
|
| 9 |
+
## What happens when you ask a question
|
| 10 |
+
|
| 11 |
+
When you send a message in the UI, the app calls `POST /api/chat`.
|
| 12 |
+
|
| 13 |
+
At a high level, we do three things:
|
| 14 |
+
|
| 15 |
+
1. Classify the question and decide what to do next.
|
| 16 |
+
2. Run research and widgets in parallel.
|
| 17 |
+
3. Write the final answer and include citations.
|
| 18 |
+
|
| 19 |
+
## Classification
|
| 20 |
+
|
| 21 |
+
Before searching or answering, we run a classification step.
|
| 22 |
+
|
| 23 |
+
This step decides things like:
|
| 24 |
+
|
| 25 |
+
- Whether we should do research for this question
|
| 26 |
+
- Whether we should show any widgets
|
| 27 |
+
- How to rewrite the question into a clearer standalone form
|
| 28 |
+
|
| 29 |
+
## Widgets
|
| 30 |
+
|
| 31 |
+
Widgets are small, structured helpers that can run alongside research.
|
| 32 |
+
|
| 33 |
+
Examples include weather, stocks, and simple calculations.
|
| 34 |
+
|
| 35 |
+
If a widget is relevant, we show it in the UI while the answer is still being generated.
|
| 36 |
+
|
| 37 |
+
Widgets are helpful context for the answer, but they are not part of what the model should cite.
|
| 38 |
+
|
| 39 |
+
## Research
|
| 40 |
+
|
| 41 |
+
If research is needed, we gather information in the background while widgets can run.
|
| 42 |
+
|
| 43 |
+
Depending on configuration, research may include web lookup and searching user uploaded files.
|
| 44 |
+
|
| 45 |
+
## Answer generation
|
| 46 |
+
|
| 47 |
+
Once we have enough context, the chat model generates the final response.
|
| 48 |
+
|
| 49 |
+
You can control the tradeoff between speed and quality using `optimizationMode`:
|
| 50 |
+
|
| 51 |
+
- `speed`
|
| 52 |
+
- `balanced`
|
| 53 |
+
- `quality`
|
| 54 |
+
|
| 55 |
+
## How citations work
|
| 56 |
+
|
| 57 |
+
We prompt the model to cite the references it used. The UI then renders those citations alongside the supporting links.
|
| 58 |
+
|
| 59 |
+
## Search API
|
| 60 |
+
|
| 61 |
+
If you are integrating Perplexica into another product, you can call `POST /api/search`.
|
| 62 |
+
|
| 63 |
+
It returns:
|
| 64 |
+
|
| 65 |
+
- `message`: the generated answer
|
| 66 |
+
- `sources`: supporting references used for the answer
|
| 67 |
+
|
| 68 |
+
You can also enable streaming by setting `stream: true`.
|
| 69 |
+
|
| 70 |
+
## Image and video search
|
| 71 |
+
|
| 72 |
+
Image and video search use separate endpoints (`POST /api/images` and `POST /api/videos`). We generate a focused query using the chat model, then fetch matching results from a search backend.
|
docs/installation/UPDATING.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Update Perplexica to the latest version
|
| 2 |
+
|
| 3 |
+
To update Perplexica to the latest version, follow these steps:
|
| 4 |
+
|
| 5 |
+
## For Docker users (Using pre-built images)
|
| 6 |
+
|
| 7 |
+
Simply pull the latest image and restart your container:
|
| 8 |
+
|
| 9 |
+
```bash
|
| 10 |
+
docker pull itzcrazykns1337/perplexica:latest
|
| 11 |
+
docker stop perplexica
|
| 12 |
+
docker rm perplexica
|
| 13 |
+
docker run -d -p 3000:3000 -v perplexica-data:/home/perplexica/data --name perplexica itzcrazykns1337/perplexica:latest
|
| 14 |
+
```
|
| 15 |
+
|
| 16 |
+
For slim version:
|
| 17 |
+
|
| 18 |
+
```bash
|
| 19 |
+
docker pull itzcrazykns1337/perplexica:slim-latest
|
| 20 |
+
docker stop perplexica
|
| 21 |
+
docker rm perplexica
|
| 22 |
+
docker run -d -p 3000:3000 -e SEARXNG_API_URL=http://your-searxng-url:8080 -v perplexica-data:/home/perplexica/data --name perplexica itzcrazykns1337/perplexica:slim-latest
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
Once updated, go to http://localhost:3000 and verify the latest changes. Your settings are preserved automatically.
|
| 26 |
+
|
| 27 |
+
## For Docker users (Building from source)
|
| 28 |
+
|
| 29 |
+
1. Navigate to your Perplexica directory and pull the latest changes:
|
| 30 |
+
|
| 31 |
+
```bash
|
| 32 |
+
cd Perplexica
|
| 33 |
+
git pull origin master
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
2. Rebuild the Docker image:
|
| 37 |
+
|
| 38 |
+
```bash
|
| 39 |
+
docker build -t perplexica .
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
3. Stop and remove the old container, then start the new one:
|
| 43 |
+
|
| 44 |
+
```bash
|
| 45 |
+
docker stop perplexica
|
| 46 |
+
docker rm perplexica
|
| 47 |
+
docker run -p 3000:3000 -p 8080:8080 --name perplexica perplexica
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
4. Once the command completes, go to http://localhost:3000 and verify the latest changes.
|
| 51 |
+
|
| 52 |
+
## For non-Docker users
|
| 53 |
+
|
| 54 |
+
1. Navigate to your Perplexica directory and pull the latest changes:
|
| 55 |
+
|
| 56 |
+
```bash
|
| 57 |
+
cd Perplexica
|
| 58 |
+
git pull origin master
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
2. Install any new dependencies:
|
| 62 |
+
|
| 63 |
+
```bash
|
| 64 |
+
npm i
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
3. Rebuild the application:
|
| 68 |
+
|
| 69 |
+
```bash
|
| 70 |
+
npm run build
|
| 71 |
+
```
|
| 72 |
+
|
| 73 |
+
4. Restart the application:
|
| 74 |
+
|
| 75 |
+
```bash
|
| 76 |
+
npm run start
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
5. Go to http://localhost:3000 and verify the latest changes. Your settings are preserved automatically.
|
| 80 |
+
|
| 81 |
+
---
|
drizzle.config.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { defineConfig } from 'drizzle-kit';
|
| 2 |
+
import path from 'path';
|
| 3 |
+
|
| 4 |
+
export default defineConfig({
|
| 5 |
+
dialect: 'sqlite',
|
| 6 |
+
schema: './src/lib/db/schema.ts',
|
| 7 |
+
out: './drizzle',
|
| 8 |
+
dbCredentials: {
|
| 9 |
+
url: path.join(process.cwd(), 'data', 'db.sqlite'),
|
| 10 |
+
},
|
| 11 |
+
});
|
drizzle/0000_fuzzy_randall.sql
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
CREATE TABLE IF NOT EXISTS `chats` (
|
| 2 |
+
`id` text PRIMARY KEY NOT NULL,
|
| 3 |
+
`title` text NOT NULL,
|
| 4 |
+
`createdAt` text NOT NULL,
|
| 5 |
+
`focusMode` text NOT NULL,
|
| 6 |
+
`files` text DEFAULT '[]'
|
| 7 |
+
);
|
| 8 |
+
--> statement-breakpoint
|
| 9 |
+
CREATE TABLE IF NOT EXISTS `messages` (
|
| 10 |
+
`id` integer PRIMARY KEY NOT NULL,
|
| 11 |
+
`content` text NOT NULL,
|
| 12 |
+
`chatId` text NOT NULL,
|
| 13 |
+
`messageId` text NOT NULL,
|
| 14 |
+
`type` text,
|
| 15 |
+
`metadata` text
|
| 16 |
+
);
|
drizzle/0001_wise_rockslide.sql
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
/* Do nothing */
|
drizzle/0002_daffy_wrecker.sql
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
/* do nothing */
|
drizzle/meta/0000_snapshot.json
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "6",
|
| 3 |
+
"dialect": "sqlite",
|
| 4 |
+
"id": "ef3a044b-0f34-40b5-babb-2bb3a909ba27",
|
| 5 |
+
"prevId": "00000000-0000-0000-0000-000000000000",
|
| 6 |
+
"tables": {
|
| 7 |
+
"chats": {
|
| 8 |
+
"name": "chats",
|
| 9 |
+
"columns": {
|
| 10 |
+
"id": {
|
| 11 |
+
"name": "id",
|
| 12 |
+
"type": "text",
|
| 13 |
+
"primaryKey": true,
|
| 14 |
+
"notNull": true,
|
| 15 |
+
"autoincrement": false
|
| 16 |
+
},
|
| 17 |
+
"title": {
|
| 18 |
+
"name": "title",
|
| 19 |
+
"type": "text",
|
| 20 |
+
"primaryKey": false,
|
| 21 |
+
"notNull": true,
|
| 22 |
+
"autoincrement": false
|
| 23 |
+
},
|
| 24 |
+
"createdAt": {
|
| 25 |
+
"name": "createdAt",
|
| 26 |
+
"type": "text",
|
| 27 |
+
"primaryKey": false,
|
| 28 |
+
"notNull": true,
|
| 29 |
+
"autoincrement": false
|
| 30 |
+
},
|
| 31 |
+
"focusMode": {
|
| 32 |
+
"name": "focusMode",
|
| 33 |
+
"type": "text",
|
| 34 |
+
"primaryKey": false,
|
| 35 |
+
"notNull": true,
|
| 36 |
+
"autoincrement": false
|
| 37 |
+
},
|
| 38 |
+
"files": {
|
| 39 |
+
"name": "files",
|
| 40 |
+
"type": "text",
|
| 41 |
+
"primaryKey": false,
|
| 42 |
+
"notNull": false,
|
| 43 |
+
"autoincrement": false,
|
| 44 |
+
"default": "'[]'"
|
| 45 |
+
}
|
| 46 |
+
},
|
| 47 |
+
"indexes": {},
|
| 48 |
+
"foreignKeys": {},
|
| 49 |
+
"compositePrimaryKeys": {},
|
| 50 |
+
"uniqueConstraints": {},
|
| 51 |
+
"checkConstraints": {}
|
| 52 |
+
},
|
| 53 |
+
"messages": {
|
| 54 |
+
"name": "messages",
|
| 55 |
+
"columns": {
|
| 56 |
+
"id": {
|
| 57 |
+
"name": "id",
|
| 58 |
+
"type": "integer",
|
| 59 |
+
"primaryKey": true,
|
| 60 |
+
"notNull": true,
|
| 61 |
+
"autoincrement": false
|
| 62 |
+
},
|
| 63 |
+
"content": {
|
| 64 |
+
"name": "content",
|
| 65 |
+
"type": "text",
|
| 66 |
+
"primaryKey": false,
|
| 67 |
+
"notNull": true,
|
| 68 |
+
"autoincrement": false
|
| 69 |
+
},
|
| 70 |
+
"chatId": {
|
| 71 |
+
"name": "chatId",
|
| 72 |
+
"type": "text",
|
| 73 |
+
"primaryKey": false,
|
| 74 |
+
"notNull": true,
|
| 75 |
+
"autoincrement": false
|
| 76 |
+
},
|
| 77 |
+
"messageId": {
|
| 78 |
+
"name": "messageId",
|
| 79 |
+
"type": "text",
|
| 80 |
+
"primaryKey": false,
|
| 81 |
+
"notNull": true,
|
| 82 |
+
"autoincrement": false
|
| 83 |
+
},
|
| 84 |
+
"type": {
|
| 85 |
+
"name": "type",
|
| 86 |
+
"type": "text",
|
| 87 |
+
"primaryKey": false,
|
| 88 |
+
"notNull": false,
|
| 89 |
+
"autoincrement": false
|
| 90 |
+
},
|
| 91 |
+
"metadata": {
|
| 92 |
+
"name": "metadata",
|
| 93 |
+
"type": "text",
|
| 94 |
+
"primaryKey": false,
|
| 95 |
+
"notNull": false,
|
| 96 |
+
"autoincrement": false
|
| 97 |
+
}
|
| 98 |
+
},
|
| 99 |
+
"indexes": {},
|
| 100 |
+
"foreignKeys": {},
|
| 101 |
+
"compositePrimaryKeys": {},
|
| 102 |
+
"uniqueConstraints": {},
|
| 103 |
+
"checkConstraints": {}
|
| 104 |
+
}
|
| 105 |
+
},
|
| 106 |
+
"views": {},
|
| 107 |
+
"enums": {},
|
| 108 |
+
"_meta": {
|
| 109 |
+
"schemas": {},
|
| 110 |
+
"tables": {},
|
| 111 |
+
"columns": {}
|
| 112 |
+
},
|
| 113 |
+
"internal": {
|
| 114 |
+
"indexes": {}
|
| 115 |
+
}
|
| 116 |
+
}
|
drizzle/meta/0001_snapshot.json
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "6",
|
| 3 |
+
"dialect": "sqlite",
|
| 4 |
+
"id": "6dedf55f-0e44-478f-82cf-14a21ac686f8",
|
| 5 |
+
"prevId": "ef3a044b-0f34-40b5-babb-2bb3a909ba27",
|
| 6 |
+
"tables": {
|
| 7 |
+
"chats": {
|
| 8 |
+
"name": "chats",
|
| 9 |
+
"columns": {
|
| 10 |
+
"id": {
|
| 11 |
+
"name": "id",
|
| 12 |
+
"type": "text",
|
| 13 |
+
"primaryKey": true,
|
| 14 |
+
"notNull": true,
|
| 15 |
+
"autoincrement": false
|
| 16 |
+
},
|
| 17 |
+
"title": {
|
| 18 |
+
"name": "title",
|
| 19 |
+
"type": "text",
|
| 20 |
+
"primaryKey": false,
|
| 21 |
+
"notNull": true,
|
| 22 |
+
"autoincrement": false
|
| 23 |
+
},
|
| 24 |
+
"createdAt": {
|
| 25 |
+
"name": "createdAt",
|
| 26 |
+
"type": "text",
|
| 27 |
+
"primaryKey": false,
|
| 28 |
+
"notNull": true,
|
| 29 |
+
"autoincrement": false
|
| 30 |
+
},
|
| 31 |
+
"focusMode": {
|
| 32 |
+
"name": "focusMode",
|
| 33 |
+
"type": "text",
|
| 34 |
+
"primaryKey": false,
|
| 35 |
+
"notNull": true,
|
| 36 |
+
"autoincrement": false
|
| 37 |
+
},
|
| 38 |
+
"files": {
|
| 39 |
+
"name": "files",
|
| 40 |
+
"type": "text",
|
| 41 |
+
"primaryKey": false,
|
| 42 |
+
"notNull": false,
|
| 43 |
+
"autoincrement": false,
|
| 44 |
+
"default": "'[]'"
|
| 45 |
+
}
|
| 46 |
+
},
|
| 47 |
+
"indexes": {},
|
| 48 |
+
"foreignKeys": {},
|
| 49 |
+
"compositePrimaryKeys": {},
|
| 50 |
+
"uniqueConstraints": {},
|
| 51 |
+
"checkConstraints": {}
|
| 52 |
+
},
|
| 53 |
+
"messages": {
|
| 54 |
+
"name": "messages",
|
| 55 |
+
"columns": {
|
| 56 |
+
"id": {
|
| 57 |
+
"name": "id",
|
| 58 |
+
"type": "integer",
|
| 59 |
+
"primaryKey": true,
|
| 60 |
+
"notNull": true,
|
| 61 |
+
"autoincrement": false
|
| 62 |
+
},
|
| 63 |
+
"type": {
|
| 64 |
+
"name": "type",
|
| 65 |
+
"type": "text",
|
| 66 |
+
"primaryKey": false,
|
| 67 |
+
"notNull": true,
|
| 68 |
+
"autoincrement": false
|
| 69 |
+
},
|
| 70 |
+
"chatId": {
|
| 71 |
+
"name": "chatId",
|
| 72 |
+
"type": "text",
|
| 73 |
+
"primaryKey": false,
|
| 74 |
+
"notNull": true,
|
| 75 |
+
"autoincrement": false
|
| 76 |
+
},
|
| 77 |
+
"createdAt": {
|
| 78 |
+
"name": "createdAt",
|
| 79 |
+
"type": "text",
|
| 80 |
+
"primaryKey": false,
|
| 81 |
+
"notNull": true,
|
| 82 |
+
"autoincrement": false,
|
| 83 |
+
"default": "CURRENT_TIMESTAMP"
|
| 84 |
+
},
|
| 85 |
+
"messageId": {
|
| 86 |
+
"name": "messageId",
|
| 87 |
+
"type": "text",
|
| 88 |
+
"primaryKey": false,
|
| 89 |
+
"notNull": true,
|
| 90 |
+
"autoincrement": false
|
| 91 |
+
},
|
| 92 |
+
"content": {
|
| 93 |
+
"name": "content",
|
| 94 |
+
"type": "text",
|
| 95 |
+
"primaryKey": false,
|
| 96 |
+
"notNull": false,
|
| 97 |
+
"autoincrement": false
|
| 98 |
+
},
|
| 99 |
+
"sources": {
|
| 100 |
+
"name": "sources",
|
| 101 |
+
"type": "text",
|
| 102 |
+
"primaryKey": false,
|
| 103 |
+
"notNull": false,
|
| 104 |
+
"autoincrement": false,
|
| 105 |
+
"default": "'[]'"
|
| 106 |
+
}
|
| 107 |
+
},
|
| 108 |
+
"indexes": {},
|
| 109 |
+
"foreignKeys": {},
|
| 110 |
+
"compositePrimaryKeys": {},
|
| 111 |
+
"uniqueConstraints": {},
|
| 112 |
+
"checkConstraints": {}
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
"views": {},
|
| 116 |
+
"enums": {},
|
| 117 |
+
"_meta": {
|
| 118 |
+
"schemas": {},
|
| 119 |
+
"tables": {},
|
| 120 |
+
"columns": {}
|
| 121 |
+
},
|
| 122 |
+
"internal": {
|
| 123 |
+
"indexes": {}
|
| 124 |
+
}
|
| 125 |
+
}
|
drizzle/meta/0002_snapshot.json
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "6",
|
| 3 |
+
"dialect": "sqlite",
|
| 4 |
+
"id": "1c5eb804-d6b4-48ec-9a8f-75fb729c8e52",
|
| 5 |
+
"prevId": "6dedf55f-0e44-478f-82cf-14a21ac686f8",
|
| 6 |
+
"tables": {
|
| 7 |
+
"chats": {
|
| 8 |
+
"name": "chats",
|
| 9 |
+
"columns": {
|
| 10 |
+
"id": {
|
| 11 |
+
"name": "id",
|
| 12 |
+
"type": "text",
|
| 13 |
+
"primaryKey": true,
|
| 14 |
+
"notNull": true,
|
| 15 |
+
"autoincrement": false
|
| 16 |
+
},
|
| 17 |
+
"title": {
|
| 18 |
+
"name": "title",
|
| 19 |
+
"type": "text",
|
| 20 |
+
"primaryKey": false,
|
| 21 |
+
"notNull": true,
|
| 22 |
+
"autoincrement": false
|
| 23 |
+
},
|
| 24 |
+
"createdAt": {
|
| 25 |
+
"name": "createdAt",
|
| 26 |
+
"type": "text",
|
| 27 |
+
"primaryKey": false,
|
| 28 |
+
"notNull": true,
|
| 29 |
+
"autoincrement": false
|
| 30 |
+
},
|
| 31 |
+
"sources": {
|
| 32 |
+
"name": "sources",
|
| 33 |
+
"type": "text",
|
| 34 |
+
"primaryKey": false,
|
| 35 |
+
"notNull": true,
|
| 36 |
+
"autoincrement": false
|
| 37 |
+
},
|
| 38 |
+
"files": {
|
| 39 |
+
"name": "files",
|
| 40 |
+
"type": "text",
|
| 41 |
+
"primaryKey": false,
|
| 42 |
+
"notNull": false,
|
| 43 |
+
"autoincrement": false,
|
| 44 |
+
"default": "'[]'"
|
| 45 |
+
}
|
| 46 |
+
},
|
| 47 |
+
"indexes": {},
|
| 48 |
+
"foreignKeys": {},
|
| 49 |
+
"compositePrimaryKeys": {},
|
| 50 |
+
"uniqueConstraints": {},
|
| 51 |
+
"checkConstraints": {}
|
| 52 |
+
},
|
| 53 |
+
"messages": {
|
| 54 |
+
"name": "messages",
|
| 55 |
+
"columns": {
|
| 56 |
+
"id": {
|
| 57 |
+
"name": "id",
|
| 58 |
+
"type": "integer",
|
| 59 |
+
"primaryKey": true,
|
| 60 |
+
"notNull": true,
|
| 61 |
+
"autoincrement": false
|
| 62 |
+
},
|
| 63 |
+
"messageId": {
|
| 64 |
+
"name": "messageId",
|
| 65 |
+
"type": "text",
|
| 66 |
+
"primaryKey": false,
|
| 67 |
+
"notNull": true,
|
| 68 |
+
"autoincrement": false
|
| 69 |
+
},
|
| 70 |
+
"chatId": {
|
| 71 |
+
"name": "chatId",
|
| 72 |
+
"type": "text",
|
| 73 |
+
"primaryKey": false,
|
| 74 |
+
"notNull": true,
|
| 75 |
+
"autoincrement": false
|
| 76 |
+
},
|
| 77 |
+
"backendId": {
|
| 78 |
+
"name": "backendId",
|
| 79 |
+
"type": "text",
|
| 80 |
+
"primaryKey": false,
|
| 81 |
+
"notNull": true,
|
| 82 |
+
"autoincrement": false
|
| 83 |
+
},
|
| 84 |
+
"query": {
|
| 85 |
+
"name": "query",
|
| 86 |
+
"type": "text",
|
| 87 |
+
"primaryKey": false,
|
| 88 |
+
"notNull": true,
|
| 89 |
+
"autoincrement": false
|
| 90 |
+
},
|
| 91 |
+
"createdAt": {
|
| 92 |
+
"name": "createdAt",
|
| 93 |
+
"type": "text",
|
| 94 |
+
"primaryKey": false,
|
| 95 |
+
"notNull": true,
|
| 96 |
+
"autoincrement": false
|
| 97 |
+
},
|
| 98 |
+
"responseBlocks": {
|
| 99 |
+
"name": "responseBlocks",
|
| 100 |
+
"type": "text",
|
| 101 |
+
"primaryKey": false,
|
| 102 |
+
"notNull": false,
|
| 103 |
+
"autoincrement": false,
|
| 104 |
+
"default": "'[]'"
|
| 105 |
+
},
|
| 106 |
+
"status": {
|
| 107 |
+
"name": "status",
|
| 108 |
+
"type": "text",
|
| 109 |
+
"primaryKey": false,
|
| 110 |
+
"notNull": false,
|
| 111 |
+
"autoincrement": false,
|
| 112 |
+
"default": "'answering'"
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
"indexes": {},
|
| 116 |
+
"foreignKeys": {},
|
| 117 |
+
"compositePrimaryKeys": {},
|
| 118 |
+
"uniqueConstraints": {},
|
| 119 |
+
"checkConstraints": {}
|
| 120 |
+
}
|
| 121 |
+
},
|
| 122 |
+
"views": {},
|
| 123 |
+
"enums": {},
|
| 124 |
+
"_meta": {
|
| 125 |
+
"schemas": {},
|
| 126 |
+
"tables": {},
|
| 127 |
+
"columns": {}
|
| 128 |
+
},
|
| 129 |
+
"internal": {
|
| 130 |
+
"indexes": {}
|
| 131 |
+
}
|
| 132 |
+
}
|
drizzle/meta/_journal.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "7",
|
| 3 |
+
"dialect": "sqlite",
|
| 4 |
+
"entries": [
|
| 5 |
+
{
|
| 6 |
+
"idx": 0,
|
| 7 |
+
"version": "6",
|
| 8 |
+
"when": 1748405503809,
|
| 9 |
+
"tag": "0000_fuzzy_randall",
|
| 10 |
+
"breakpoints": true
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"idx": 1,
|
| 14 |
+
"version": "6",
|
| 15 |
+
"when": 1758863991284,
|
| 16 |
+
"tag": "0001_wise_rockslide",
|
| 17 |
+
"breakpoints": true
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"idx": 2,
|
| 21 |
+
"version": "6",
|
| 22 |
+
"when": 1763732708332,
|
| 23 |
+
"tag": "0002_daffy_wrecker",
|
| 24 |
+
"breakpoints": true
|
| 25 |
+
}
|
| 26 |
+
]
|
| 27 |
+
}
|
entrypoint-hf.sh
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
PORT="${PORT:-7860}"
|
| 5 |
+
SPACE_PASSWORD="${PASSWORD:-${password:-}}"
|
| 6 |
+
|
| 7 |
+
if [ -z "${SPACE_PASSWORD}" ]; then
|
| 8 |
+
echo "ERROR: PASSWORD secret is required for this public Space."
|
| 9 |
+
exit 1
|
| 10 |
+
fi
|
| 11 |
+
|
| 12 |
+
password_hash="$(openssl passwd -apr1 "${SPACE_PASSWORD}")"
|
| 13 |
+
printf "admin:%s\n" "${password_hash}" >/tmp/.htpasswd
|
| 14 |
+
cat >/tmp/nginx.auth.conf <<EOF
|
| 15 |
+
auth_basic "Perplexica";
|
| 16 |
+
auth_basic_user_file /tmp/.htpasswd;
|
| 17 |
+
EOF
|
| 18 |
+
|
| 19 |
+
sed "s/__PORT__/${PORT}/g" /home/perplexica/hf.nginx.conf >/tmp/nginx.conf
|
| 20 |
+
|
| 21 |
+
echo "Starting SearXNG..."
|
| 22 |
+
sudo -H -u searxng bash -c "cd /usr/local/searxng/searxng-src && export SEARXNG_SETTINGS_PATH='/etc/searxng/settings.yml' && export FLASK_APP=searx/webapp.py && /usr/local/searxng/searx-pyenv/bin/python -m flask run --host=0.0.0.0 --port=8080" &
|
| 23 |
+
SEARXNG_PID=$!
|
| 24 |
+
|
| 25 |
+
echo "Waiting for SearXNG..."
|
| 26 |
+
COUNTER=0
|
| 27 |
+
MAX_TRIES=30
|
| 28 |
+
until curl -s http://127.0.0.1:8080 >/dev/null 2>&1; do
|
| 29 |
+
COUNTER=$((COUNTER + 1))
|
| 30 |
+
if [ "${COUNTER}" -ge "${MAX_TRIES}" ]; then
|
| 31 |
+
echo "WARNING: SearXNG health check timeout, continuing startup."
|
| 32 |
+
break
|
| 33 |
+
fi
|
| 34 |
+
sleep 1
|
| 35 |
+
done
|
| 36 |
+
|
| 37 |
+
echo "Starting Perplexica..."
|
| 38 |
+
cd /home/perplexica
|
| 39 |
+
HOSTNAME=0.0.0.0 PORT=3000 node server.js &
|
| 40 |
+
NODE_PID=$!
|
| 41 |
+
|
| 42 |
+
echo "Starting Nginx..."
|
| 43 |
+
nginx -g "daemon off;" -c /tmp/nginx.conf &
|
| 44 |
+
NGINX_PID=$!
|
| 45 |
+
|
| 46 |
+
cleanup() {
|
| 47 |
+
kill "${NGINX_PID}" "${NODE_PID}" "${SEARXNG_PID}" 2>/dev/null || true
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
trap cleanup SIGINT SIGTERM
|
| 51 |
+
|
| 52 |
+
set +e
|
| 53 |
+
wait -n "${NGINX_PID}" "${NODE_PID}" "${SEARXNG_PID}"
|
| 54 |
+
status=$?
|
| 55 |
+
set -e
|
| 56 |
+
|
| 57 |
+
cleanup
|
| 58 |
+
wait || true
|
| 59 |
+
exit "${status}"
|
entrypoint.sh
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
echo "Starting SearXNG..."
|
| 5 |
+
|
| 6 |
+
sudo -H -u searxng bash -c "cd /usr/local/searxng/searxng-src && export SEARXNG_SETTINGS_PATH='/etc/searxng/settings.yml' && export FLASK_APP=searx/webapp.py && /usr/local/searxng/searx-pyenv/bin/python -m flask run --host=0.0.0.0 --port=8080" &
|
| 7 |
+
SEARXNG_PID=$!
|
| 8 |
+
|
| 9 |
+
echo "Waiting for SearXNG to be ready..."
|
| 10 |
+
sleep 5
|
| 11 |
+
|
| 12 |
+
COUNTER=0
|
| 13 |
+
MAX_TRIES=30
|
| 14 |
+
until curl -s http://localhost:8080 > /dev/null 2>&1; do
|
| 15 |
+
COUNTER=$((COUNTER+1))
|
| 16 |
+
if [ $COUNTER -ge $MAX_TRIES ]; then
|
| 17 |
+
echo "Warning: SearXNG health check timeout, but continuing..."
|
| 18 |
+
break
|
| 19 |
+
fi
|
| 20 |
+
sleep 1
|
| 21 |
+
done
|
| 22 |
+
|
| 23 |
+
if curl -s http://localhost:8080 > /dev/null 2>&1; then
|
| 24 |
+
echo "SearXNG started successfully (PID: $SEARXNG_PID)"
|
| 25 |
+
else
|
| 26 |
+
echo "SearXNG may not be fully ready, but continuing (PID: $SEARXNG_PID)"
|
| 27 |
+
fi
|
| 28 |
+
|
| 29 |
+
cd /home/perplexica
|
| 30 |
+
echo "Starting Perplexica..."
|
| 31 |
+
|
| 32 |
+
exec node server.js
|
hf.nginx.conf
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
events {
|
| 2 |
+
worker_connections 1024;
|
| 3 |
+
}
|
| 4 |
+
|
| 5 |
+
pid /tmp/nginx.pid;
|
| 6 |
+
|
| 7 |
+
http {
|
| 8 |
+
access_log /dev/stdout;
|
| 9 |
+
error_log /dev/stderr;
|
| 10 |
+
|
| 11 |
+
server {
|
| 12 |
+
listen __PORT__;
|
| 13 |
+
listen [::]:__PORT__;
|
| 14 |
+
server_name _;
|
| 15 |
+
include /tmp/nginx.auth.conf;
|
| 16 |
+
|
| 17 |
+
location / {
|
| 18 |
+
proxy_pass http://127.0.0.1:3000;
|
| 19 |
+
proxy_http_version 1.1;
|
| 20 |
+
proxy_set_header Host $host;
|
| 21 |
+
proxy_set_header X-Real-IP $remote_addr;
|
| 22 |
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
| 23 |
+
proxy_set_header X-Forwarded-Proto $scheme;
|
| 24 |
+
proxy_set_header Upgrade $http_upgrade;
|
| 25 |
+
proxy_set_header Connection "upgrade";
|
| 26 |
+
proxy_read_timeout 600s;
|
| 27 |
+
proxy_send_timeout 600s;
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
}
|
next-env.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// <reference types="next" />
|
| 2 |
+
/// <reference types="next/image-types/global" />
|
| 3 |
+
import './.next/dev/types/routes.d.ts';
|
| 4 |
+
|
| 5 |
+
// NOTE: This file should not be edited
|
| 6 |
+
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
next.config.mjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pkg from './package.json' with { type: 'json' };
|
| 2 |
+
|
| 3 |
+
/** @type {import('next').NextConfig} */
|
| 4 |
+
const nextConfig = {
|
| 5 |
+
output: 'standalone',
|
| 6 |
+
images: {
|
| 7 |
+
remotePatterns: [
|
| 8 |
+
{
|
| 9 |
+
hostname: 's2.googleusercontent.com',
|
| 10 |
+
},
|
| 11 |
+
],
|
| 12 |
+
},
|
| 13 |
+
serverExternalPackages: ['pdf-parse'],
|
| 14 |
+
outputFileTracingIncludes: {
|
| 15 |
+
'/api/**': [
|
| 16 |
+
'./node_modules/@napi-rs/canvas/**',
|
| 17 |
+
'./node_modules/@napi-rs/canvas-linux-x64-gnu/**',
|
| 18 |
+
'./node_modules/@napi-rs/canvas-linux-x64-musl/**',
|
| 19 |
+
],
|
| 20 |
+
},
|
| 21 |
+
env: {
|
| 22 |
+
NEXT_PUBLIC_VERSION: pkg.version,
|
| 23 |
+
},
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
export default nextConfig;
|
package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "perplexica",
|
| 3 |
+
"version": "1.12.1",
|
| 4 |
+
"license": "MIT",
|
| 5 |
+
"author": "ItzCrazyKns",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "next dev --webpack",
|
| 8 |
+
"build": "next build --webpack",
|
| 9 |
+
"start": "next start",
|
| 10 |
+
"lint": "next lint",
|
| 11 |
+
"format:write": "prettier . --write"
|
| 12 |
+
},
|
| 13 |
+
"dependencies": {
|
| 14 |
+
"@google/genai": "^1.34.0",
|
| 15 |
+
"@headlessui/react": "^2.2.0",
|
| 16 |
+
"@headlessui/tailwindcss": "^0.2.2",
|
| 17 |
+
"@huggingface/transformers": "^3.8.1",
|
| 18 |
+
"@icons-pack/react-simple-icons": "^12.3.0",
|
| 19 |
+
"@phosphor-icons/react": "^2.1.10",
|
| 20 |
+
"@radix-ui/react-tooltip": "^1.2.8",
|
| 21 |
+
"@tailwindcss/typography": "^0.5.12",
|
| 22 |
+
"@toolsycc/json-repair": "^0.1.22",
|
| 23 |
+
"axios": "^1.8.3",
|
| 24 |
+
"better-sqlite3": "^11.9.1",
|
| 25 |
+
"clsx": "^2.1.0",
|
| 26 |
+
"drizzle-orm": "^0.40.1",
|
| 27 |
+
"js-tiktoken": "^1.0.21",
|
| 28 |
+
"jspdf": "^3.0.4",
|
| 29 |
+
"lightweight-charts": "^5.0.9",
|
| 30 |
+
"lucide-react": "^0.556.0",
|
| 31 |
+
"mammoth": "^1.9.1",
|
| 32 |
+
"markdown-to-jsx": "^7.7.2",
|
| 33 |
+
"mathjs": "^15.1.0",
|
| 34 |
+
"motion": "^12.23.26",
|
| 35 |
+
"next": "^16.0.7",
|
| 36 |
+
"next-themes": "^0.3.0",
|
| 37 |
+
"officeparser": "^5.2.2",
|
| 38 |
+
"ollama": "^0.6.3",
|
| 39 |
+
"openai": "^6.9.0",
|
| 40 |
+
"partial-json": "^0.1.7",
|
| 41 |
+
"pdf-parse": "^2.4.5",
|
| 42 |
+
"react": "^18",
|
| 43 |
+
"react-dom": "^18",
|
| 44 |
+
"react-syntax-highlighter": "^16.1.0",
|
| 45 |
+
"react-text-to-speech": "^0.14.5",
|
| 46 |
+
"react-textarea-autosize": "^8.5.3",
|
| 47 |
+
"rfc6902": "^5.1.2",
|
| 48 |
+
"sonner": "^1.4.41",
|
| 49 |
+
"tailwind-merge": "^2.2.2",
|
| 50 |
+
"turndown": "^7.2.2",
|
| 51 |
+
"yahoo-finance2": "^3.10.2",
|
| 52 |
+
"yet-another-react-lightbox": "^3.17.2",
|
| 53 |
+
"zod": "^4.1.12"
|
| 54 |
+
},
|
| 55 |
+
"devDependencies": {
|
| 56 |
+
"@types/better-sqlite3": "^7.6.12",
|
| 57 |
+
"@types/jspdf": "^2.0.0",
|
| 58 |
+
"@types/node": "^24.8.1",
|
| 59 |
+
"@types/pdf-parse": "^1.1.4",
|
| 60 |
+
"@types/react": "^18",
|
| 61 |
+
"@types/react-dom": "^18",
|
| 62 |
+
"@types/react-syntax-highlighter": "^15.5.13",
|
| 63 |
+
"@types/turndown": "^5.0.6",
|
| 64 |
+
"autoprefixer": "^10.0.1",
|
| 65 |
+
"drizzle-kit": "^0.30.5",
|
| 66 |
+
"eslint": "^8",
|
| 67 |
+
"eslint-config-next": "14.1.4",
|
| 68 |
+
"postcss": "^8",
|
| 69 |
+
"prettier": "^3.2.5",
|
| 70 |
+
"tailwindcss": "^3.3.0",
|
| 71 |
+
"typescript": "^5.9.3"
|
| 72 |
+
},
|
| 73 |
+
"optionalDependencies": {
|
| 74 |
+
"@napi-rs/canvas": "^0.1.87"
|
| 75 |
+
}
|
| 76 |
+
}
|
postcss.config.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
plugins: {
|
| 3 |
+
tailwindcss: {},
|
| 4 |
+
autoprefixer: {},
|
| 5 |
+
},
|
| 6 |
+
};
|
public/fonts/pp-ed-ul.otf
ADDED
|
Binary file (57.8 kB). View file
|
|
|
public/icon-100.png
ADDED
|
|
public/icon-50.png
ADDED
|
|
public/icon.png
ADDED
|
|
public/next.svg
ADDED
|
|
public/screenshots/p1.png
ADDED
|
Git LFS Details
|
public/screenshots/p1_small.png
ADDED
|
Git LFS Details
|
public/screenshots/p2.png
ADDED
|
Git LFS Details
|
public/screenshots/p2_small.png
ADDED
|
Git LFS Details
|