forked from open-webui/open-webui
		
	Merge pull request #407 from anuraagdjain/feat/parallel-model-downloads
feat: parallel model downloads
This commit is contained in:
		
						commit
						ed4b3e0b32
					
				
					 4 changed files with 152 additions and 552 deletions
				
			
		
							
								
								
									
										452
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										452
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -9,6 +9,7 @@ | ||||||
| 			"version": "0.0.1", | 			"version": "0.0.1", | ||||||
| 			"dependencies": { | 			"dependencies": { | ||||||
| 				"@sveltejs/adapter-node": "^1.3.1", | 				"@sveltejs/adapter-node": "^1.3.1", | ||||||
|  | 				"async": "^3.2.5", | ||||||
| 				"dayjs": "^1.11.10", | 				"dayjs": "^1.11.10", | ||||||
| 				"file-saver": "^2.0.5", | 				"file-saver": "^2.0.5", | ||||||
| 				"highlight.js": "^11.9.0", | 				"highlight.js": "^11.9.0", | ||||||
|  | @ -76,51 +77,6 @@ | ||||||
| 				"node": ">=6.0.0" | 				"node": ">=6.0.0" | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 		"node_modules/@esbuild/android-arm": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"arm" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"android" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/android-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"arm64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"android" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/android-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"android" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/darwin-arm64": { | 		"node_modules/@esbuild/darwin-arm64": { | ||||||
| 			"version": "0.18.20", | 			"version": "0.18.20", | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", | 			"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", | ||||||
|  | @ -136,276 +92,6 @@ | ||||||
| 				"node": ">=12" | 				"node": ">=12" | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 		"node_modules/@esbuild/darwin-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"darwin" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/freebsd-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"arm64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"freebsd" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/freebsd-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"freebsd" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-arm": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"arm" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"arm64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-ia32": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"ia32" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-loong64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"loong64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-mips64el": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"mips64el" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-ppc64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"ppc64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-riscv64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"riscv64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-s390x": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"s390x" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/linux-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"linux" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/netbsd-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"netbsd" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/openbsd-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"openbsd" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/sunos-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"sunos" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/win32-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"arm64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"win32" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/win32-ia32": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"ia32" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"win32" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@esbuild/win32-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", |  | ||||||
| 			"cpu": [ |  | ||||||
| 				"x64" |  | ||||||
| 			], |  | ||||||
| 			"optional": true, |  | ||||||
| 			"os": [ |  | ||||||
| 				"win32" |  | ||||||
| 			], |  | ||||||
| 			"engines": { |  | ||||||
| 				"node": ">=12" |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		"node_modules/@eslint-community/eslint-utils": { | 		"node_modules/@eslint-community/eslint-utils": { | ||||||
| 			"version": "4.4.0", | 			"version": "4.4.0", | ||||||
| 			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", | 			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", | ||||||
|  | @ -1250,6 +936,11 @@ | ||||||
| 				"node": ">=8" | 				"node": ">=8" | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
|  | 		"node_modules/async": { | ||||||
|  | 			"version": "3.2.5", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", | ||||||
|  | 			"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" | ||||||
|  | 		}, | ||||||
| 		"node_modules/autoprefixer": { | 		"node_modules/autoprefixer": { | ||||||
| 			"version": "10.4.16", | 			"version": "10.4.16", | ||||||
| 			"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", | 			"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", | ||||||
|  | @ -4022,138 +3713,12 @@ | ||||||
| 				"@jridgewell/trace-mapping": "^0.3.9" | 				"@jridgewell/trace-mapping": "^0.3.9" | ||||||
| 			} | 			} | ||||||
| 		}, | 		}, | ||||||
| 		"@esbuild/android-arm": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/android-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/android-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/darwin-arm64": { | 		"@esbuild/darwin-arm64": { | ||||||
| 			"version": "0.18.20", | 			"version": "0.18.20", | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", | 			"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", | ||||||
| 			"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", | 			"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", | ||||||
| 			"optional": true | 			"optional": true | ||||||
| 		}, | 		}, | ||||||
| 		"@esbuild/darwin-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/freebsd-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/freebsd-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-arm": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-ia32": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-loong64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-mips64el": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-ppc64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-riscv64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-s390x": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/linux-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/netbsd-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/openbsd-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/sunos-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/win32-arm64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/win32-ia32": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@esbuild/win32-x64": { |  | ||||||
| 			"version": "0.18.20", |  | ||||||
| 			"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", |  | ||||||
| 			"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", |  | ||||||
| 			"optional": true |  | ||||||
| 		}, |  | ||||||
| 		"@eslint-community/eslint-utils": { | 		"@eslint-community/eslint-utils": { | ||||||
| 			"version": "4.4.0", | 			"version": "4.4.0", | ||||||
| 			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", | 			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", | ||||||
|  | @ -4735,6 +4300,11 @@ | ||||||
| 			"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", | 			"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", | ||||||
| 			"dev": true | 			"dev": true | ||||||
| 		}, | 		}, | ||||||
|  | 		"async": { | ||||||
|  | 			"version": "3.2.5", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", | ||||||
|  | 			"integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" | ||||||
|  | 		}, | ||||||
| 		"autoprefixer": { | 		"autoprefixer": { | ||||||
| 			"version": "10.4.16", | 			"version": "10.4.16", | ||||||
| 			"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", | 			"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", | ||||||
|  |  | ||||||
|  | @ -40,6 +40,7 @@ | ||||||
| 	"type": "module", | 	"type": "module", | ||||||
| 	"dependencies": { | 	"dependencies": { | ||||||
| 		"@sveltejs/adapter-node": "^1.3.1", | 		"@sveltejs/adapter-node": "^1.3.1", | ||||||
|  | 		"async": "^3.2.5", | ||||||
| 		"dayjs": "^1.11.10", | 		"dayjs": "^1.11.10", | ||||||
| 		"file-saver": "^2.0.5", | 		"file-saver": "^2.0.5", | ||||||
| 		"highlight.js": "^11.9.0", | 		"highlight.js": "^11.9.0", | ||||||
|  |  | ||||||
|  | @ -299,13 +299,30 @@ export const pullModel = async (token: string, tagName: string) => { | ||||||
| 			name: tagName | 			name: tagName | ||||||
| 		}) | 		}) | ||||||
| 	}).catch((err) => { | 	}).catch((err) => { | ||||||
|  | 		console.log(err); | ||||||
| 		error = err; | 		error = err; | ||||||
|  | 
 | ||||||
|  | 		if ('detail' in err) { | ||||||
|  | 			error = err.detail; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		return null; | 		return null; | ||||||
| 	}); | 	}); | ||||||
| 
 |  | ||||||
