Spaces:
Sleeping
Sleeping
fix: build local llama (#1805)
Browse files* fix: build local llama
* fix: node build local
* fix: docker build
* feat: use group for CI?
* fix: github actions
- .github/workflows/build-image.yml +4 -2
- Dockerfile +0 -1
- package-lock.json +28 -4
- package.json +3 -1
- src/lib/server/endpoints/local/utilsLocal.ts +0 -1
- src/lib/server/logger.ts +1 -1
- vite.config.ts +64 -0
.github/workflows/build-image.yml
CHANGED
|
@@ -19,7 +19,8 @@ on:
|
|
| 19 |
|
| 20 |
jobs:
|
| 21 |
build-and-publish-image-with-db:
|
| 22 |
-
runs-on:
|
|
|
|
| 23 |
steps:
|
| 24 |
- name: Checkout
|
| 25 |
uses: actions/checkout@v4
|
|
@@ -79,7 +80,8 @@ jobs:
|
|
| 79 |
INCLUDE_DB=true
|
| 80 |
PUBLIC_COMMIT_SHA=${{ env.GITHUB_SHA_SHORT }}
|
| 81 |
build-and-publish-image-nodb:
|
| 82 |
-
runs-on:
|
|
|
|
| 83 |
steps:
|
| 84 |
- name: Checkout
|
| 85 |
uses: actions/checkout@v4
|
|
|
|
| 19 |
|
| 20 |
jobs:
|
| 21 |
build-and-publish-image-with-db:
|
| 22 |
+
runs-on:
|
| 23 |
+
group: aws-general-8-plus
|
| 24 |
steps:
|
| 25 |
- name: Checkout
|
| 26 |
uses: actions/checkout@v4
|
|
|
|
| 80 |
INCLUDE_DB=true
|
| 81 |
PUBLIC_COMMIT_SHA=${{ env.GITHUB_SHA_SHORT }}
|
| 82 |
build-and-publish-image-nodb:
|
| 83 |
+
runs-on:
|
| 84 |
+
group: aws-general-8-plus
|
| 85 |
steps:
|
| 86 |
- name: Checkout
|
| 87 |
uses: actions/checkout@v4
|
Dockerfile
CHANGED
|
@@ -101,6 +101,5 @@ ENV MODELS_STORAGE_PATH=/data/models
|
|
| 101 |
#import the build & dependencies
|
| 102 |
COPY --from=builder --chown=1000 /app/build /app/build
|
| 103 |
COPY --from=builder --chown=1000 /app/node_modules /app/node_modules
|
| 104 |
-
COPY --from=builder --chown=1000 /app/node_modules/node-llama-cpp/llama /app/build/server/llama
|
| 105 |
|
| 106 |
CMD ["/bin/bash", "-c", "/app/entrypoint.sh"]
|
|
|
|
| 101 |
#import the build & dependencies
|
| 102 |
COPY --from=builder --chown=1000 /app/build /app/build
|
| 103 |
COPY --from=builder --chown=1000 /app/node_modules /app/node_modules
|
|
|
|
| 104 |
|
| 105 |
CMD ["/bin/bash", "-c", "/app/entrypoint.sh"]
|
package-lock.json
CHANGED
|
@@ -21,7 +21,7 @@
|
|
| 21 |
"aws-sigv4-fetch": "^4.0.1",
|
| 22 |
"aws4": "^1.13.0",
|
| 23 |
"date-fns": "^2.29.3",
|
| 24 |
-
"dotenv": "^16.0
|
| 25 |
"express": "^4.21.2",
|
| 26 |
"file-type": "^19.4.1",
|
| 27 |
"google-auth-library": "^9.13.0",
|
|
@@ -66,6 +66,7 @@
|
|
| 66 |
"@tailwindcss/typography": "^0.5.9",
|
| 67 |
"@types/dompurify": "^3.0.5",
|
| 68 |
"@types/express": "^4.17.21",
|
|
|
|
| 69 |
"@types/js-yaml": "^4.0.9",
|
| 70 |
"@types/jsdom": "^21.1.1",
|
| 71 |
"@types/jsonpath": "^0.2.4",
|
|
@@ -82,6 +83,7 @@
|
|
| 82 |
"eslint": "^8.28.0",
|
| 83 |
"eslint-config-prettier": "^8.5.0",
|
| 84 |
"eslint-plugin-svelte": "^2.45.1",
|
|
|
|
| 85 |
"isomorphic-dompurify": "^2.13.0",
|
| 86 |
"js-yaml": "^4.1.0",
|
| 87 |
"minimist": "^1.2.8",
|
|
@@ -5053,6 +5055,17 @@
|
|
| 5053 |
"resolved": "https://registry.npmjs.org/@types/firefox-webext-browser/-/firefox-webext-browser-120.0.4.tgz",
|
| 5054 |
"integrity": "sha512-lBrpf08xhiZBigrtdQfUaqX1UauwZ+skbFiL8u2Tdra/rklkKadYmIzTwkNZSWtuZ7OKpFqbE2HHfDoFqvZf6w=="
|
| 5055 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5056 |
"node_modules/@types/har-format": {
|
| 5057 |
"version": "1.2.15",
|
| 5058 |
"resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.15.tgz",
|
|
@@ -5087,6 +5100,16 @@
|
|
| 5087 |
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
| 5088 |
"dev": true
|
| 5089 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5090 |
"node_modules/@types/jsonpath": {
|
| 5091 |
"version": "0.2.4",
|
| 5092 |
"resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz",
|
|
@@ -7167,9 +7190,10 @@
|
|
| 7167 |
}
|
| 7168 |
},
|
| 7169 |
"node_modules/dotenv": {
|
| 7170 |
-
"version": "16.
|
| 7171 |
-
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.
|
| 7172 |
-
"integrity": "sha512-
|
|
|
|
| 7173 |
"engines": {
|
| 7174 |
"node": ">=12"
|
| 7175 |
},
|
|
|
|
| 21 |
"aws-sigv4-fetch": "^4.0.1",
|
| 22 |
"aws4": "^1.13.0",
|
| 23 |
"date-fns": "^2.29.3",
|
| 24 |
+
"dotenv": "^16.5.0",
|
| 25 |
"express": "^4.21.2",
|
| 26 |
"file-type": "^19.4.1",
|
| 27 |
"google-auth-library": "^9.13.0",
|
|
|
|
| 66 |
"@tailwindcss/typography": "^0.5.9",
|
| 67 |
"@types/dompurify": "^3.0.5",
|
| 68 |
"@types/express": "^4.17.21",
|
| 69 |
+
"@types/fs-extra": "^11.0.4",
|
| 70 |
"@types/js-yaml": "^4.0.9",
|
| 71 |
"@types/jsdom": "^21.1.1",
|
| 72 |
"@types/jsonpath": "^0.2.4",
|
|
|
|
| 83 |
"eslint": "^8.28.0",
|
| 84 |
"eslint-config-prettier": "^8.5.0",
|
| 85 |
"eslint-plugin-svelte": "^2.45.1",
|
| 86 |
+
"fs-extra": "^11.3.0",
|
| 87 |
"isomorphic-dompurify": "^2.13.0",
|
| 88 |
"js-yaml": "^4.1.0",
|
| 89 |
"minimist": "^1.2.8",
|
|
|
|
| 5055 |
"resolved": "https://registry.npmjs.org/@types/firefox-webext-browser/-/firefox-webext-browser-120.0.4.tgz",
|
| 5056 |
"integrity": "sha512-lBrpf08xhiZBigrtdQfUaqX1UauwZ+skbFiL8u2Tdra/rklkKadYmIzTwkNZSWtuZ7OKpFqbE2HHfDoFqvZf6w=="
|
| 5057 |
},
|
| 5058 |
+
"node_modules/@types/fs-extra": {
|
| 5059 |
+
"version": "11.0.4",
|
| 5060 |
+
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
|
| 5061 |
+
"integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==",
|
| 5062 |
+
"dev": true,
|
| 5063 |
+
"license": "MIT",
|
| 5064 |
+
"dependencies": {
|
| 5065 |
+
"@types/jsonfile": "*",
|
| 5066 |
+
"@types/node": "*"
|
| 5067 |
+
}
|
| 5068 |
+
},
|
| 5069 |
"node_modules/@types/har-format": {
|
| 5070 |
"version": "1.2.15",
|
| 5071 |
"resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.15.tgz",
|
|
|
|
| 5100 |
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
| 5101 |
"dev": true
|
| 5102 |
},
|
| 5103 |
+
"node_modules/@types/jsonfile": {
|
| 5104 |
+
"version": "6.1.4",
|
| 5105 |
+
"resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
|
| 5106 |
+
"integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==",
|
| 5107 |
+
"dev": true,
|
| 5108 |
+
"license": "MIT",
|
| 5109 |
+
"dependencies": {
|
| 5110 |
+
"@types/node": "*"
|
| 5111 |
+
}
|
| 5112 |
+
},
|
| 5113 |
"node_modules/@types/jsonpath": {
|
| 5114 |
"version": "0.2.4",
|
| 5115 |
"resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz",
|
|
|
|
| 7190 |
}
|
| 7191 |
},
|
| 7192 |
"node_modules/dotenv": {
|
| 7193 |
+
"version": "16.5.0",
|
| 7194 |
+
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
|
| 7195 |
+
"integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
|
| 7196 |
+
"license": "BSD-2-Clause",
|
| 7197 |
"engines": {
|
| 7198 |
"node": ">=12"
|
| 7199 |
},
|
package.json
CHANGED
|
@@ -27,6 +27,7 @@
|
|
| 27 |
"@tailwindcss/typography": "^0.5.9",
|
| 28 |
"@types/dompurify": "^3.0.5",
|
| 29 |
"@types/express": "^4.17.21",
|
|
|
|
| 30 |
"@types/js-yaml": "^4.0.9",
|
| 31 |
"@types/jsdom": "^21.1.1",
|
| 32 |
"@types/jsonpath": "^0.2.4",
|
|
@@ -43,6 +44,7 @@
|
|
| 43 |
"eslint": "^8.28.0",
|
| 44 |
"eslint-config-prettier": "^8.5.0",
|
| 45 |
"eslint-plugin-svelte": "^2.45.1",
|
|
|
|
| 46 |
"isomorphic-dompurify": "^2.13.0",
|
| 47 |
"js-yaml": "^4.1.0",
|
| 48 |
"minimist": "^1.2.8",
|
|
@@ -79,7 +81,7 @@
|
|
| 79 |
"aws-sigv4-fetch": "^4.0.1",
|
| 80 |
"aws4": "^1.13.0",
|
| 81 |
"date-fns": "^2.29.3",
|
| 82 |
-
"dotenv": "^16.0
|
| 83 |
"express": "^4.21.2",
|
| 84 |
"file-type": "^19.4.1",
|
| 85 |
"google-auth-library": "^9.13.0",
|
|
|
|
| 27 |
"@tailwindcss/typography": "^0.5.9",
|
| 28 |
"@types/dompurify": "^3.0.5",
|
| 29 |
"@types/express": "^4.17.21",
|
| 30 |
+
"@types/fs-extra": "^11.0.4",
|
| 31 |
"@types/js-yaml": "^4.0.9",
|
| 32 |
"@types/jsdom": "^21.1.1",
|
| 33 |
"@types/jsonpath": "^0.2.4",
|
|
|
|
| 44 |
"eslint": "^8.28.0",
|
| 45 |
"eslint-config-prettier": "^8.5.0",
|
| 46 |
"eslint-plugin-svelte": "^2.45.1",
|
| 47 |
+
"fs-extra": "^11.3.0",
|
| 48 |
"isomorphic-dompurify": "^2.13.0",
|
| 49 |
"js-yaml": "^4.1.0",
|
| 50 |
"minimist": "^1.2.8",
|
|
|
|
| 81 |
"aws-sigv4-fetch": "^4.0.1",
|
| 82 |
"aws4": "^1.13.0",
|
| 83 |
"date-fns": "^2.29.3",
|
| 84 |
+
"dotenv": "^16.5.0",
|
| 85 |
"express": "^4.21.2",
|
| 86 |
"file-type": "^19.4.1",
|
| 87 |
"google-auth-library": "^9.13.0",
|
src/lib/server/endpoints/local/utilsLocal.ts
CHANGED
|
@@ -28,7 +28,6 @@ export const llama = await getLlama({
|
|
| 28 |
break;
|
| 29 |
}
|
| 30 |
},
|
| 31 |
-
build: "never",
|
| 32 |
}).catch((e) => {
|
| 33 |
logger.warn(
|
| 34 |
e,
|
|
|
|
| 28 |
break;
|
| 29 |
}
|
| 30 |
},
|
|
|
|
| 31 |
}).catch((e) => {
|
| 32 |
logger.warn(
|
| 33 |
e,
|
src/lib/server/logger.ts
CHANGED
|
@@ -15,4 +15,4 @@ if (dev) {
|
|
| 15 |
};
|
| 16 |
}
|
| 17 |
|
| 18 |
-
export const logger = pino({ ...options, level: config.LOG_LEVEL
|
|
|
|
| 15 |
};
|
| 16 |
}
|
| 17 |
|
| 18 |
+
export const logger = pino({ ...options, level: config.LOG_LEVEL || "info" });
|
vite.config.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { sveltekit } from "@sveltejs/kit/vite";
|
|
| 2 |
import Icons from "unplugin-icons/vite";
|
| 3 |
import { promises } from "fs";
|
| 4 |
import { defineConfig } from "vitest/config";
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
// used to load fonts server side for thumbnail generation
|
| 7 |
function loadTTFAsArrayBuffer() {
|
|
@@ -16,6 +20,65 @@ function loadTTFAsArrayBuffer() {
|
|
| 16 |
},
|
| 17 |
};
|
| 18 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
export default defineConfig({
|
| 21 |
plugins: [
|
|
@@ -24,6 +87,7 @@ export default defineConfig({
|
|
| 24 |
compiler: "svelte",
|
| 25 |
}),
|
| 26 |
loadTTFAsArrayBuffer(),
|
|
|
|
| 27 |
],
|
| 28 |
optimizeDeps: {
|
| 29 |
include: ["uuid", "@huggingface/transformers", "sharp", "@gradio/client", "clsx"],
|
|
|
|
| 2 |
import Icons from "unplugin-icons/vite";
|
| 3 |
import { promises } from "fs";
|
| 4 |
import { defineConfig } from "vitest/config";
|
| 5 |
+
import { resolve } from "path";
|
| 6 |
+
import fs from "fs-extra";
|
| 7 |
+
import { spawn } from "child_process";
|
| 8 |
+
import type { Plugin } from "vite";
|
| 9 |
|
| 10 |
// used to load fonts server side for thumbnail generation
|
| 11 |
function loadTTFAsArrayBuffer() {
|
|
|
|
| 20 |
},
|
| 21 |
};
|
| 22 |
}
|
| 23 |
+
const isViteNode = process.argv.some((arg) => arg.includes("vite-node")) || !!process.env.VITE_NODE;
|
| 24 |
+
const shouldCopyLlama = process.env.npm_lifecycle_event === "build" && !isViteNode; // Copy node-llama-cpp/llama files to build output
|
| 25 |
+
|
| 26 |
+
function copyLlamaFiles() {
|
| 27 |
+
return {
|
| 28 |
+
name: "copy-llama-files",
|
| 29 |
+
apply: "build" as const,
|
| 30 |
+
closeBundle: async () => {
|
| 31 |
+
try {
|
| 32 |
+
// Run npx command first and pipe IO
|
| 33 |
+
console.log("Running node-llama-cpp source download...");
|
| 34 |
+
|
| 35 |
+
await new Promise((resolve, reject) => {
|
| 36 |
+
const npxProcess = spawn("npx", ["--no", "node-llama-cpp", "source", "download"], {
|
| 37 |
+
stdio: "inherit", // Pipe all IO to parent process
|
| 38 |
+
shell: true,
|
| 39 |
+
});
|
| 40 |
+
|
| 41 |
+
npxProcess.on("close", (code) => {
|
| 42 |
+
if (code === 0) {
|
| 43 |
+
console.log("✓ Successfully downloaded llama source files");
|
| 44 |
+
resolve(code);
|
| 45 |
+
} else {
|
| 46 |
+
reject(new Error(`npx command failed with code ${code}`));
|
| 47 |
+
}
|
| 48 |
+
});
|
| 49 |
+
|
| 50 |
+
npxProcess.on("error", (err) => {
|
| 51 |
+
reject(err);
|
| 52 |
+
});
|
| 53 |
+
});
|
| 54 |
+
|
| 55 |
+
const sourcePath = resolve("node_modules/node-llama-cpp/llama");
|
| 56 |
+
const destPath = resolve("build/server/llama");
|
| 57 |
+
|
| 58 |
+
// Ensure destination directory exists
|
| 59 |
+
await fs.ensureDir(destPath);
|
| 60 |
+
|
| 61 |
+
// Copy files - using a filter to prevent copying files to subdirectories of themselves
|
| 62 |
+
await fs.copy(sourcePath, destPath, {
|
| 63 |
+
filter: (src, dest) => {
|
| 64 |
+
// Skip if source path is inside destination path or vice versa
|
| 65 |
+
if (src.includes(destPath) || dest.includes(sourcePath)) {
|
| 66 |
+
console.log(`Skipping problematic copy: ${src} -> ${dest}`);
|
| 67 |
+
return false;
|
| 68 |
+
}
|
| 69 |
+
return true;
|
| 70 |
+
},
|
| 71 |
+
overwrite: true,
|
| 72 |
+
dereference: true,
|
| 73 |
+
});
|
| 74 |
+
|
| 75 |
+
console.log("✓ Successfully copied llama files to build output");
|
| 76 |
+
} catch (error) {
|
| 77 |
+
console.error("Error in llama files process:", error);
|
| 78 |
+
}
|
| 79 |
+
},
|
| 80 |
+
} satisfies Plugin;
|
| 81 |
+
}
|
| 82 |
|
| 83 |
export default defineConfig({
|
| 84 |
plugins: [
|
|
|
|
| 87 |
compiler: "svelte",
|
| 88 |
}),
|
| 89 |
loadTTFAsArrayBuffer(),
|
| 90 |
+
...(shouldCopyLlama ? [copyLlamaFiles()] : []),
|
| 91 |
],
|
| 92 |
optimizeDeps: {
|
| 93 |
include: ["uuid", "@huggingface/transformers", "sharp", "@gradio/client", "clsx"],
|