Add basic functionality
This commit is contained in:
@@ -1 +1,4 @@
|
||||
# Open-Wheight Modelle und ihre Anwendung
|
||||
# Open-Wheight Modelle und ihre Verwendung
|
||||
|
||||
# Quellen:
|
||||
https://vectorwiki.com/tools/embedding-visualizer
|
||||
Generated
+579
-9
@@ -8,15 +8,24 @@
|
||||
"name": "hausarbeit",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@lucide/vue": "^1.48.0",
|
||||
"@tailwindcss/vite": "^4.3.3",
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-opener": "^2",
|
||||
"@tauri-apps/plugin-http": "^2.6.1",
|
||||
"@tauri-apps/plugin-opener": "^2.6.0",
|
||||
"@tauri-apps/plugin-store": "^2.4.5",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"tailwind-merge": "^3.7.0",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"vue": "^3.5.13"
|
||||
"umap-js": "^1.4.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^5.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2",
|
||||
"@vitejs/plugin-vue": "^6.0.7",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "~6.0.3",
|
||||
"vite": "^8.0.16",
|
||||
"vue-tsc": "^3.3.5"
|
||||
@@ -113,6 +122,15 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@lucide/vue": {
|
||||
"version": "1.48.0",
|
||||
"resolved": "https://registry.npmjs.org/@lucide/vue/-/vue-1.48.0.tgz",
|
||||
"integrity": "sha512-3/Nwx/RsqQ4ZrrSML1GNsSWCSDyLnBgoF/eEr1q9G6iZymn3+WKtzIj7Dbc/Nxrt9WOPuGrJ58S+CBiamK+36w==",
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
"vue": ">=3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.151.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.151.0.tgz",
|
||||
@@ -875,9 +893,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/api": {
|
||||
"version": "2.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.11.1.tgz",
|
||||
"integrity": "sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==",
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.12.0.tgz",
|
||||
"integrity": "sha512-fUSxFX8VABYe9W9K5ROdEaKVkNUFRcMSRofjruvaxztXA+I0XnQHcYHF8m/a6iExRUxsUf0HsFWhPBuH9IgzJw==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -1101,10 +1119,28 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-http": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.6.1.tgz",
|
||||
"integrity": "sha512-9gtfe6eOaVKofASoMZ4Ph8E6vDYnpUTbMXrLt4FkXPzC5+O+wnGqJ9fz2koSPYcQt10bb3cx5qHkU0AU1l8tcQ==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-opener": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.5.5.tgz",
|
||||
"integrity": "sha512-xvzGai5aQds8j8R8RsUK/lW6pGG50YgOYIPLzvkqmkwAj7dfySOD7sGtejRzvVdMmv1EQfKVEFh1MvmDp8QR0g==",
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.6.0.tgz",
|
||||
"integrity": "sha512-KIl9qkBGyAUrbzfCtdk+NRPTXUOwpMyUKsKN57H6/qA0q8auVywXpfUyWClqX6I/iH8PHmqAUa/KK9YZPWVQew==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-store": {
|
||||
"version": "2.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-store/-/plugin-store-2.4.5.tgz",
|
||||
"integrity": "sha512-bVD9riKzf+WKYm1L8uXD1CMDTC/eaFS2Cbjcgq+39ahChtVGnyDCbzug3HpjgpZMw78yoAVMqHOAEjqJ/kD9YQ==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.11.0"
|
||||
@@ -1156,6 +1192,33 @@
|
||||
"vscode-uri": "^3.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue-macros/common": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue-macros/common/-/common-3.1.4.tgz",
|
||||
"integrity": "sha512-/5Fv+6DgIcM9ajY05ZmKBv+LMX1M9A0X+IUwDRVdt67ciw8OV9bvG2r34p3RiEadlsQybjhKPRKNXDC8Bp23cw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-sfc": "^3.5.22",
|
||||
"ast-kit": "^2.1.2",
|
||||
"local-pkg": "^1.1.2",
|
||||
"magic-string-ast": "^1.0.2",
|
||||
"unplugin-utils": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/vue-macros"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^2.7.0 || ^3.2.25"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.5.43",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.43.tgz",
|
||||
@@ -1206,6 +1269,33 @@
|
||||
"@vue/shared": "3.5.43"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-api": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.2.1.tgz",
|
||||
"integrity": "sha512-6u4vXBlIBAC1wMplIZgpyPn7uh/s4Bf6F5bMzvLv+EdJ0aHs/+4B7Ygv864EStQSjRbsRzTko/kUG1A1IejQ3A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-kit": "^8.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-kit": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.2.1.tgz",
|
||||
"integrity": "sha512-FIGIuq3AWReEpbAHY/cRGeHDfI0qOb8OCQ3YjbEAX04uaxIDbGc9rhkbVcG7rnfHPXE3RsU5KrWOu9V/okd8AQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-shared": "^8.2.1",
|
||||
"birpc": "^2.6.1",
|
||||
"hookable": "^5.5.3",
|
||||
"perfect-debounce": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-shared": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.2.1.tgz",
|
||||
"integrity": "sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/language-core": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.11.tgz",
|
||||
@@ -1270,6 +1360,18 @@
|
||||
"integrity": "sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
|
||||
"integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/alien-signals": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.2.1.tgz",
|
||||
@@ -1277,6 +1379,90 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ast-kit": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz",
|
||||
"integrity": "sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"pathe": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-walker-scope": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/ast-walker-scope/-/ast-walker-scope-0.9.0.tgz",
|
||||
"integrity": "sha512-IJdzo2vLiElBxKzwS36VsCue/62d6IdWjnPB2v3nuPKeWGynp6FF/CYoLa5i/3jXH/z97ZDdsXz6abpgM6w07A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.29.2",
|
||||
"@babel/types": "^7.29.0",
|
||||
"ast-kit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
},
|
||||
"node_modules/birpc": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz",
|
||||
"integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
||||
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/class-variance-authority": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
|
||||
"integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://polar.sh/cva"
|
||||
}
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/confbox": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz",
|
||||
"integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
@@ -1323,6 +1509,12 @@
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/exsolve": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.1.tgz",
|
||||
"integrity": "sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||
@@ -1360,6 +1552,18 @@
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/hookable": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
||||
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-any-array": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-0.1.1.tgz",
|
||||
"integrity": "sha512-qTiELO+kpTKqPgxPYbshMERlzaFu29JDnpB8s3bjg+JkxBpw29/qqSaOdKv2pCdaG92rLGeG/zG2GauX58hfoA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
|
||||
@@ -1618,6 +1822,23 @@
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/local-pkg": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.2.1.tgz",
|
||||
"integrity": "sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mlly": "^1.7.4",
|
||||
"pkg-types": "^2.3.0",
|
||||
"quansync": "^0.2.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
||||
@@ -1627,11 +1848,127 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string-ast": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/magic-string-ast/-/magic-string-ast-1.0.3.tgz",
|
||||
"integrity": "sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"magic-string": "^0.30.19"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
},
|
||||
"node_modules/ml-array-max": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ml-array-max/-/ml-array-max-2.0.0.tgz",
|
||||
"integrity": "sha512-QQZ4kENwpWmyNb98UXRDFXrmtIXuXtt1+bSbda/2KA85+F+rrJP8hZk6QOkCQXM2Th9mUDYdq/PNByPdT9ID4A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-any-array": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ml-array-max/node_modules/is-any-array": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-3.0.0.tgz",
|
||||
"integrity": "sha512-o4h+tylWykC4BD1vaejp6gDxoM13bwW8FGuNs4yIKpj8xbBJcRxJx8vZpq0dCr7ZDEfeKjmsi/euolKhX6f/ww==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ml-array-min": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ml-array-min/-/ml-array-min-2.0.0.tgz",
|
||||
"integrity": "sha512-GRj6Ky6sW9vGL6yIjgsHmXZ9YgrdmcQ8nCxPqEGeKc6dkfYg1XDYxGFxADUjNuZyoCd5PUscWAS4N+cFaX6hFg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-any-array": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ml-array-min/node_modules/is-any-array": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-3.0.0.tgz",
|
||||
"integrity": "sha512-o4h+tylWykC4BD1vaejp6gDxoM13bwW8FGuNs4yIKpj8xbBJcRxJx8vZpq0dCr7ZDEfeKjmsi/euolKhX6f/ww==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ml-array-rescale": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ml-array-rescale/-/ml-array-rescale-2.0.0.tgz",
|
||||
"integrity": "sha512-2GGtKfSno94/kIloWGvpp/U5Q5vLvLrza+SAaGsLeo6Xj4mEbA6Gqx+oTfZFkxnd1grT2X007HfJNs3T5BsiVg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-any-array": "^3.0.0",
|
||||
"ml-array-max": "^2.0.0",
|
||||
"ml-array-min": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ml-array-rescale/node_modules/is-any-array": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-3.0.0.tgz",
|
||||
"integrity": "sha512-o4h+tylWykC4BD1vaejp6gDxoM13bwW8FGuNs4yIKpj8xbBJcRxJx8vZpq0dCr7ZDEfeKjmsi/euolKhX6f/ww==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ml-levenberg-marquardt": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ml-levenberg-marquardt/-/ml-levenberg-marquardt-2.1.1.tgz",
|
||||
"integrity": "sha512-2+HwUqew4qFFFYujYlQtmFUrxCB4iJAPqnUYro3P831wj70eJZcANwcRaIMGUVaH9NDKzfYuA4N5u67KExmaRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-any-array": "^0.1.0",
|
||||
"ml-matrix": "^6.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ml-matrix": {
|
||||
"version": "6.15.0",
|
||||
"resolved": "https://registry.npmjs.org/ml-matrix/-/ml-matrix-6.15.0.tgz",
|
||||
"integrity": "sha512-wFa1v6KP8bKp+fj0nYmRs1Pb5K4zRkXGKsOvLinvILENFIADncm4XlOI+S1M7yuACMGfI6cfk0IifDgd4j5xmw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-any-array": "^3.0.0",
|
||||
"ml-array-rescale": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ml-matrix/node_modules/is-any-array": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-3.0.0.tgz",
|
||||
"integrity": "sha512-o4h+tylWykC4BD1vaejp6gDxoM13bwW8FGuNs4yIKpj8xbBJcRxJx8vZpq0dCr7ZDEfeKjmsi/euolKhX6f/ww==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mlly": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz",
|
||||
"integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.16.0",
|
||||
"pathe": "^2.0.3",
|
||||
"pkg-types": "^1.3.1",
|
||||
"ufo": "^1.6.3"
|
||||
}
|
||||
},
|
||||
"node_modules/mlly/node_modules/confbox": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mlly/node_modules/pkg-types": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
|
||||
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"confbox": "^0.1.8",
|
||||
"mlly": "^1.7.4",
|
||||
"pathe": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/muggle-string": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
|
||||
"integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
@@ -1652,6 +1989,12 @@
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/nostics": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/nostics/-/nostics-1.3.0.tgz",
|
||||
"integrity": "sha512-wzRsrJwNlFbqIRQt8aCeL2WE8USip/uuvGSOZV1D02CxX8ABTMbw8IywKjH7yWHETMXbWJI4OBpihg9rmz2Vyg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-browserify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
|
||||
@@ -1659,6 +2002,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pathe": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/perfect-debounce": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz",
|
||||
"integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@@ -1677,6 +2032,23 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-types": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.3.tgz",
|
||||
"integrity": "sha512-j/lCFdcppV0JxWpCEITdbDltBxPP6cHT+yNJ6Go2OgoSA9518X847X9z0p6LtA4Nc16+eQzCZjRrWanTGvHJ5w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"confbox": "^0.3.1",
|
||||
"exsolve": "^1.1.1",
|
||||
"pathe": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-types/node_modules/confbox": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.3.1.tgz",
|
||||
"integrity": "sha512-cKUSoKa8YxFZZSmraVi7onONx3amu77ngK3kGpsYHDH7drPwCRkQE1RYMPlLRrMtnciRj274XNRxcHxnKmDSnA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.28",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
|
||||
@@ -1705,6 +2077,35 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/quansync": {
|
||||
"version": "0.2.11",
|
||||
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
|
||||
"integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz",
|
||||
"integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.2.11",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.11.tgz",
|
||||
@@ -1738,6 +2139,12 @@
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.11"
|
||||
}
|
||||
},
|
||||
"node_modules/scule": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz",
|
||||
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
@@ -1747,6 +2154,16 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwind-merge": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.7.0.tgz",
|
||||
"integrity": "sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/dcastil"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz",
|
||||
@@ -1782,6 +2199,16 @@
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/tw-animate-css": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz",
|
||||
"integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Wombosvideo"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
|
||||
@@ -1796,6 +2223,95 @@
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/ufo": {
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz",
|
||||
"integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/umap-js": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/umap-js/-/umap-js-1.4.0.tgz",
|
||||
"integrity": "sha512-xxpviF9wUO6Nxrx+C58SoDgea+h2PnVaRPKDelWv0HotmY6BeWeh0kAPJoumfqUkzUvowGsYfMbnsWI0b9do+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ml-levenberg-marquardt": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.4.0.tgz",
|
||||
"integrity": "sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"picomatch": "^4.0.7",
|
||||
"webpack-virtual-modules": "^0.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@farmfe/core": "*",
|
||||
"@rsbuild/core": "*",
|
||||
"@rspack/core": "*",
|
||||
"bun-types-no-globals": "*",
|
||||
"esbuild": "*",
|
||||
"rolldown": "*",
|
||||
"rollup": "*",
|
||||
"unloader": "*",
|
||||
"vite": "*",
|
||||
"webpack": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@farmfe/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@rsbuild/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@rspack/core": {
|
||||
"optional": true
|
||||
},
|
||||
"bun-types-no-globals": {
|
||||
"optional": true
|
||||
},
|
||||
"esbuild": {
|
||||
"optional": true
|
||||
},
|
||||
"rolldown": {
|
||||
"optional": true
|
||||
},
|
||||
"rollup": {
|
||||
"optional": true
|
||||
},
|
||||
"unloader": {
|
||||
"optional": true
|
||||
},
|
||||
"vite": {
|
||||
"optional": true
|
||||
},
|
||||
"webpack": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-utils": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.2.tgz",
|
||||
"integrity": "sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pathe": "^2.0.3",
|
||||
"picomatch": "^4.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "8.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.1.tgz",
|
||||
@@ -1901,6 +2417,54 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.3.1.tgz",
|
||||
"integrity": "sha512-GDBZzgmILxA/kFnkFbJjQZdZ2QQbngnIMMuoUcjhZIfH1RGMaPjPwX5ASnV38qamuA9uhO0RDjSBHTDNG2uXyQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue-macros/common": "^3.1.3",
|
||||
"@vue/devtools-api": "^8.1.5",
|
||||
"ast-walker-scope": "^0.9.0",
|
||||
"chokidar": "^5.0.0",
|
||||
"confbox": "^0.2.4",
|
||||
"local-pkg": "^1.2.1",
|
||||
"magic-string": "^0.30.21",
|
||||
"mlly": "^1.8.2",
|
||||
"muggle-string": "^0.4.1",
|
||||
"nostics": "^1.1.4",
|
||||
"pathe": "^2.0.3",
|
||||
"picomatch": "^4.0.5",
|
||||
"scule": "^1.3.0",
|
||||
"tinyglobby": "^0.2.17",
|
||||
"unplugin": "^3.3.0",
|
||||
"unplugin-utils": "^0.3.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@pinia/colada": ">=0.21.2",
|
||||
"@vue/compiler-sfc": "^3.5.34 || ^4.0.0",
|
||||
"pinia": "^3.0.4 || ^4.0.2",
|
||||
"vite": "^7.3.0 || ^8.0.0",
|
||||
"vue": "^3.5.34 || ^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@pinia/colada": {
|
||||
"optional": true
|
||||
},
|
||||
"@vue/compiler-sfc": {
|
||||
"optional": true
|
||||
},
|
||||
"pinia": {
|
||||
"optional": true
|
||||
},
|
||||
"vite": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.11.tgz",
|
||||
@@ -1917,6 +2481,12 @@
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-virtual-modules": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-2
@@ -10,15 +10,24 @@
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lucide/vue": "^1.48.0",
|
||||
"@tailwindcss/vite": "^4.3.3",
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-opener": "^2",
|
||||
"@tauri-apps/plugin-http": "^2.6.1",
|
||||
"@tauri-apps/plugin-opener": "^2.6.0",
|
||||
"@tauri-apps/plugin-store": "^2.4.5",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"tailwind-merge": "^3.7.0",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"vue": "^3.5.13"
|
||||
"umap-js": "^1.4.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^5.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2",
|
||||
"@vitejs/plugin-vue": "^6.0.7",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "~6.0.3",
|
||||
"vite": "^8.0.16",
|
||||
"vue-tsc": "^3.3.5"
|
||||
|
||||
Generated
+1076
-253
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,10 @@ tauri = { version = "2", features = [] }
|
||||
tauri-plugin-opener = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
ollama-rs = { version = "0.3.6", features= ["headers", "stream", "modelfile"] }
|
||||
tauri-plugin-store = "2"
|
||||
tokio = "1.53.1"
|
||||
tauri-plugin-http = "2"
|
||||
|
||||
|
||||
# Read the optimization guideline for more details: https://tauri.app/concept/size/#cargo-configuration
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Capability for the main window",
|
||||
"windows": ["main"],
|
||||
"windows": [
|
||||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"opener:default"
|
||||
"opener:default",
|
||||
"store:default",
|
||||
"http:default"
|
||||
]
|
||||
}
|
||||
+88
-1
@@ -1,3 +1,81 @@
|
||||
use ollama_rs::generation::completion::GenerationResponse;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::{io, sync::RwLock};
|
||||
use std::sync::Arc;
|
||||
use tauri_plugin_http::reqwest;
|
||||
|
||||
use ollama_rs::generation::completion::request::GenerationRequest;
|
||||
use ollama_rs::{Ollama, generation::{embeddings::request::GenerateEmbeddingsRequest}, models::{LocalModel, ModelOptions, ModelInfo, create::CreateModelRequest}};
|
||||
use tauri::{State, Url, Manager};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct OllamaState (pub Arc<RwLock<Option<Ollama>>>);
|
||||
|
||||
#[tauri::command]
|
||||
async fn connect_ollama(url: String, api_key: String, ollama_state: State<'_, OllamaState>) -> Result<(),String>{
|
||||
let url_parsed=Url::from_str(&url).map_err(|e|e.to_string())?;
|
||||
let mut headers=reqwest::header::HeaderMap::new();
|
||||
headers.insert("Authorization",reqwest::header::HeaderValue::from_str(&format!("Bearer {api_key}")).map_err(|e|e.to_string())?);
|
||||
let ollama_instance=Ollama::builder().url(url_parsed).request_headers(headers).build();
|
||||
|
||||
*(*ollama_state).0.write().await = Some(ollama_instance);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn prompt_embedding(ollama_state: State<'_,OllamaState>, model: String, prompt: String) -> Result<Vec<f32>,String>{
|
||||
let guard=(*ollama_state).0.read().await;
|
||||
let ollama=guard.as_ref().ok_or_else(|| "Ollama wurde nicht initialisiert")?;
|
||||
let generate_request=GenerateEmbeddingsRequest::new(model,prompt.into());
|
||||
let result=ollama.generate_embeddings(generate_request).await.map_err(|e|e.to_string())?;
|
||||
if result.embeddings.get(0).is_some(){
|
||||
return Ok(result.embeddings.get(0).unwrap().to_vec());
|
||||
}
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
async fn get_models(ollama_state: State<'_,OllamaState>) -> Result<Vec<LocalModel>,String>{
|
||||
let guard=(*ollama_state).0.read().await;
|
||||
let ollama=guard.as_ref().ok_or_else(|| "Ollama wurde nicht initialisiert")?;
|
||||
Ok(ollama.list_local_models().await.map_err(|e|e.to_string())?)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct MyGenerationResponse {
|
||||
pub response: String,
|
||||
pub thinking: Option<String>
|
||||
}
|
||||
|
||||
impl From<GenerationResponse> for MyGenerationResponse {
|
||||
fn from(arg: GenerationResponse) -> Self {
|
||||
MyGenerationResponse { response: arg.response, thinking: arg.thinking }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn prompt_normal(ollama_state: State<'_,OllamaState>, model:String, prompt: String, thinking: bool, temperature: f32) -> Result<MyGenerationResponse,String>{
|
||||
let guard=(*ollama_state).0.read().await;
|
||||
let ollama=guard.as_ref().ok_or_else(|| "Ollama wurde nicht initialisiert")?;
|
||||
let options=ModelOptions::default().temperature(temperature);
|
||||
Ok(ollama.generate(GenerationRequest::new(model,prompt).options(options).think(thinking)).await.map_err(|e|e.to_string())?.into())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn get_model_info(ollama_state: State<'_,OllamaState>, model:String) -> Result<ModelInfo,String>{
|
||||
let guard=(*ollama_state).0.read().await;
|
||||
let ollama=guard.as_ref().ok_or_else(|| "Ollama wurde nicht initialisiert")?;
|
||||
Ok(ollama.show_model_info(model).await.map_err(|e|e.to_string())?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn create_model(ollama_state: State<'_,OllamaState>, from_model:String, system_prompt: String, template: String, new_model: String) -> Result<String,String>{
|
||||
let guard=(*ollama_state).0.read().await;
|
||||
let ollama=guard.as_ref().ok_or_else(|| "Ollama wurde nicht initialisiert")?;
|
||||
Ok(ollama.create_model(CreateModelRequest::new(new_model).from_model(from_model).system(system_prompt).template(template)).await.map_err(|e|e.to_string())?.message)
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
@@ -8,9 +86,18 @@ pub fn run() {
|
||||
std::env::set_var("WEBKIT_DISABLE_COMPOSITING_MODE", "1");
|
||||
}
|
||||
|
||||
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.invoke_handler(tauri::generate_handler![])
|
||||
.setup(|app| {
|
||||
let handle=app.handle();
|
||||
let ollama_state: OllamaState = OllamaState(Arc::new(RwLock::new(None)));
|
||||
handle.manage(ollama_state);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![connect_ollama, get_model_info, prompt_embedding, get_models, prompt_normal, create_model])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
+52
@@ -1,5 +1,57 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import Input from './components/Input.vue';
|
||||
import {load, Store} from "@tauri-apps/plugin-store";
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
|
||||
const initialized = ref(false);
|
||||
const ollama_url = ref("");
|
||||
const ollama_api_key = ref("");
|
||||
|
||||
const home_page=ref(false);
|
||||
|
||||
async function submit(ev){
|
||||
ev.preventDefault();
|
||||
await store.set("url",ollama_url.value);
|
||||
await store.set("api-key",ollama_api_key.value);
|
||||
await store.save();
|
||||
try {
|
||||
await invoke("connect_ollama",{url: ollama_url.value, apiKey: ollama_api_key.value});
|
||||
} catch(e){
|
||||
window.alert("Verbindung nicht möglich: "+e);
|
||||
return;
|
||||
}
|
||||
home_page.value=true;
|
||||
}
|
||||
let store: Store;
|
||||
|
||||
async function init(){
|
||||
store = await load('store.json', { autoSave: false });
|
||||
if (await store.has("url")){
|
||||
ollama_url.value=await store.get("url");
|
||||
}
|
||||
if (await store.has("api-key")){
|
||||
ollama_api_key.value=await store.get("api-key");
|
||||
}
|
||||
initialized.value=true;
|
||||
}
|
||||
init();
|
||||
</script>
|
||||
<template>
|
||||
<main class="w-screen h-screen overflow-hidden flex items-center justify-center p-10" v-if="initialized">
|
||||
<div class="w-full h-full border rounded-2xl transition-all ease-in-out duration-200 p-6 overflow-y-scroll">
|
||||
<div v-if="!home_page">
|
||||
<h1>Moin!</h1>
|
||||
<p>Mit dieser App kannst du verschiedene Modelle über die Ollama API ausprobieren und vergleichen.</p>
|
||||
<form @submit="submit">
|
||||
<Input placeholder="Ollama URL (z.B. http://localhost:11434)" class="w-full" v-model="ollama_url"/> <br>
|
||||
<Input placeholder="API Key (optional)" class="w-full" type="password" v-model="ollama_api_key"/> <br>
|
||||
<br>
|
||||
<input value="Weiter" class="w-full border" type="submit"/>
|
||||
</form>
|
||||
</div>
|
||||
<RouterView v-else/>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</template>
|
||||
@@ -1 +1 @@
|
||||
@import "tailwindcss";
|
||||
@import "tailwindcss"
|
||||
@@ -0,0 +1,7 @@
|
||||
<script setup lang="ts"></script>
|
||||
<template>
|
||||
<RouterLink to="/">Zurück zur Startseite</RouterLink>
|
||||
<h1>Context Window einstellen</h1>
|
||||
Das Context Window muss beim Start des Ollama Servers als Environment-Variable gesetzt werden. Mehr Informationen <a href="https://docs.ollama.com/context-length" target="_blank" class="underline text-blue-700">hier.</a>
|
||||
|
||||
</template>
|
||||
@@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const initialized=ref(false);
|
||||
const models=ref([]);
|
||||
const model=ref("");
|
||||
const new_model=ref("");
|
||||
const information=ref(undefined);
|
||||
const system_prompt=ref("");
|
||||
|
||||
async function init(){
|
||||
models.value=await invoke("get_models");
|
||||
|
||||
initialized.value=true;
|
||||
}
|
||||
init();
|
||||
|
||||
async function load_model(localmodel){
|
||||
model.value=localmodel;
|
||||
let info;
|
||||
try{
|
||||
info=await invoke("get_model_info",{model: model.value});
|
||||
} catch(e){
|
||||
window.alert("Das funktioniert mit diesem Modell leider nicht.");
|
||||
return
|
||||
}
|
||||
|
||||
information.value={parameters: info.parameters, template: info.template}
|
||||
|
||||
console.log(information.value)
|
||||
}
|
||||
|
||||
async function save(){
|
||||
|
||||
try {
|
||||
window.alert("Antwort von Ollama: " + await invoke("create_model",{fromModel: model.value, template: information.value.template, systemPrompt: system_prompt.value, newModel: new_model.value}))
|
||||
} catch(e){
|
||||
window.alert("Das hat nicht geklappt. Fehlermeldung: "+e)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<RouterLink to="/">Zurück zur Startseite</RouterLink>
|
||||
<h1>Modell bearbeiten</h1>
|
||||
<p>Diese Funktion ist leider nicht für alle Modelle verfügbar.</p>
|
||||
<div v-if="initialized">
|
||||
<ul v-if="information==undefined">
|
||||
<li @click="load_model(model.name)" v-for="model in models">{{ model.name }}</li>
|
||||
</ul>
|
||||
<form v-else @submit.prevent="save">
|
||||
<button @click="information=undefined">Zurück zur Modellauswahl</button>
|
||||
<textarea v-model="information.template" placeholder="Prompt Template" class="w-full"></textarea>
|
||||
<textarea v-model="system_prompt" placeholder="System Prompt" class="w-full"></textarea>
|
||||
<input type="text" placeholder="Neuer Modellname" v-model="new_model">
|
||||
<input type="submit" value="Speichern"/>
|
||||
</form>
|
||||
</div>
|
||||
<div v-else>
|
||||
Rufe die Liste der Modelle bei Ollama ab...
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import EmbeddingVisualizer from './EmbeddingVisualizer.vue';
|
||||
import PromptInput from './PromptInput.vue';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
|
||||
const dataset=ref([]);
|
||||
|
||||
const model = ref("");
|
||||
const model_options = ref([]);
|
||||
const prompt = ref("");
|
||||
|
||||
async function execute_prompt(ev){
|
||||
ev.preventDefault();
|
||||
let embedding;
|
||||
try{
|
||||
embedding=await invoke("prompt_embedding",{model: model.value, prompt: prompt.value});
|
||||
}catch(e){
|
||||
window.alert("Fehler beim Ausführen des Prompts: "+e);
|
||||
}
|
||||
if(embedding!=undefined){
|
||||
dataset.value.push({vector: embedding, label: prompt.value});
|
||||
prompt.value="";
|
||||
}
|
||||
}
|
||||
|
||||
async function init(){
|
||||
model_options.value=await invoke("get_models")
|
||||
}
|
||||
init();
|
||||
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<RouterLink to="/">Zurück zur Startseite</RouterLink>
|
||||
<EmbeddingVisualizer :dataset="dataset"/>
|
||||
<select class="w-[500px]" v-model="model">
|
||||
<option value="" disabled></option>
|
||||
<option :value="m.name" v-for="m in model_options">{{ m.name }}</option>
|
||||
</select>
|
||||
<button class="border ml-2" @click="dataset=[]">Punkte löschen</button>
|
||||
<form @submit="execute_prompt">
|
||||
<PromptInput v-model="prompt"/>
|
||||
</form>
|
||||
</template>
|
||||
@@ -0,0 +1,153 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UMAP } from 'umap-js';
|
||||
import { onMounted, ref, useTemplateRef, watch } from "vue";
|
||||
const canvas = useTemplateRef("canvas");
|
||||
|
||||
const {dataset} = defineProps({
|
||||
dataset: {
|
||||
type: Array<{vector: Array<number>, label: String}>,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
// Simple PCA-like projection
|
||||
function project(data) {
|
||||
if (data.length === 0) return [];
|
||||
|
||||
const vectors = data.map((d) => d.vector);
|
||||
const dims = vectors[0].length;
|
||||
|
||||
// Center the data
|
||||
const means = Array(dims).fill(0);
|
||||
vectors.forEach((v) => v.forEach((val, i) => (means[i] += val)));
|
||||
means.forEach((m, i) => (means[i] = m / vectors.length));
|
||||
|
||||
const centered = vectors.map((v) => v.map((val, i) => val - means[i]));
|
||||
|
||||
// Simple projection using first two "principal" directions
|
||||
// (This is a simplified version - real PCA would compute eigenvectors)
|
||||
const proj = centered.map((v) => {
|
||||
const x = v.reduce(
|
||||
(sum, val, i) => sum + val * (i % 2 === 0 ? 1 : -0.5),
|
||||
0,
|
||||
);
|
||||
const y = v.reduce(
|
||||
(sum, val, i) => sum + val * (i % 2 === 1 ? 1 : -0.5),
|
||||
0,
|
||||
);
|
||||
return [x, y];
|
||||
});
|
||||
|
||||
// Normalize to [0, 1]
|
||||
const minX = Math.min(...proj.map((p) => p[0]));
|
||||
const maxX = Math.max(...proj.map((p) => p[0]));
|
||||
const minY = Math.min(...proj.map((p) => p[1]));
|
||||
const maxY = Math.max(...proj.map((p) => p[1]));
|
||||
|
||||
const rangeX = maxX - minX || 1;
|
||||
const rangeY = maxY - minY || 1;
|
||||
|
||||
return proj.map((p) => [(p[0] - minX) / rangeX, (p[1] - minY) / rangeY]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function draw(ctx, width, height, pointSize, showConnections, showLabels, points) {
|
||||
let projected=project(points);
|
||||
|
||||
const padding = 50;
|
||||
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
|
||||
// Draw grid
|
||||
ctx.strokeStyle = document.documentElement.classList.contains("dark")
|
||||
? "#374151"
|
||||
: "#e5e7eb";
|
||||
ctx.lineWidth = 1;
|
||||
for (let i = 0; i <= 10; i++) {
|
||||
const x = padding + ((width - 2 * padding) * i) / 10;
|
||||
const y = padding + ((height - 2 * padding) * i) / 10;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, padding);
|
||||
ctx.lineTo(x, height - padding);
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding, y);
|
||||
ctx.lineTo(width - padding, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// Draw connections to nearest neighbors
|
||||
if (showConnections && projected.length > 1) {
|
||||
ctx.strokeStyle = "#94a3b8";
|
||||
ctx.lineWidth = 1;
|
||||
projected.forEach((p, i) => {
|
||||
// Find nearest neighbor
|
||||
let minDist = Infinity;
|
||||
let nearest = -1;
|
||||
projected.forEach((q, j) => {
|
||||
if (i !== j) {
|
||||
const dist = Math.hypot(p[0] - q[0], p[1] - q[1]);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
nearest = j;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (nearest >= 0) {
|
||||
const x1 = padding + p[0] * (width - 2 * padding);
|
||||
const y1 = padding + p[1] * (height - 2 * padding);
|
||||
const x2 = padding + projected[nearest][0] * (width - 2 * padding);
|
||||
const y2 = padding + projected[nearest][1] * (height - 2 * padding);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x1, y1);
|
||||
ctx.lineTo(x2, y2);
|
||||
ctx.stroke();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Draw points
|
||||
projected.forEach((p, i) => {
|
||||
const x = padding + p[0] * (width - 2 * padding);
|
||||
const y = padding + p[1] * (height - 2 * padding);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, pointSize, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Draw labels
|
||||
if (showLabels) {
|
||||
ctx.fillStyle = document.documentElement.classList.contains("dark")
|
||||
? "#e5e7eb"
|
||||
: "#374151";
|
||||
ctx.font = "12px Inter, sans-serif";
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(points[i].label, x, y - pointSize - 5);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
let ctx;
|
||||
|
||||
watch(()=>dataset, async (old_value, new_value)=>{
|
||||
draw(ctx,500,500,3,false,true, new_value);
|
||||
}, {deep: true});
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
ctx=canvas.value.getContext("2d");
|
||||
draw(ctx,500,500,3,false,true, dataset);
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<canvas ref="canvas" class="w-[500px] h-[500px] border border-gray-200 rounded-lg bg-gray-50" width="500" height="500"></canvas>
|
||||
</template>
|
||||
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
<template>
|
||||
<main>
|
||||
<h1>Home</h1>
|
||||
<RouterLink to="/pull">Modelle runterladen</RouterLink> <br>
|
||||
<RouterLink to="/embedding">Embedding-Modelle</RouterLink> <br>
|
||||
<RouterLink to="/normal">"Normale" Modelle</RouterLink> <br>
|
||||
<RouterLink to="/context">Context Window einstellen</RouterLink> <br>
|
||||
<RouterLink to="/edit">Modell bearbeiten</RouterLink> <br>
|
||||
</main>
|
||||
</template>
|
||||
@@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
const model=defineModel();
|
||||
const {placeholder, type} = defineProps({
|
||||
"placeholder": {
|
||||
type: String
|
||||
},
|
||||
"type": {
|
||||
type: String
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<input :placeholder="placeholder" v-model="model" :type="type" class="border rounded-md my-1"/>
|
||||
</template>
|
||||
@@ -0,0 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import Input from './Input.vue';
|
||||
let {placeholder} = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "Prompt"
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Input class="rounded-full w-full border-2 p-4 text-xl" :placeholder="placeholder"/>
|
||||
</template>
|
||||
@@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import PromptInput from './PromptInput.vue';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
|
||||
|
||||
const prompt=ref("");
|
||||
const response=ref("");
|
||||
const thinking_response=ref("");
|
||||
const model=ref("");
|
||||
const model_options=ref([]);
|
||||
const thinking=ref(true);
|
||||
const temperature=ref(0.2);
|
||||
|
||||
|
||||
async function submit(ev){
|
||||
ev.preventDefault();
|
||||
response.value="Generiere eine Antwort..."
|
||||
thinking_response.value="";
|
||||
|
||||
try {
|
||||
let output:any=await invoke("prompt_normal",{model: model.value, prompt: prompt.value, thinking: thinking.value, temperature: temperature.value});
|
||||
response.value=output.response;
|
||||
thinking_response.value=output.thinking;
|
||||
}catch(e){
|
||||
window.alert("Fehler beim Generieren der Antwort: "+e);
|
||||
}
|
||||
|
||||
prompt.value="";
|
||||
|
||||
}
|
||||
|
||||
|
||||
async function init(){
|
||||
model_options.value=await invoke("get_models");
|
||||
}
|
||||
init();
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<RouterLink to="/">Zurück zur Startseite</RouterLink>
|
||||
<br>
|
||||
<br>
|
||||
<i class="whitespace-pre-line">{{ thinking_response }}</i> <br>
|
||||
<br>
|
||||
<div class="whitespace-pre-line">{{ response }}</div>
|
||||
<br>
|
||||
|
||||
<form @submit="submit">
|
||||
|
||||
<select class="w-[500px]" v-model="model">
|
||||
<option value="" disabled></option>
|
||||
<option :value="m.name" v-for="m in model_options">{{ m.name }}</option>
|
||||
</select>
|
||||
Thinking: <input type="checkbox" v-model="thinking">
|
||||
Temperature: <input type="number" v-model="temperature" max="1" min="0" step="0.01" class="w-16 border">
|
||||
<PromptInput v-model="prompt"/>
|
||||
<input type="submit" value="Antwort generieren" class="border rounded-md p-2 cursor-pointer">
|
||||
</form>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { openUrl } from '@tauri-apps/plugin-opener';
|
||||
</script>
|
||||
<template>
|
||||
<RouterLink to="/">Zurück zur Startseite</RouterLink>
|
||||
<br><br>
|
||||
Gehe auf <span class="text-blue-600 underline cursor-pointer" @click="openUrl('https://ollama.com/search')">https://ollama.com/search</span> und suche dir das Modell, was du haben möchtest, raus. <br>
|
||||
Dann öffne ein Terminal und führe "ollama pull {modellname}" aus.
|
||||
</template>
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import "./assets/style.css"
|
||||
import router from "./router"
|
||||
|
||||
createApp(App).mount("#app");
|
||||
createApp(App)
|
||||
.use(router)
|
||||
.mount("#app");
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
import HomeView from '../components/HomeView.vue'
|
||||
import EmbeddingPrompt from '../components/EmbeddingPrompt.vue'
|
||||
import PullModelsView from '../components/PullModelsView.vue'
|
||||
import PromptView from '../components/PromptView.vue'
|
||||
import ContextView from '../components/ContextView.vue'
|
||||
import EditView from '../components/EditView.vue'
|
||||
|
||||
const routes = [
|
||||
{ path: '/', component: HomeView },
|
||||
{ path: '/normal', component: PromptView },
|
||||
{ path: '/pull', component: PullModelsView },
|
||||
{ path: '/embedding', component: EmbeddingPrompt },
|
||||
{ path: '/context', component: ContextView },
|
||||
{ path: '/edit', component: EditView },
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
})
|
||||
|
||||
export default router
|
||||
+10
-5
@@ -15,11 +15,16 @@
|
||||
"jsx": "preserve",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"strict": false,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noFallthroughCasesInSwitch": false,
|
||||
|
||||
"paths": {
|
||||
"@/*": ["/src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
"references": [{ "path": "./tsconfig.node.json" }],
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user