| 	if (error) { | 	if (error) { | ||||||
| 		throw error; | 		throw error; | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	return res; | 	return res; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | // export const pullModel = async (token: string, tagName: string) => {
 | ||||||
|  | // 	return await fetch(`${OLLAMA_API_BASE_URL}/pull`, {
 | ||||||
|  | // 		method: 'POST',
 | ||||||
|  | // 		headers: {
 | ||||||
|  | // 			'Content-Type': 'text/event-stream',
 | ||||||
|  | // 			Authorization: `Bearer ${token}`
 | ||||||
|  | // 		},
 | ||||||
|  | // 		body: JSON.stringify({
 | ||||||
|  | // 			name: tagName
 | ||||||
|  | // 		})
 | ||||||
|  | // 	});
 | ||||||
|  | // };
 | ||||||
|  |  | ||||||
|  | @ -1,11 +1,11 @@ | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| 	import toast from 'svelte-french-toast'; | 	import toast from 'svelte-french-toast'; | ||||||
|  | 	import queue from 'async/queue'; | ||||||
| 	import fileSaver from 'file-saver'; | 	import fileSaver from 'file-saver'; | ||||||
| 	const { saveAs } = fileSaver; | 	const { saveAs } = fileSaver; | ||||||
| 
 | 
 | ||||||
|  | 	import { goto } from '$app/navigation'; | ||||||
| 	import { onMount } from 'svelte'; | 	import { onMount } from 'svelte'; | ||||||
| 	import { config, models, settings, user, chats } from '$lib/stores'; |  | ||||||
| 	import { splitStream, getGravatarURL } from '$lib/utils'; |  | ||||||
| 
 | 
 | ||||||
| 	import { | 	import { | ||||||
| 		getOllamaVersion, | 		getOllamaVersion, | ||||||
|  | @ -16,14 +16,16 @@ | ||||||
| 		createModel, | 		createModel, | ||||||
| 		deleteModel | 		deleteModel | ||||||
| 	} from '$lib/apis/ollama'; | 	} from '$lib/apis/ollama'; | ||||||
|  | 	import { updateUserPassword } from '$lib/apis/auths'; | ||||||
| 	import { createNewChat, deleteAllChats, getAllChats, getChatList } from '$lib/apis/chats'; | 	import { createNewChat, deleteAllChats, getAllChats, getChatList } from '$lib/apis/chats'; | ||||||
| 	import { WEB_UI_VERSION, WEBUI_API_BASE_URL } from '$lib/constants'; | 	import { WEB_UI_VERSION, WEBUI_API_BASE_URL } from '$lib/constants'; | ||||||
| 
 | 
 | ||||||
|  | 	import { config, models, settings, user, chats } from '$lib/stores'; | ||||||
|  | 	import { splitStream, getGravatarURL } from '$lib/utils'; | ||||||
|  | 
 | ||||||
| 	import Advanced from './Settings/Advanced.svelte'; | 	import Advanced from './Settings/Advanced.svelte'; | ||||||
| 	import Modal from '../common/Modal.svelte'; | 	import Modal from '../common/Modal.svelte'; | ||||||
| 	import { updateUserPassword } from '$lib/apis/auths'; | 
 | ||||||
| 	import { goto } from '$app/navigation'; |  | ||||||
| 	import Page from '../../../routes/(app)/+page.svelte'; |  | ||||||
| 	import { | 	import { | ||||||
| 		getOpenAIKey, | 		getOpenAIKey, | ||||||
| 		getOpenAIModels, | 		getOpenAIModels, | ||||||
|  | @ -71,8 +73,15 @@ | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	// Models | 	// Models | ||||||
| 	let modelTransferring = false; | 	const MAX_PARALLEL_DOWNLOADS = 3; | ||||||
|  | 	const modelDownloadQueue = queue( | ||||||
|  | 		(task: { modelName: string }, cb) => | ||||||
|  | 			pullModelHandlerProcessor({ modelName: task.modelName, callback: cb }), | ||||||
|  | 		MAX_PARALLEL_DOWNLOADS | ||||||
|  | 	); | ||||||
|  | 	let modelDownloadStatus: Record<string, any> = {}; | ||||||
| 
 | 
 | ||||||
|  | 	let modelTransferring = false; | ||||||
| 	let modelTag = ''; | 	let modelTag = ''; | ||||||
| 	let digest = ''; | 	let digest = ''; | ||||||
| 	let pullProgress = null; | 	let pullProgress = null; | ||||||
|  | @ -87,7 +96,6 @@ | ||||||
| 	let deleteModelTag = ''; | 	let deleteModelTag = ''; | ||||||
| 
 | 
 | ||||||
| 	// External | 	// External | ||||||
| 
 |  | ||||||
| 	let OPENAI_API_KEY = ''; | 	let OPENAI_API_KEY = ''; | ||||||
| 	let OPENAI_API_BASE_URL = ''; | 	let OPENAI_API_BASE_URL = ''; | ||||||
| 
 | 
 | ||||||
|  | @ -104,6 +112,32 @@ | ||||||
| 	let importFiles; | 	let importFiles; | ||||||
| 	let showDeleteConfirm = false; | 	let showDeleteConfirm = false; | ||||||
| 
 | 
 | ||||||
|  | 	// Auth | ||||||
|  | 	let authEnabled = false; | ||||||
|  | 	let authType = 'Basic'; | ||||||
|  | 	let authContent = ''; | ||||||
|  | 
 | ||||||
|  | 	// Account | ||||||
|  | 	let currentPassword = ''; | ||||||
|  | 	let newPassword = ''; | ||||||
|  | 	let newPasswordConfirm = ''; | ||||||
|  | 
 | ||||||
|  | 	// About | ||||||
|  | 	let ollamaVersion = ''; | ||||||
|  | 
 | ||||||
|  | 	$: if (importFiles) { | ||||||
|  | 		console.log(importFiles); | ||||||
|  | 
 | ||||||
|  | 		let reader = new FileReader(); | ||||||
|  | 		reader.onload = (event) => { | ||||||
|  | 			let chats = JSON.parse(event.target.result); | ||||||
|  | 			console.log(chats); | ||||||
|  | 			importChats(chats); | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		reader.readAsText(importFiles[0]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	const importChats = async (_chats) => { | 	const importChats = async (_chats) => { | ||||||
| 		for (const chat of _chats) { | 		for (const chat of _chats) { | ||||||
| 			console.log(chat); | 			console.log(chat); | ||||||
|  | @ -120,38 +154,12 @@ | ||||||
| 		saveAs(blob, `chat-export-${Date.now()}.json`); | 		saveAs(blob, `chat-export-${Date.now()}.json`); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	$: if (importFiles) { |  | ||||||
| 		console.log(importFiles); |  | ||||||
| 
 |  | ||||||
| 		let reader = new FileReader(); |  | ||||||
| 		reader.onload = (event) => { |  | ||||||
| 			let chats = JSON.parse(event.target.result); |  | ||||||
| 			console.log(chats); |  | ||||||
| 			importChats(chats); |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		reader.readAsText(importFiles[0]); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	const deleteChats = async () => { | 	const deleteChats = async () => { | ||||||
| 		await goto('/'); | 		await goto('/'); | ||||||
| 		await deleteAllChats(localStorage.token); | 		await deleteAllChats(localStorage.token); | ||||||
| 		await chats.set(await getChatList(localStorage.token)); | 		await chats.set(await getChatList(localStorage.token)); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	// Auth |  | ||||||
| 	let authEnabled = false; |  | ||||||
| 	let authType = 'Basic'; |  | ||||||
| 	let authContent = ''; |  | ||||||
| 
 |  | ||||||
| 	// Account |  | ||||||
| 	let currentPassword = ''; |  | ||||||
| 	let newPassword = ''; |  | ||||||
| 	let newPasswordConfirm = ''; |  | ||||||
| 
 |  | ||||||
| 	// About |  | ||||||
| 	let ollamaVersion = ''; |  | ||||||
| 
 |  | ||||||
| 	const updateOllamaAPIUrlHandler = async () => { | 	const updateOllamaAPIUrlHandler = async () => { | ||||||
| 		API_BASE_URL = await updateOllamaAPIUrl(localStorage.token, API_BASE_URL); | 		API_BASE_URL = await updateOllamaAPIUrl(localStorage.token, API_BASE_URL); | ||||||
| 		const _models = await getModels('ollama'); | 		const _models = await getModels('ollama'); | ||||||
|  | @ -247,10 +255,11 @@ | ||||||
| 		saveSettings({ saveChatHistory: saveChatHistory }); | 		saveSettings({ saveChatHistory: saveChatHistory }); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const pullModelHandler = async () => { | 	const pullModelHandlerProcessor = async (opts: { modelName: string; callback: Function }) => { | ||||||
| 		modelTransferring = true; | 		const res = await pullModel(localStorage.token, opts.modelName).catch((error) => { | ||||||
| 
 | 			opts.callback({ success: false, error, modelName: opts.modelName }); | ||||||
| 		const res = await pullModel(localStorage.token, modelTag); | 			return null; | ||||||
|  | 		}); | ||||||
| 
 | 
 | ||||||
| 		if (res) { | 		if (res) { | ||||||
| 			const reader = res.body | 			const reader = res.body | ||||||
|  | @ -259,92 +268,89 @@ | ||||||
| 				.getReader(); | 				.getReader(); | ||||||
| 
 | 
 | ||||||
| 			while (true) { | 			while (true) { | ||||||
| 				const { value, done } = await reader.read(); |  | ||||||
| 				if (done) break; |  | ||||||
| 
 |  | ||||||
| 				try { | 				try { | ||||||
|  | 					const { value, done } = await reader.read(); | ||||||
|  | 					if (done) break; | ||||||
|  | 
 | ||||||
| 					let lines = value.split('\n'); | 					let lines = value.split('\n'); | ||||||
| 
 | 
 | ||||||
| 					for (const line of lines) { | 					for (const line of lines) { | ||||||
| 						if (line !== '') { | 						if (line !== '') { | ||||||
| 							console.log(line); |  | ||||||
| 							let data = JSON.parse(line); | 							let data = JSON.parse(line); | ||||||
| 							console.log(data); |  | ||||||
| 
 |  | ||||||
| 							if (data.error) { | 							if (data.error) { | ||||||
| 								throw data.error; | 								throw data.error; | ||||||
| 							} | 							} | ||||||
| 
 |  | ||||||
| 							if (data.detail) { | 							if (data.detail) { | ||||||
| 								throw data.detail; | 								throw data.detail; | ||||||
| 							} | 							} | ||||||
| 							if (data.status) { | 							if (data.status) { | ||||||
| 								if (!data.digest) { | 								if (data.digest) { | ||||||
| 									toast.success(data.status); | 									let downloadProgress = 0; | ||||||
| 
 |  | ||||||
| 									if (data.status === 'success') { |  | ||||||
| 										const notification = new Notification(`Ollama`, { |  | ||||||
| 											body: `Model '${modelTag}' has been successfully downloaded.`, |  | ||||||
| 											icon: '/favicon.png' |  | ||||||
| 										}); |  | ||||||
| 									} |  | ||||||
| 								} else { |  | ||||||
| 									digest = data.digest; |  | ||||||
| 									if (data.completed) { | 									if (data.completed) { | ||||||
| 										pullProgress = Math.round((data.completed / data.total) * 1000) / 10; | 										downloadProgress = Math.round((data.completed / data.total) * 1000) / 10; | ||||||
| 									} else { | 									} else { | ||||||
| 										pullProgress = 100; | 										downloadProgress = 100; | ||||||
| 									} | 									} | ||||||
|  | 									modelDownloadStatus[opts.modelName] = { | ||||||
|  | 										pullProgress: downloadProgress, | ||||||
|  | 										digest: data.digest | ||||||
|  | 									}; | ||||||
|  | 								} else { | ||||||
|  | 									toast.success(data.status); | ||||||
| 								} | 								} | ||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} catch (error) { | 				} catch (error) { | ||||||
| 					console.log(error); | 					console.log(error); | ||||||
| 					toast.error(error); | 					if (typeof error !== 'string') { | ||||||
|  | 						error = error.message; | ||||||
|  | 					} | ||||||
|  | 					opts.callback({ success: false, error, modelName: opts.modelName }); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 			opts.callback({ success: true, modelName: opts.modelName }); | ||||||
| 		} | 		} | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	const pullModelHandler = async () => { | ||||||
|  | 		if (modelDownloadStatus[modelTag]) { | ||||||
|  | 			toast.error(`Model '${modelTag}' is already in queue for downloading.`); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 		if (Object.keys(modelDownloadStatus).length === 3) { | ||||||
|  | 			toast.error('Maximum of 3 models can be downloaded simultaneously. Please try again later.'); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		modelTransferring = true; | ||||||
|  | 
 | ||||||
|  | 		modelDownloadQueue.push( | ||||||
|  | 			{ modelName: modelTag }, | ||||||
|  | 			async (data: { modelName: string; success: boolean; error?: Error }) => { | ||||||
|  | 				const { modelName } = data; | ||||||
|  | 				// Remove the downloaded model | ||||||
|  | 				delete modelDownloadStatus[modelName]; | ||||||
|  | 
 | ||||||
|  | 				console.log(data); | ||||||
|  | 
 | ||||||
|  | 				if (!data.success) { | ||||||
|  | 					toast.error(data.error); | ||||||
|  | 				} else { | ||||||
|  | 					toast.success(`Model '${modelName}' has been successfully downloaded.`); | ||||||
|  | 
 | ||||||
|  | 					const notification = new Notification(`Ollama`, { | ||||||
|  | 						body: `Model '${modelName}' has been successfully downloaded.`, | ||||||
|  | 						icon: '/favicon.png' | ||||||
|  | 					}); | ||||||
|  | 
 | ||||||
|  | 					models.set(await getModels()); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		); | ||||||
| 
 | 
 | ||||||
| 		modelTag = ''; | 		modelTag = ''; | ||||||
| 		modelTransferring = false; | 		modelTransferring = false; | ||||||
| 
 |  | ||||||
| 		models.set(await getModels()); |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	const calculateSHA256 = async (file) => { |  | ||||||
| 		console.log(file); |  | ||||||
| 		// Create a FileReader to read the file asynchronously |  | ||||||
| 		const reader = new FileReader(); |  | ||||||
| 
 |  | ||||||
| 		// Define a promise to handle the file reading |  | ||||||
| 		const readFile = new Promise((resolve, reject) => { |  | ||||||
| 			reader.onload = () => resolve(reader.result); |  | ||||||
| 			reader.onerror = reject; |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		// Read the file as an ArrayBuffer |  | ||||||
| 		reader.readAsArrayBuffer(file); |  | ||||||
| 
 |  | ||||||
| 		try { |  | ||||||
| 			// Wait for the FileReader to finish reading the file |  | ||||||
| 			const buffer = await readFile; |  | ||||||
| 
 |  | ||||||
| 			// Convert the ArrayBuffer to a Uint8Array |  | ||||||
| 			const uint8Array = new Uint8Array(buffer); |  | ||||||
| 
 |  | ||||||
| 			// Calculate the SHA-256 hash using Web Crypto API |  | ||||||
| 			const hashBuffer = await crypto.subtle.digest('SHA-256', uint8Array); |  | ||||||
| 
 |  | ||||||
| 			// Convert the hash to a hexadecimal string |  | ||||||
| 			const hashArray = Array.from(new Uint8Array(hashBuffer)); |  | ||||||
| 			const hashHex = hashArray.map((byte) => byte.toString(16).padStart(2, '0')).join(''); |  | ||||||
| 
 |  | ||||||
| 			return `sha256:${hashHex}`; |  | ||||||
| 		} catch (error) { |  | ||||||
| 			console.error('Error calculating SHA-256 hash:', error); |  | ||||||
| 			throw error; |  | ||||||
| 		} |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const uploadModelHandler = async () => { | 	const uploadModelHandler = async () => { | ||||||
|  | @ -1158,7 +1164,7 @@ | ||||||
| 									</button> | 									</button> | ||||||
| 								</div> | 								</div> | ||||||
| 
 | 
 | ||||||
| 								<div class="mt-2 text-xs text-gray-400 dark:text-gray-500"> | 								<div class="mt-2 mb-1 text-xs text-gray-400 dark:text-gray-500"> | ||||||
| 									To access the available model names for downloading, <a | 									To access the available model names for downloading, <a | ||||||
| 										class=" text-gray-500 dark:text-gray-300 font-medium" | 										class=" text-gray-500 dark:text-gray-300 font-medium" | ||||||
| 										href="https://ollama.ai/library" | 										href="https://ollama.ai/library" | ||||||
|  | @ -1166,23 +1172,29 @@ | ||||||
| 									> | 									> | ||||||
| 								</div> | 								</div> | ||||||
| 
 | 
 | ||||||
| 								{#if pullProgress !== null} | 								{#if Object.keys(modelDownloadStatus).length > 0} | ||||||
| 									<div class="mt-2"> | 									{#each Object.keys(modelDownloadStatus) as model} | ||||||
| 										<div class=" mb-2 text-xs">Pull Progress</div> | 										<div class="flex flex-col"> | ||||||
| 										<div class="w-full rounded-full dark:bg-gray-800"> | 											<div class="font-medium mb-1">{model}</div> | ||||||
| 											<div | 											<div class=""> | ||||||
| 												class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full" | 												<div | ||||||
| 												style="width: {Math.max(15, pullProgress ?? 0)}%" | 													class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full" | ||||||
| 											> | 													style="width: {Math.max( | ||||||
| 												{pullProgress ?? 0}% | 														15, | ||||||
|  | 														modelDownloadStatus[model].pullProgress ?? 0 | ||||||
|  | 													)}%" | ||||||
|  | 												> | ||||||
|  | 													{modelDownloadStatus[model].pullProgress ?? 0}% | ||||||
|  | 												</div> | ||||||
|  | 												<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;"> | ||||||
|  | 													{modelDownloadStatus[model].digest} | ||||||
|  | 												</div> | ||||||
| 											</div> | 											</div> | ||||||
| 										</div> | 										</div> | ||||||
| 										<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;"> | 									{/each} | ||||||
| 											{digest} |  | ||||||
| 										</div> |  | ||||||
| 									</div> |  | ||||||
| 								{/if} | 								{/if} | ||||||
| 							</div> | 							</div> | ||||||
|  | 
 | ||||||
| 							<hr class=" dark:border-gray-700" /> | 							<hr class=" dark:border-gray-700" /> | ||||||
| 
 | 
 | ||||||
| 							<div> | 							<div> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Jaeryang Baek
						Timothy Jaeryang Baek