Unverified Commit c41b33c9 authored by Timothy Jaeryang Baek's avatar Timothy Jaeryang Baek Committed by GitHub
Browse files

Merge pull request #3013 from open-webui/dev

0.3.3
parents 06976c45 7131ac24
import inspect
from typing import get_type_hints, List, Dict, Any
def doc_to_dict(docstring):
lines = docstring.split("\n")
description = lines[1].strip()
param_dict = {}
for line in lines:
if ":param" in line:
line = line.replace(":param", "").strip()
param, desc = line.split(":", 1)
param_dict[param.strip()] = desc.strip()
ret_dict = {"description": description, "params": param_dict}
return ret_dict
def get_tools_specs(tools) -> List[dict]:
function_list = [
{"name": func, "function": getattr(tools, func)}
for func in dir(tools)
if callable(getattr(tools, func)) and not func.startswith("__")
]
specs = []
for function_item in function_list:
function_name = function_item["name"]
function = function_item["function"]
function_doc = doc_to_dict(function.__doc__ or function_name)
specs.append(
{
"name": function_name,
# TODO: multi-line desc?
"description": function_doc.get("description", function_name),
"parameters": {
"type": "object",
"properties": {
param_name: {
"type": param_annotation.__name__.lower(),
**(
{
"enum": (
str(param_annotation.__args__)
if hasattr(param_annotation, "__args__")
else None
)
}
if hasattr(param_annotation, "__args__")
else {}
),
"description": function_doc.get("params", {}).get(
param_name, param_name
),
}
for param_name, param_annotation in get_type_hints(
function
).items()
if param_name != "return" and param_name != "__user__"
},
"required": [
name
for name, param in inspect.signature(
function
).parameters.items()
if param.default is param.empty
],
},
}
)
return specs
...@@ -28,19 +28,6 @@ describe('Settings', () => { ...@@ -28,19 +28,6 @@ describe('Settings', () => {
}); });
}); });
context('Connections', () => {
it('user can open the Connections modal and hit save', () => {
cy.get('button').contains('Connections').click();
cy.get('button').contains('Save').click();
});
});
context('Models', () => {
it('user can open the Models modal', () => {
cy.get('button').contains('Models').click();
});
});
context('Interface', () => { context('Interface', () => {
it('user can open the Interface modal and hit save', () => { it('user can open the Interface modal and hit save', () => {
cy.get('button').contains('Interface').click(); cy.get('button').contains('Interface').click();
...@@ -55,14 +42,6 @@ describe('Settings', () => { ...@@ -55,14 +42,6 @@ describe('Settings', () => {
}); });
}); });
context('Images', () => {
it('user can open the Images modal and hit save', () => {
cy.get('button').contains('Images').click();
// Currently fails because the backend requires a valid URL
// cy.get('button').contains('Save').click();
});
});
context('Chats', () => { context('Chats', () => {
it('user can open the Chats modal', () => { it('user can open the Chats modal', () => {
cy.get('button').contains('Chats').click(); cy.get('button').contains('Chats').click();
......
{ {
"name": "open-webui", "name": "open-webui",
"version": "0.3.2", "version": "0.3.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "open-webui", "name": "open-webui",
"version": "0.3.2", "version": "0.3.3",
"dependencies": { "dependencies": {
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-python": "^6.1.6",
"@codemirror/theme-one-dark": "^6.1.2",
"@pyscript/core": "^0.4.32", "@pyscript/core": "^0.4.32",
"@sveltejs/adapter-node": "^1.3.1", "@sveltejs/adapter-node": "^1.3.1",
"async": "^3.2.5", "async": "^3.2.5",
"bits-ui": "^0.19.7", "bits-ui": "^0.19.7",
"codemirror": "^6.0.1",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"eventsource-parser": "^1.1.2", "eventsource-parser": "^1.1.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
...@@ -108,6 +112,119 @@ ...@@ -108,6 +112,119 @@
"resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz",
"integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="
}, },
"node_modules/@codemirror/autocomplete": {
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.16.2.tgz",
"integrity": "sha512-MjfDrHy0gHKlPWsvSsikhO1+BOh+eBHNgfH1OXs1+DAf30IonQldgMM3kxLDTG9ktE7kDLaA1j/l7KMPA4KNfw==",
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.17.0",
"@lezer/common": "^1.0.0"
},
"peerDependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@lezer/common": "^1.0.0"
}
},
"node_modules/@codemirror/commands": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.0.tgz",
"integrity": "sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg==",
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.4.0",
"@codemirror/view": "^6.27.0",
"@lezer/common": "^1.1.0"
}
},
"node_modules/@codemirror/lang-javascript": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz",
"integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==",
"dependencies": {
"@codemirror/autocomplete": "^6.0.0",
"@codemirror/language": "^6.6.0",
"@codemirror/lint": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.17.0",
"@lezer/common": "^1.0.0",
"@lezer/javascript": "^1.0.0"
}
},
"node_modules/@codemirror/lang-python": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.6.tgz",
"integrity": "sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg==",
"dependencies": {
"@codemirror/autocomplete": "^6.3.2",
"@codemirror/language": "^6.8.0",
"@codemirror/state": "^6.0.0",
"@lezer/common": "^1.2.1",
"@lezer/python": "^1.1.4"
}
},
"node_modules/@codemirror/language": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz",
"integrity": "sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==",
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.23.0",
"@lezer/common": "^1.1.0",
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0",
"style-mod": "^4.0.0"
}
},
"node_modules/@codemirror/lint": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.0.tgz",
"integrity": "sha512-lsFofvaw0lnPRJlQylNsC4IRt/1lI4OD/yYslrSGVndOJfStc58v+8p9dgGiD90ktOfL7OhBWns1ZETYgz0EJA==",
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"crelt": "^1.0.5"
}
},
"node_modules/@codemirror/search": {
"version": "6.5.6",
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz",
"integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==",
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"crelt": "^1.0.5"
}
},
"node_modules/@codemirror/state": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
"integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
},
"node_modules/@codemirror/theme-one-dark": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
"integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@lezer/highlight": "^1.0.0"
}
},
"node_modules/@codemirror/view": {
"version": "6.28.0",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.0.tgz",
"integrity": "sha512-fo7CelaUDKWIyemw4b+J57cWuRkOu4SWCCPfNDkPvfWkGjM9D5racHQXr4EQeYCD6zEBIBxGCeaKkQo+ysl0gA==",
"dependencies": {
"@codemirror/state": "^6.4.0",
"style-mod": "^4.1.0",
"w3c-keyname": "^2.2.4"
}
},
"node_modules/@colors/colors": { "node_modules/@colors/colors": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
...@@ -825,6 +942,47 @@ ...@@ -825,6 +942,47 @@
"@jridgewell/sourcemap-codec": "^1.4.14" "@jridgewell/sourcemap-codec": "^1.4.14"
} }
}, },
"node_modules/@lezer/common": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
"integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
},
"node_modules/@lezer/highlight": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
"integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@lezer/javascript": {
"version": "1.4.16",
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.16.tgz",
"integrity": "sha512-84UXR3N7s11MPQHWgMnjb9571fr19MmXnr5zTv2XX0gHXXUvW3uPJ8GCjKrfTXmSdfktjRK0ayKklw+A13rk4g==",
"dependencies": {
"@lezer/common": "^1.2.0",
"@lezer/highlight": "^1.1.3",
"@lezer/lr": "^1.3.0"
}
},
"node_modules/@lezer/lr": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.1.tgz",
"integrity": "sha512-CHsKq8DMKBf9b3yXPDIU4DbH+ZJd/sJdYOW2llbW/HudP5u0VS6Bfq1hLYfgU7uAYGFIyGGQIsSOXGPEErZiJw==",
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@lezer/python": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.14.tgz",
"integrity": "sha512-ykDOb2Ti24n76PJsSa4ZoDF0zH12BSw1LGfQXCYJhJyOGiFTfGaX0Du66Ze72R+u/P35U+O6I9m8TFXov1JzsA==",
"dependencies": {
"@lezer/common": "^1.2.0",
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0"
}
},
"node_modules/@melt-ui/svelte": { "node_modules/@melt-ui/svelte": {
"version": "0.76.0", "version": "0.76.0",
"resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.76.0.tgz", "resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.76.0.tgz",
...@@ -2224,12 +2382,12 @@ ...@@ -2224,12 +2382,12 @@
} }
}, },
"node_modules/braces": { "node_modules/braces": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"fill-range": "^7.0.1" "fill-range": "^7.1.1"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
...@@ -2769,6 +2927,20 @@ ...@@ -2769,6 +2927,20 @@
"plain-tag": "^0.1.3" "plain-tag": "^0.1.3"
} }
}, },
"node_modules/codemirror": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
"dependencies": {
"@codemirror/autocomplete": "^6.0.0",
"@codemirror/commands": "^6.0.0",
"@codemirror/language": "^6.0.0",
"@codemirror/lint": "^6.0.0",
"@codemirror/search": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0"
}
},
"node_modules/coincident": { "node_modules/coincident": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/coincident/-/coincident-1.2.3.tgz", "resolved": "https://registry.npmjs.org/coincident/-/coincident-1.2.3.tgz",
...@@ -2891,6 +3063,11 @@ ...@@ -2891,6 +3063,11 @@
"layout-base": "^1.0.0" "layout-base": "^1.0.0"
} }
}, },
"node_modules/crelt": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
...@@ -4429,9 +4606,9 @@ ...@@ -4429,9 +4606,9 @@
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
}, },
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.0.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
...@@ -8278,6 +8455,11 @@ ...@@ -8278,6 +8455,11 @@
"url": "https://github.com/sponsors/antfu" "url": "https://github.com/sponsors/antfu"
} }
}, },
"node_modules/style-mod": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
},
"node_modules/stylis": { "node_modules/stylis": {
"version": "4.3.2", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
...@@ -10022,6 +10204,11 @@ ...@@ -10022,6 +10204,11 @@
"he": "^1.2.0" "he": "^1.2.0"
} }
}, },
"node_modules/w3c-keyname": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
},
"node_modules/walk-sync": { "node_modules/walk-sync": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz",
......
{ {
"name": "open-webui", "name": "open-webui",
"version": "0.3.2", "version": "0.3.3",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "npm run pyodide:fetch && vite dev --host", "dev": "npm run pyodide:fetch && vite dev --host",
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
"format:backend": "black . --exclude \".venv/|/venv/\"", "format:backend": "black . --exclude \".venv/|/venv/\"",
"i18n:parse": "i18next --config i18next-parser.config.ts && prettier --write \"src/lib/i18n/**/*.{js,json}\"", "i18n:parse": "i18next --config i18next-parser.config.ts && prettier --write \"src/lib/i18n/**/*.{js,json}\"",
"cy:open": "cypress open", "cy:open": "cypress open",
"test:frontend": "vitest", "test:frontend": "vitest --passWithNoTests",
"pyodide:fetch": "node scripts/prepare-pyodide.js" "pyodide:fetch": "node scripts/prepare-pyodide.js"
}, },
"devDependencies": { "devDependencies": {
...@@ -48,10 +48,14 @@ ...@@ -48,10 +48,14 @@
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-python": "^6.1.6",
"@codemirror/theme-one-dark": "^6.1.2",
"@pyscript/core": "^0.4.32", "@pyscript/core": "^0.4.32",
"@sveltejs/adapter-node": "^1.3.1", "@sveltejs/adapter-node": "^1.3.1",
"async": "^3.2.5", "async": "^3.2.5",
"bits-ui": "^0.19.7", "bits-ui": "^0.19.7",
"codemirror": "^6.0.1",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"eventsource-parser": "^1.1.2", "eventsource-parser": "^1.1.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
......
...@@ -26,8 +26,6 @@ dependencies = [ ...@@ -26,8 +26,6 @@ dependencies = [
"PyMySQL==1.1.0", "PyMySQL==1.1.0",
"bcrypt==4.1.3", "bcrypt==4.1.3",
"litellm[proxy]==1.37.20",
"boto3==1.34.110", "boto3==1.34.110",
"argon2-cffi==23.1.0", "argon2-cffi==23.1.0",
...@@ -66,6 +64,10 @@ dependencies = [ ...@@ -66,6 +64,10 @@ dependencies = [
"langfuse==2.33.0", "langfuse==2.33.0",
"youtube-transcript-api==0.6.2", "youtube-transcript-api==0.6.2",
"pytube==15.0.0", "pytube==15.0.0",
"extract_msg",
"pydub",
"duckduckgo-search~=6.1.5"
] ]
readme = "README.md" readme = "README.md"
requires-python = ">= 3.11, < 3.12.0a1" requires-python = ">= 3.11, < 3.12.0a1"
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
aiohttp==3.9.5 aiohttp==3.9.5
# via langchain # via langchain
# via langchain-community # via langchain-community
# via litellm
# via open-webui # via open-webui
aiosignal==1.3.1 aiosignal==1.3.1
# via aiohttp # via aiohttp
...@@ -20,11 +19,9 @@ annotated-types==0.6.0 ...@@ -20,11 +19,9 @@ annotated-types==0.6.0
# via pydantic # via pydantic
anyio==4.3.0 anyio==4.3.0
# via httpx # via httpx
# via openai
# via starlette # via starlette
# via watchfiles # via watchfiles
apscheduler==3.10.4 apscheduler==3.10.4
# via litellm
# via open-webui # via open-webui
argon2-cffi==23.1.0 argon2-cffi==23.1.0
# via open-webui # via open-webui
...@@ -38,7 +35,6 @@ av==11.0.0 ...@@ -38,7 +35,6 @@ av==11.0.0
# via faster-whisper # via faster-whisper
backoff==2.2.1 backoff==2.2.1
# via langfuse # via langfuse
# via litellm
# via posthog # via posthog
# via unstructured # via unstructured
bcrypt==4.1.3 bcrypt==4.1.3
...@@ -46,6 +42,7 @@ bcrypt==4.1.3 ...@@ -46,6 +42,7 @@ bcrypt==4.1.3
# via open-webui # via open-webui
# via passlib # via passlib
beautifulsoup4==4.12.3 beautifulsoup4==4.12.3
# via extract-msg
# via unstructured # via unstructured
bidict==0.23.1 bidict==0.23.1
# via python-socketio # via python-socketio
...@@ -83,17 +80,20 @@ chromadb==0.5.0 ...@@ -83,17 +80,20 @@ chromadb==0.5.0
# via open-webui # via open-webui
click==8.1.7 click==8.1.7
# via black # via black
# via duckduckgo-search
# via flask # via flask
# via litellm
# via nltk # via nltk
# via peewee-migrate # via peewee-migrate
# via rq
# via typer # via typer
# via uvicorn # via uvicorn
colorclass==2.2.2
# via oletools
coloredlogs==15.0.1 coloredlogs==15.0.1
# via onnxruntime # via onnxruntime
compressed-rtf==1.0.6
# via extract-msg
cryptography==42.0.7 cryptography==42.0.7
# via litellm # via msoffcrypto-tool
# via pyjwt # via pyjwt
ctranslate2==4.2.1 ctranslate2==4.2.1
# via faster-whisper # via faster-whisper
...@@ -109,33 +109,34 @@ defusedxml==0.7.1 ...@@ -109,33 +109,34 @@ defusedxml==0.7.1
deprecated==1.2.14 deprecated==1.2.14
# via opentelemetry-api # via opentelemetry-api
# via opentelemetry-exporter-otlp-proto-grpc # via opentelemetry-exporter-otlp-proto-grpc
distro==1.9.0
# via openai
dnspython==2.6.1 dnspython==2.6.1
# via email-validator # via email-validator
docx2txt==0.8 docx2txt==0.8
# via open-webui # via open-webui
duckduckgo-search==6.1.5
# via open-webui
easygui==0.98.3
# via oletools
ebcdic==1.1.1
# via extract-msg
ecdsa==0.19.0 ecdsa==0.19.0
# via python-jose # via python-jose
email-validator==2.1.1 email-validator==2.1.1
# via fastapi # via fastapi
# via pydantic
emoji==2.11.1 emoji==2.11.1
# via unstructured # via unstructured
et-xmlfile==1.1.0 et-xmlfile==1.1.0
# via openpyxl # via openpyxl
extract-msg==0.48.5
# via open-webui
fake-useragent==1.5.1 fake-useragent==1.5.1
# via open-webui # via open-webui
fastapi==0.111.0 fastapi==0.111.0
# via chromadb # via chromadb
# via fastapi-sso
# via langchain-chroma # via langchain-chroma
# via litellm
# via open-webui # via open-webui
fastapi-cli==0.0.4 fastapi-cli==0.0.4
# via fastapi # via fastapi
fastapi-sso==0.10.0
# via litellm
faster-whisper==1.0.2 faster-whisper==1.0.2
# via open-webui # via open-webui
filelock==3.14.0 filelock==3.14.0
...@@ -191,8 +192,6 @@ grpcio==1.63.0 ...@@ -191,8 +192,6 @@ grpcio==1.63.0
# via opentelemetry-exporter-otlp-proto-grpc # via opentelemetry-exporter-otlp-proto-grpc
grpcio-status==1.62.2 grpcio-status==1.62.2
# via google-api-core # via google-api-core
gunicorn==22.0.0
# via litellm
h11==0.14.0 h11==0.14.0
# via httpcore # via httpcore
# via uvicorn # via uvicorn
...@@ -206,9 +205,7 @@ httptools==0.6.1 ...@@ -206,9 +205,7 @@ httptools==0.6.1
# via uvicorn # via uvicorn
httpx==0.27.0 httpx==0.27.0
# via fastapi # via fastapi
# via fastapi-sso
# via langfuse # via langfuse
# via openai
huggingface-hub==0.23.0 huggingface-hub==0.23.0
# via faster-whisper # via faster-whisper
# via sentence-transformers # via sentence-transformers
...@@ -225,7 +222,6 @@ idna==3.7 ...@@ -225,7 +222,6 @@ idna==3.7
# via unstructured-client # via unstructured-client
# via yarl # via yarl
importlib-metadata==7.0.0 importlib-metadata==7.0.0
# via litellm
# via opentelemetry-api # via opentelemetry-api
importlib-resources==6.4.0 importlib-resources==6.4.0
# via chromadb # via chromadb
...@@ -234,7 +230,6 @@ itsdangerous==2.2.0 ...@@ -234,7 +230,6 @@ itsdangerous==2.2.0
jinja2==3.1.4 jinja2==3.1.4
# via fastapi # via fastapi
# via flask # via flask
# via litellm
# via torch # via torch
jmespath==1.0.1 jmespath==1.0.1
# via boto3 # via boto3
...@@ -272,8 +267,8 @@ langsmith==0.1.57 ...@@ -272,8 +267,8 @@ langsmith==0.1.57
# via langchain # via langchain
# via langchain-community # via langchain-community
# via langchain-core # via langchain-core
litellm==1.37.20 lark==1.1.8
# via open-webui # via rtfde
lxml==5.2.2 lxml==5.2.2
# via unstructured # via unstructured
markdown==3.6 markdown==3.6
...@@ -294,6 +289,8 @@ monotonic==1.6 ...@@ -294,6 +289,8 @@ monotonic==1.6
# via posthog # via posthog
mpmath==1.3.0 mpmath==1.3.0
# via sympy # via sympy
msoffcrypto-tool==5.4.1
# via oletools
multidict==6.0.5 multidict==6.0.5
# via aiohttp # via aiohttp
# via yarl # via yarl
...@@ -325,15 +322,19 @@ numpy==1.26.4 ...@@ -325,15 +322,19 @@ numpy==1.26.4
# via transformers # via transformers
# via unstructured # via unstructured
oauthlib==3.2.2 oauthlib==3.2.2
# via fastapi-sso
# via kubernetes # via kubernetes
# via requests-oauthlib # via requests-oauthlib
olefile==0.47
# via extract-msg
# via msoffcrypto-tool
# via oletools
oletools==0.60.1
# via pcodedmp
# via rtfde
onnxruntime==1.17.3 onnxruntime==1.17.3
# via chromadb # via chromadb
# via faster-whisper # via faster-whisper
# via rapidocr-onnxruntime # via rapidocr-onnxruntime
openai==1.28.1
# via litellm
opencv-python==4.9.0.80 opencv-python==4.9.0.80
# via rapidocr-onnxruntime # via rapidocr-onnxruntime
opencv-python-headless==4.9.0.80 opencv-python-headless==4.9.0.80
...@@ -375,15 +376,14 @@ ordered-set==4.1.0 ...@@ -375,15 +376,14 @@ ordered-set==4.1.0
# via deepdiff # via deepdiff
orjson==3.10.3 orjson==3.10.3
# via chromadb # via chromadb
# via duckduckgo-search
# via fastapi # via fastapi
# via langsmith # via langsmith
# via litellm
overrides==7.7.0 overrides==7.7.0
# via chromadb # via chromadb
packaging==23.2 packaging==23.2
# via black # via black
# via build # via build
# via gunicorn
# via huggingface-hub # via huggingface-hub
# via langchain-core # via langchain-core
# via langfuse # via langfuse
...@@ -397,6 +397,8 @@ passlib==1.7.4 ...@@ -397,6 +397,8 @@ passlib==1.7.4
# via open-webui # via open-webui
pathspec==0.12.1 pathspec==0.12.1
# via black # via black
pcodedmp==1.2.6
# via oletools
peewee==3.17.5 peewee==3.17.5
# via open-webui # via open-webui
# via peewee-migrate # via peewee-migrate
...@@ -437,27 +439,27 @@ pycparser==2.22 ...@@ -437,27 +439,27 @@ pycparser==2.22
pydantic==2.7.1 pydantic==2.7.1
# via chromadb # via chromadb
# via fastapi # via fastapi
# via fastapi-sso
# via google-generativeai # via google-generativeai
# via langchain # via langchain
# via langchain-core # via langchain-core
# via langfuse # via langfuse
# via langsmith # via langsmith
# via open-webui # via open-webui
# via openai
pydantic-core==2.18.2 pydantic-core==2.18.2
# via pydantic # via pydantic
pydub==0.25.1
# via open-webui
pygments==2.18.0 pygments==2.18.0
# via rich # via rich
pyjwt==2.8.0 pyjwt==2.8.0
# via litellm
# via open-webui # via open-webui
pymysql==1.1.0 pymysql==1.1.0
# via open-webui # via open-webui
pypandoc==1.13 pypandoc==1.13
# via open-webui # via open-webui
pyparsing==3.1.2 pyparsing==2.4.7
# via httplib2 # via httplib2
# via oletools
pypdf==4.2.0 pypdf==4.2.0
# via open-webui # via open-webui
# via unstructured-client # via unstructured-client
...@@ -465,6 +467,8 @@ pypika==0.48.9 ...@@ -465,6 +467,8 @@ pypika==0.48.9
# via chromadb # via chromadb
pyproject-hooks==1.1.0 pyproject-hooks==1.1.0
# via build # via build
pyreqwest-impersonate==0.4.7
# via duckduckgo-search
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
# via botocore # via botocore
# via kubernetes # via kubernetes
...@@ -472,7 +476,6 @@ python-dateutil==2.9.0.post0 ...@@ -472,7 +476,6 @@ python-dateutil==2.9.0.post0
# via posthog # via posthog
# via unstructured-client # via unstructured-client
python-dotenv==1.0.1 python-dotenv==1.0.1
# via litellm
# via uvicorn # via uvicorn
python-engineio==4.9.0 python-engineio==4.9.0
# via python-socketio # via python-socketio
...@@ -484,7 +487,6 @@ python-magic==0.4.27 ...@@ -484,7 +487,6 @@ python-magic==0.4.27
# via unstructured # via unstructured
python-multipart==0.0.9 python-multipart==0.0.9
# via fastapi # via fastapi
# via litellm
# via open-webui # via open-webui
python-socketio==5.11.2 python-socketio==5.11.2
# via open-webui # via open-webui
...@@ -503,7 +505,6 @@ pyyaml==6.0.1 ...@@ -503,7 +505,6 @@ pyyaml==6.0.1
# via langchain # via langchain
# via langchain-community # via langchain-community
# via langchain-core # via langchain-core
# via litellm
# via rapidocr-onnxruntime # via rapidocr-onnxruntime
# via transformers # via transformers
# via uvicorn # via uvicorn
...@@ -513,11 +514,10 @@ rapidfuzz==3.9.0 ...@@ -513,11 +514,10 @@ rapidfuzz==3.9.0
# via unstructured # via unstructured
rapidocr-onnxruntime==1.3.22 rapidocr-onnxruntime==1.3.22
# via open-webui # via open-webui
redis==5.0.4 red-black-tree-mod==1.20
# via rq # via extract-msg
regex==2024.5.10 regex==2024.5.10
# via nltk # via nltk
# via tiktoken
# via transformers # via transformers
requests==2.32.2 requests==2.32.2
# via chromadb # via chromadb
...@@ -527,11 +527,9 @@ requests==2.32.2 ...@@ -527,11 +527,9 @@ requests==2.32.2
# via langchain # via langchain
# via langchain-community # via langchain-community
# via langsmith # via langsmith
# via litellm
# via open-webui # via open-webui
# via posthog # via posthog
# via requests-oauthlib # via requests-oauthlib
# via tiktoken
# via transformers # via transformers
# via unstructured # via unstructured
# via unstructured-client # via unstructured-client
...@@ -540,11 +538,11 @@ requests-oauthlib==2.0.0 ...@@ -540,11 +538,11 @@ requests-oauthlib==2.0.0
# via kubernetes # via kubernetes
rich==13.7.1 rich==13.7.1
# via typer # via typer
rq==1.16.2
# via litellm
rsa==4.9 rsa==4.9
# via google-auth # via google-auth
# via python-jose # via python-jose
rtfde==0.1.1
# via extract-msg
s3transfer==0.10.1 s3transfer==0.10.1
# via boto3 # via boto3
safetensors==0.4.3 safetensors==0.4.3
...@@ -577,7 +575,6 @@ six==1.16.0 ...@@ -577,7 +575,6 @@ six==1.16.0
sniffio==1.3.1 sniffio==1.3.1
# via anyio # via anyio
# via httpx # via httpx
# via openai
soupsieve==2.5 soupsieve==2.5
# via beautifulsoup4 # via beautifulsoup4
sqlalchemy==2.0.30 sqlalchemy==2.0.30
...@@ -597,12 +594,9 @@ tenacity==8.3.0 ...@@ -597,12 +594,9 @@ tenacity==8.3.0
# via langchain-core # via langchain-core
threadpoolctl==3.5.0 threadpoolctl==3.5.0
# via scikit-learn # via scikit-learn
tiktoken==0.6.0
# via litellm
tokenizers==0.15.2 tokenizers==0.15.2
# via chromadb # via chromadb
# via faster-whisper # via faster-whisper
# via litellm
# via transformers # via transformers
torch==2.3.0 torch==2.3.0
# via sentence-transformers # via sentence-transformers
...@@ -611,7 +605,6 @@ tqdm==4.66.4 ...@@ -611,7 +605,6 @@ tqdm==4.66.4
# via google-generativeai # via google-generativeai
# via huggingface-hub # via huggingface-hub
# via nltk # via nltk
# via openai
# via sentence-transformers # via sentence-transformers
# via transformers # via transformers
transformers==4.39.3 transformers==4.39.3
...@@ -624,7 +617,6 @@ typing-extensions==4.11.0 ...@@ -624,7 +617,6 @@ typing-extensions==4.11.0
# via fastapi # via fastapi
# via google-generativeai # via google-generativeai
# via huggingface-hub # via huggingface-hub
# via openai
# via opentelemetry-sdk # via opentelemetry-sdk
# via pydantic # via pydantic
# via pydantic-core # via pydantic-core
...@@ -641,6 +633,7 @@ tzdata==2024.1 ...@@ -641,6 +633,7 @@ tzdata==2024.1
# via pandas # via pandas
tzlocal==5.2 tzlocal==5.2
# via apscheduler # via apscheduler
# via extract-msg
ujson==5.10.0 ujson==5.10.0
# via fastapi # via fastapi
unstructured==0.14.0 unstructured==0.14.0
...@@ -657,7 +650,6 @@ urllib3==2.2.1 ...@@ -657,7 +650,6 @@ urllib3==2.2.1
uvicorn==0.22.0 uvicorn==0.22.0
# via chromadb # via chromadb
# via fastapi # via fastapi
# via litellm
# via open-webui # via open-webui
uvloop==0.19.0 uvloop==0.19.0
# via uvicorn # via uvicorn
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
aiohttp==3.9.5 aiohttp==3.9.5
# via langchain # via langchain
# via langchain-community # via langchain-community
# via litellm
# via open-webui # via open-webui
aiosignal==1.3.1 aiosignal==1.3.1
# via aiohttp # via aiohttp
...@@ -20,11 +19,9 @@ annotated-types==0.6.0 ...@@ -20,11 +19,9 @@ annotated-types==0.6.0
# via pydantic # via pydantic
anyio==4.3.0 anyio==4.3.0
# via httpx # via httpx
# via openai
# via starlette # via starlette
# via watchfiles # via watchfiles
apscheduler==3.10.4 apscheduler==3.10.4
# via litellm
# via open-webui # via open-webui
argon2-cffi==23.1.0 argon2-cffi==23.1.0
# via open-webui # via open-webui
...@@ -38,7 +35,6 @@ av==11.0.0 ...@@ -38,7 +35,6 @@ av==11.0.0
# via faster-whisper # via faster-whisper
backoff==2.2.1 backoff==2.2.1
# via langfuse # via langfuse
# via litellm
# via posthog # via posthog
# via unstructured # via unstructured
bcrypt==4.1.3 bcrypt==4.1.3
...@@ -46,6 +42,7 @@ bcrypt==4.1.3 ...@@ -46,6 +42,7 @@ bcrypt==4.1.3
# via open-webui # via open-webui
# via passlib # via passlib
beautifulsoup4==4.12.3 beautifulsoup4==4.12.3
# via extract-msg
# via unstructured # via unstructured
bidict==0.23.1 bidict==0.23.1
# via python-socketio # via python-socketio
...@@ -83,17 +80,20 @@ chromadb==0.5.0 ...@@ -83,17 +80,20 @@ chromadb==0.5.0
# via open-webui # via open-webui
click==8.1.7 click==8.1.7
# via black # via black
# via duckduckgo-search
# via flask # via flask
# via litellm
# via nltk # via nltk
# via peewee-migrate # via peewee-migrate
# via rq
# via typer # via typer
# via uvicorn # via uvicorn
colorclass==2.2.2
# via oletools
coloredlogs==15.0.1 coloredlogs==15.0.1
# via onnxruntime # via onnxruntime
compressed-rtf==1.0.6
# via extract-msg
cryptography==42.0.7 cryptography==42.0.7
# via litellm # via msoffcrypto-tool
# via pyjwt # via pyjwt
ctranslate2==4.2.1 ctranslate2==4.2.1
# via faster-whisper # via faster-whisper
...@@ -109,33 +109,34 @@ defusedxml==0.7.1 ...@@ -109,33 +109,34 @@ defusedxml==0.7.1
deprecated==1.2.14 deprecated==1.2.14
# via opentelemetry-api # via opentelemetry-api
# via opentelemetry-exporter-otlp-proto-grpc # via opentelemetry-exporter-otlp-proto-grpc
distro==1.9.0
# via openai
dnspython==2.6.1 dnspython==2.6.1
# via email-validator # via email-validator
docx2txt==0.8 docx2txt==0.8
# via open-webui # via open-webui
duckduckgo-search==6.1.5
# via open-webui
easygui==0.98.3
# via oletools
ebcdic==1.1.1
# via extract-msg
ecdsa==0.19.0 ecdsa==0.19.0
# via python-jose # via python-jose
email-validator==2.1.1 email-validator==2.1.1
# via fastapi # via fastapi
# via pydantic
emoji==2.11.1 emoji==2.11.1
# via unstructured # via unstructured
et-xmlfile==1.1.0 et-xmlfile==1.1.0
# via openpyxl # via openpyxl
extract-msg==0.48.5
# via open-webui
fake-useragent==1.5.1 fake-useragent==1.5.1
# via open-webui # via open-webui
fastapi==0.111.0 fastapi==0.111.0
# via chromadb # via chromadb
# via fastapi-sso
# via langchain-chroma # via langchain-chroma
# via litellm
# via open-webui # via open-webui
fastapi-cli==0.0.4 fastapi-cli==0.0.4
# via fastapi # via fastapi
fastapi-sso==0.10.0
# via litellm
faster-whisper==1.0.2 faster-whisper==1.0.2
# via open-webui # via open-webui
filelock==3.14.0 filelock==3.14.0
...@@ -191,8 +192,6 @@ grpcio==1.63.0 ...@@ -191,8 +192,6 @@ grpcio==1.63.0
# via opentelemetry-exporter-otlp-proto-grpc # via opentelemetry-exporter-otlp-proto-grpc
grpcio-status==1.62.2 grpcio-status==1.62.2
# via google-api-core # via google-api-core
gunicorn==22.0.0
# via litellm
h11==0.14.0 h11==0.14.0
# via httpcore # via httpcore
# via uvicorn # via uvicorn
...@@ -206,9 +205,7 @@ httptools==0.6.1 ...@@ -206,9 +205,7 @@ httptools==0.6.1
# via uvicorn # via uvicorn
httpx==0.27.0 httpx==0.27.0
# via fastapi # via fastapi
# via fastapi-sso
# via langfuse # via langfuse
# via openai
huggingface-hub==0.23.0 huggingface-hub==0.23.0
# via faster-whisper # via faster-whisper
# via sentence-transformers # via sentence-transformers
...@@ -225,7 +222,6 @@ idna==3.7 ...@@ -225,7 +222,6 @@ idna==3.7
# via unstructured-client # via unstructured-client
# via yarl # via yarl
importlib-metadata==7.0.0 importlib-metadata==7.0.0
# via litellm
# via opentelemetry-api # via opentelemetry-api
importlib-resources==6.4.0 importlib-resources==6.4.0
# via chromadb # via chromadb
...@@ -234,7 +230,6 @@ itsdangerous==2.2.0 ...@@ -234,7 +230,6 @@ itsdangerous==2.2.0
jinja2==3.1.4 jinja2==3.1.4
# via fastapi # via fastapi
# via flask # via flask
# via litellm
# via torch # via torch
jmespath==1.0.1 jmespath==1.0.1
# via boto3 # via boto3
...@@ -272,8 +267,8 @@ langsmith==0.1.57 ...@@ -272,8 +267,8 @@ langsmith==0.1.57
# via langchain # via langchain
# via langchain-community # via langchain-community
# via langchain-core # via langchain-core
litellm==1.37.20 lark==1.1.8
# via open-webui # via rtfde
lxml==5.2.2 lxml==5.2.2
# via unstructured # via unstructured
markdown==3.6 markdown==3.6
...@@ -294,6 +289,8 @@ monotonic==1.6 ...@@ -294,6 +289,8 @@ monotonic==1.6
# via posthog # via posthog
mpmath==1.3.0 mpmath==1.3.0
# via sympy # via sympy
msoffcrypto-tool==5.4.1
# via oletools
multidict==6.0.5 multidict==6.0.5
# via aiohttp # via aiohttp
# via yarl # via yarl
...@@ -325,15 +322,19 @@ numpy==1.26.4 ...@@ -325,15 +322,19 @@ numpy==1.26.4
# via transformers # via transformers
# via unstructured # via unstructured
oauthlib==3.2.2 oauthlib==3.2.2
# via fastapi-sso
# via kubernetes # via kubernetes
# via requests-oauthlib # via requests-oauthlib
olefile==0.47
# via extract-msg
# via msoffcrypto-tool
# via oletools
oletools==0.60.1
# via pcodedmp
# via rtfde
onnxruntime==1.17.3 onnxruntime==1.17.3
# via chromadb # via chromadb
# via faster-whisper # via faster-whisper
# via rapidocr-onnxruntime # via rapidocr-onnxruntime
openai==1.28.1
# via litellm
opencv-python==4.9.0.80 opencv-python==4.9.0.80
# via rapidocr-onnxruntime # via rapidocr-onnxruntime
opencv-python-headless==4.9.0.80 opencv-python-headless==4.9.0.80
...@@ -375,15 +376,14 @@ ordered-set==4.1.0 ...@@ -375,15 +376,14 @@ ordered-set==4.1.0
# via deepdiff # via deepdiff
orjson==3.10.3 orjson==3.10.3
# via chromadb # via chromadb
# via duckduckgo-search
# via fastapi # via fastapi
# via langsmith # via langsmith
# via litellm
overrides==7.7.0 overrides==7.7.0
# via chromadb # via chromadb
packaging==23.2 packaging==23.2
# via black # via black
# via build # via build
# via gunicorn
# via huggingface-hub # via huggingface-hub
# via langchain-core # via langchain-core
# via langfuse # via langfuse
...@@ -397,6 +397,8 @@ passlib==1.7.4 ...@@ -397,6 +397,8 @@ passlib==1.7.4
# via open-webui # via open-webui
pathspec==0.12.1 pathspec==0.12.1
# via black # via black
pcodedmp==1.2.6
# via oletools
peewee==3.17.5 peewee==3.17.5
# via open-webui # via open-webui
# via peewee-migrate # via peewee-migrate
...@@ -437,27 +439,27 @@ pycparser==2.22 ...@@ -437,27 +439,27 @@ pycparser==2.22
pydantic==2.7.1 pydantic==2.7.1
# via chromadb # via chromadb
# via fastapi # via fastapi
# via fastapi-sso
# via google-generativeai # via google-generativeai
# via langchain # via langchain
# via langchain-core # via langchain-core
# via langfuse # via langfuse
# via langsmith # via langsmith
# via open-webui # via open-webui
# via openai
pydantic-core==2.18.2 pydantic-core==2.18.2
# via pydantic # via pydantic
pydub==0.25.1
# via open-webui
pygments==2.18.0 pygments==2.18.0
# via rich # via rich
pyjwt==2.8.0 pyjwt==2.8.0
# via litellm
# via open-webui # via open-webui
pymysql==1.1.0 pymysql==1.1.0
# via open-webui # via open-webui
pypandoc==1.13 pypandoc==1.13
# via open-webui # via open-webui
pyparsing==3.1.2 pyparsing==2.4.7
# via httplib2 # via httplib2
# via oletools
pypdf==4.2.0 pypdf==4.2.0
# via open-webui # via open-webui
# via unstructured-client # via unstructured-client
...@@ -465,6 +467,8 @@ pypika==0.48.9 ...@@ -465,6 +467,8 @@ pypika==0.48.9
# via chromadb # via chromadb
pyproject-hooks==1.1.0 pyproject-hooks==1.1.0
# via build # via build
pyreqwest-impersonate==0.4.7
# via duckduckgo-search
python-dateutil==2.9.0.post0 python-dateutil==2.9.0.post0
# via botocore # via botocore
# via kubernetes # via kubernetes
...@@ -472,7 +476,6 @@ python-dateutil==2.9.0.post0 ...@@ -472,7 +476,6 @@ python-dateutil==2.9.0.post0
# via posthog # via posthog
# via unstructured-client # via unstructured-client
python-dotenv==1.0.1 python-dotenv==1.0.1
# via litellm
# via uvicorn # via uvicorn
python-engineio==4.9.0 python-engineio==4.9.0
# via python-socketio # via python-socketio
...@@ -484,7 +487,6 @@ python-magic==0.4.27 ...@@ -484,7 +487,6 @@ python-magic==0.4.27
# via unstructured # via unstructured
python-multipart==0.0.9 python-multipart==0.0.9
# via fastapi # via fastapi
# via litellm
# via open-webui # via open-webui
python-socketio==5.11.2 python-socketio==5.11.2
# via open-webui # via open-webui
...@@ -503,7 +505,6 @@ pyyaml==6.0.1 ...@@ -503,7 +505,6 @@ pyyaml==6.0.1
# via langchain # via langchain
# via langchain-community # via langchain-community
# via langchain-core # via langchain-core
# via litellm
# via rapidocr-onnxruntime # via rapidocr-onnxruntime
# via transformers # via transformers
# via uvicorn # via uvicorn
...@@ -513,11 +514,10 @@ rapidfuzz==3.9.0 ...@@ -513,11 +514,10 @@ rapidfuzz==3.9.0
# via unstructured # via unstructured
rapidocr-onnxruntime==1.3.22 rapidocr-onnxruntime==1.3.22
# via open-webui # via open-webui
redis==5.0.4 red-black-tree-mod==1.20
# via rq # via extract-msg
regex==2024.5.10 regex==2024.5.10
# via nltk # via nltk
# via tiktoken
# via transformers # via transformers
requests==2.32.2 requests==2.32.2
# via chromadb # via chromadb
...@@ -527,11 +527,9 @@ requests==2.32.2 ...@@ -527,11 +527,9 @@ requests==2.32.2
# via langchain # via langchain
# via langchain-community # via langchain-community
# via langsmith # via langsmith
# via litellm
# via open-webui # via open-webui
# via posthog # via posthog
# via requests-oauthlib # via requests-oauthlib
# via tiktoken
# via transformers # via transformers
# via unstructured # via unstructured
# via unstructured-client # via unstructured-client
...@@ -540,11 +538,11 @@ requests-oauthlib==2.0.0 ...@@ -540,11 +538,11 @@ requests-oauthlib==2.0.0
# via kubernetes # via kubernetes
rich==13.7.1 rich==13.7.1
# via typer # via typer
rq==1.16.2
# via litellm
rsa==4.9 rsa==4.9
# via google-auth # via google-auth
# via python-jose # via python-jose
rtfde==0.1.1
# via extract-msg
s3transfer==0.10.1 s3transfer==0.10.1
# via boto3 # via boto3
safetensors==0.4.3 safetensors==0.4.3
...@@ -577,7 +575,6 @@ six==1.16.0 ...@@ -577,7 +575,6 @@ six==1.16.0
sniffio==1.3.1 sniffio==1.3.1
# via anyio # via anyio
# via httpx # via httpx
# via openai
soupsieve==2.5 soupsieve==2.5
# via beautifulsoup4 # via beautifulsoup4
sqlalchemy==2.0.30 sqlalchemy==2.0.30
...@@ -597,12 +594,9 @@ tenacity==8.3.0 ...@@ -597,12 +594,9 @@ tenacity==8.3.0
# via langchain-core # via langchain-core
threadpoolctl==3.5.0 threadpoolctl==3.5.0
# via scikit-learn # via scikit-learn
tiktoken==0.6.0
# via litellm
tokenizers==0.15.2 tokenizers==0.15.2
# via chromadb # via chromadb
# via faster-whisper # via faster-whisper
# via litellm
# via transformers # via transformers
torch==2.3.0 torch==2.3.0
# via sentence-transformers # via sentence-transformers
...@@ -611,7 +605,6 @@ tqdm==4.66.4 ...@@ -611,7 +605,6 @@ tqdm==4.66.4
# via google-generativeai # via google-generativeai
# via huggingface-hub # via huggingface-hub
# via nltk # via nltk
# via openai
# via sentence-transformers # via sentence-transformers
# via transformers # via transformers
transformers==4.39.3 transformers==4.39.3
...@@ -624,7 +617,6 @@ typing-extensions==4.11.0 ...@@ -624,7 +617,6 @@ typing-extensions==4.11.0
# via fastapi # via fastapi
# via google-generativeai # via google-generativeai
# via huggingface-hub # via huggingface-hub
# via openai
# via opentelemetry-sdk # via opentelemetry-sdk
# via pydantic # via pydantic
# via pydantic-core # via pydantic-core
...@@ -641,6 +633,7 @@ tzdata==2024.1 ...@@ -641,6 +633,7 @@ tzdata==2024.1
# via pandas # via pandas
tzlocal==5.2 tzlocal==5.2
# via apscheduler # via apscheduler
# via extract-msg
ujson==5.10.0 ujson==5.10.0
# via fastapi # via fastapi
unstructured==0.14.0 unstructured==0.14.0
...@@ -657,7 +650,6 @@ urllib3==2.2.1 ...@@ -657,7 +650,6 @@ urllib3==2.2.1
uvicorn==0.22.0 uvicorn==0.22.0
# via chromadb # via chromadb
# via fastapi # via fastapi
# via litellm
# via open-webui # via open-webui
uvloop==0.19.0 uvloop==0.19.0
# via uvicorn # via uvicorn
......
...@@ -92,10 +92,18 @@ select { ...@@ -92,10 +92,18 @@ select {
visibility: hidden; visibility: hidden;
} }
.scrollbar-hidden::-webkit-scrollbar-corner {
display: none;
}
.scrollbar-none::-webkit-scrollbar { .scrollbar-none::-webkit-scrollbar {
display: none; /* for Chrome, Safari and Opera */ display: none; /* for Chrome, Safari and Opera */
} }
.scrollbar-none::-webkit-scrollbar-corner {
display: none;
}
.scrollbar-none { .scrollbar-none {
-ms-overflow-style: none; /* IE and Edge */ -ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */ scrollbar-width: none; /* Firefox */
...@@ -111,3 +119,16 @@ input::-webkit-inner-spin-button { ...@@ -111,3 +119,16 @@ input::-webkit-inner-spin-button {
input[type='number'] { input[type='number'] {
-moz-appearance: textfield; /* Firefox */ -moz-appearance: textfield; /* Firefox */
} }
.cm-editor {
height: 100%;
width: 100%;
}
.cm-scroller {
@apply scrollbar-hidden;
}
.cm-editor.cm-focused {
outline: none;
}
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
} else if (localStorage.theme && localStorage.theme === 'system') { } else if (localStorage.theme && localStorage.theme === 'system') {
systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches; systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.classList.add(systemTheme ? 'dark' : 'light'); document.documentElement.classList.add(systemTheme ? 'dark' : 'light');
} else if (localStorage.theme && localStorage.theme === 'her') {
document.documentElement.classList.add('dark');
document.documentElement.classList.add('her');
} else { } else {
document.documentElement.classList.add('dark'); document.documentElement.classList.add('dark');
} }
...@@ -68,17 +71,67 @@ ...@@ -68,17 +71,67 @@
</style> </style>
<img <img
id="logo"
style=" style="
position: absolute; position: absolute;
width: 6rem; width: 6rem;
height: 6rem; height: 6rem;
top: 46%; top: 41%;
left: 50%;
margin-left: -3rem;
"
src="/logo.svg"
/>
<img
id="logo-her"
style="
position: absolute;
width: 13rem;
height: 13rem;
top: 33%;
left: 50%; left: 50%;
margin: -40px 0 0 -40px; margin-left: -6.5rem;
" "
src="/logo.svg" src="/logo.svg"
class="animate-pulse-fast"
/> />
<div
id="progress-background"
style="
position: absolute;
top: 58%;
left: 50%;
margin-left: -12rem;
width: 24rem;
height: 0.75rem;
border-radius: 9999px;
background-color: #fafafa9a;
"
class="bg-white"
></div>
<div
id="progress-bar"
style="
position: absolute;
top: 58%;
left: 50%;
margin-left: -12rem;
height: 0.75rem;
border-radius: 9999px;
background-color: #fff;
width: 0rem;
"
class="bg-white"
></div>
<!-- <span style="position: absolute; bottom: 32px; left: 50%; margin: -36px 0 0 -36px"> <!-- <span style="position: absolute; bottom: 32px; left: 50%; margin: -36px 0 0 -36px">
Footer content Footer content
</span> --> </span> -->
...@@ -101,4 +154,46 @@ ...@@ -101,4 +154,46 @@
html.dark #splash-screen img { html.dark #splash-screen img {
filter: invert(1); filter: invert(1);
} }
html.her #splash-screen {
background: #983724;
}
#logo-her {
display: none;
}
#progress-background {
display: none;
}
#progress-bar {
display: none;
}
html.her #logo {
display: none;
}
html.her #logo-her {
display: block;
filter: invert(1);
}
html.her #progress-background {
display: block;
}
html.her #progress-bar {
display: block;
}
@keyframes pulse {
50% {
opacity: 0.65;
}
}
.animate-pulse-fast {
animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
</style> </style>
import { WEBUI_API_BASE_URL } from '$lib/constants';
export const createNewTool = async (token: string, tool: object) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/create`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
},
body: JSON.stringify({
...tool
})
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const getTools = async (token: string = '') => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/tools`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const exportTools = async (token: string = '') => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/export`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const getToolById = async (token: string, id: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const updateToolById = async (token: string, id: string, tool: object) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/update`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
},
body: JSON.stringify({
...tool
})
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const deleteToolById = async (token: string, id: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/delete`, {
method: 'DELETE',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
...@@ -22,6 +22,39 @@ export const getGravatarUrl = async (email: string) => { ...@@ -22,6 +22,39 @@ export const getGravatarUrl = async (email: string) => {
return res; return res;
}; };
export const formatPythonCode = async (code: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/utils/code/format`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
code: code
})
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
console.log(err);
error = err;
if (err.detail) {
error = err.detail;
}
return null;
});
if (error) {
throw error;
}
return res;
};
export const downloadChatAsPDF = async (chat: object) => { export const downloadChatAsPDF = async (chat: object) => {
let error = null; let error = null;
......
...@@ -11,7 +11,15 @@ ...@@ -11,7 +11,15 @@
export let saveHandler: Function; export let saveHandler: Function;
let webConfig = null; let webConfig = null;
let webSearchEngines = ['searxng', 'google_pse', 'brave', 'serpstack', 'serper', 'serply']; let webSearchEngines = [
'searxng',
'google_pse',
'brave',
'serpstack',
'serper',
'serply',
'duckduckgo'
];
let youtubeLanguage = 'en'; let youtubeLanguage = 'en';
let youtubeTranslation = null; let youtubeTranslation = null;
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
banners, banners,
user, user,
socket, socket,
showCallOverlay showCallOverlay,
tools
} from '$lib/stores'; } from '$lib/stores';
import { import {
convertMessagesToHistory, convertMessagesToHistory,
...@@ -73,6 +74,10 @@ ...@@ -73,6 +74,10 @@
let selectedModels = ['']; let selectedModels = [''];
let atSelectedModel: Model | undefined; let atSelectedModel: Model | undefined;
let selectedModelIds = [];
$: selectedModelIds = atSelectedModel !== undefined ? [atSelectedModel.id] : selectedModels;
let selectedToolIds = [];
let webSearchEnabled = false; let webSearchEnabled = false;
let chat = null; let chat = null;
...@@ -687,6 +692,7 @@ ...@@ -687,6 +692,7 @@
}, },
format: $settings.requestFormat ?? undefined, format: $settings.requestFormat ?? undefined,
keep_alive: $settings.keepAlive ?? undefined, keep_alive: $settings.keepAlive ?? undefined,
tool_ids: selectedToolIds.length > 0 ? selectedToolIds : undefined,
docs: docs.length > 0 ? docs : undefined, docs: docs.length > 0 ? docs : undefined,
citations: docs.length > 0, citations: docs.length > 0,
chat_id: $chatId chat_id: $chatId
...@@ -948,6 +954,7 @@ ...@@ -948,6 +954,7 @@
top_p: $settings?.params?.top_p ?? undefined, top_p: $settings?.params?.top_p ?? undefined,
frequency_penalty: $settings?.params?.frequency_penalty ?? undefined, frequency_penalty: $settings?.params?.frequency_penalty ?? undefined,
max_tokens: $settings?.params?.max_tokens ?? undefined, max_tokens: $settings?.params?.max_tokens ?? undefined,
tool_ids: selectedToolIds.length > 0 ? selectedToolIds : undefined,
docs: docs.length > 0 ? docs : undefined, docs: docs.length > 0 ? docs : undefined,
citations: docs.length > 0, citations: docs.length > 0,
chat_id: $chatId chat_id: $chatId
...@@ -1274,8 +1281,16 @@ ...@@ -1274,8 +1281,16 @@
bind:files bind:files
bind:prompt bind:prompt
bind:autoScroll bind:autoScroll
bind:selectedToolIds
bind:webSearchEnabled bind:webSearchEnabled
bind:atSelectedModel bind:atSelectedModel
availableToolIds={selectedModelIds.reduce((a, e, i, arr) => {
const model = $models.find((m) => m.id === e);
if (model?.info?.meta?.toolIds ?? false) {
return [...new Set([...a, ...model.info.meta.toolIds])];
}
return a;
}, [])}
{selectedModels} {selectedModels}
{messages} {messages}
{submitPrompt} {submitPrompt}
......
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
showSidebar, showSidebar,
models, models,
config, config,
showCallOverlay showCallOverlay,
tools,
user as _user
} from '$lib/stores'; } from '$lib/stores';
import { blobToFile, calculateSHA256, findWordIndices } from '$lib/utils'; import { blobToFile, calculateSHA256, findWordIndices } from '$lib/utils';
...@@ -58,6 +60,8 @@ ...@@ -58,6 +60,8 @@
export let files = []; export let files = [];
export let availableToolIds = [];
export let selectedToolIds = [];
export let webSearchEnabled = false; export let webSearchEnabled = false;
export let prompt = ''; export let prompt = '';
...@@ -653,6 +657,17 @@ ...@@ -653,6 +657,17 @@
<div class=" ml-0.5 self-end mb-1.5 flex space-x-1"> <div class=" ml-0.5 self-end mb-1.5 flex space-x-1">
<InputMenu <InputMenu
bind:webSearchEnabled bind:webSearchEnabled
bind:selectedToolIds
tools={$tools.reduce((a, e, i, arr) => {
if (availableToolIds.includes(e.id) || ($_user?.role ?? 'user') === 'admin') {
a[e.id] = {
name: e.name,
description: e.meta.description,
enabled: false
};
}
return a;
}, {})}
uploadFilesHandler={() => { uploadFilesHandler={() => {
filesInputElement.click(); filesInputElement.click();
}} }}
......
...@@ -4,24 +4,33 @@ ...@@ -4,24 +4,33 @@
import { getContext } from 'svelte'; import { getContext } from 'svelte';
import Dropdown from '$lib/components/common/Dropdown.svelte'; import Dropdown from '$lib/components/common/Dropdown.svelte';
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
import Pencil from '$lib/components/icons/Pencil.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte';
import Tags from '$lib/components/chat/Tags.svelte';
import Share from '$lib/components/icons/Share.svelte';
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
import DocumentArrowUpSolid from '$lib/components/icons/DocumentArrowUpSolid.svelte'; import DocumentArrowUpSolid from '$lib/components/icons/DocumentArrowUpSolid.svelte';
import Switch from '$lib/components/common/Switch.svelte'; import Switch from '$lib/components/common/Switch.svelte';
import GlobeAltSolid from '$lib/components/icons/GlobeAltSolid.svelte'; import GlobeAltSolid from '$lib/components/icons/GlobeAltSolid.svelte';
import { config } from '$lib/stores'; import { config } from '$lib/stores';
import WrenchSolid from '$lib/components/icons/WrenchSolid.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
export let uploadFilesHandler: Function; export let uploadFilesHandler: Function;
export let selectedToolIds: string[] = [];
export let webSearchEnabled: boolean; export let webSearchEnabled: boolean;
export let tools = {};
export let onClose: Function; export let onClose: Function;
$: tools = Object.fromEntries(
Object.keys(tools).map((toolId) => [
toolId,
{
...tools[toolId],
enabled: selectedToolIds.includes(toolId)
}
])
);
let show = false; let show = false;
</script> </script>
...@@ -39,20 +48,48 @@ ...@@ -39,20 +48,48 @@
<div slot="content"> <div slot="content">
<DropdownMenu.Content <DropdownMenu.Content
class="w-full max-w-[190px] rounded-xl px-1 py-1 border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow" class="w-full max-w-[200px] rounded-xl px-1 py-1 border-gray-300/30 dark:border-gray-700/50 z-50 bg-white dark:bg-gray-850 dark:text-white shadow"
sideOffset={15} sideOffset={15}
alignOffset={-8} alignOffset={-8}
side="top" side="top"
align="start" align="start"
transition={flyAndScale} transition={flyAndScale}
> >
{#if Object.keys(tools).length > 0}
<div class=" max-h-28 overflow-y-auto scrollbar-hidden">
{#each Object.keys(tools) as toolId}
<div
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer rounded-xl"
>
<div class="flex-1 flex items-center gap-2">
<WrenchSolid />
<Tooltip content={tools[toolId]?.description ?? ''} className="flex-1">
<div class=" line-clamp-1">{tools[toolId].name}</div>
</Tooltip>
</div>
<Switch
bind:state={tools[toolId].enabled}
on:change={(e) => {
selectedToolIds = e.detail
? [...selectedToolIds, toolId]
: selectedToolIds.filter((id) => id !== toolId);
}}
/>
</div>
{/each}
</div>
<hr class="border-gray-100 dark:border-gray-800 my-1" />
{/if}
{#if $config?.features?.enable_web_search} {#if $config?.features?.enable_web_search}
<div <div
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer rounded-xl" class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer rounded-xl"
> >
<div class="flex-1 flex items-center gap-2"> <div class="flex-1 flex items-center gap-2">
<GlobeAltSolid /> <GlobeAltSolid />
<div class="flex items-center">{$i18n.t('Web Search')}</div> <div class=" line-clamp-1">{$i18n.t('Web Search')}</div>
</div> </div>
<Switch bind:state={webSearchEnabled} /> <Switch bind:state={webSearchEnabled} />
...@@ -68,7 +105,7 @@ ...@@ -68,7 +105,7 @@
}} }}
> >
<DocumentArrowUpSolid /> <DocumentArrowUpSolid />
<div class="flex items-center">{$i18n.t('Upload Files')}</div> <div class=" line-clamp-1">{$i18n.t('Upload Files')}</div>
</DropdownMenu.Item> </DropdownMenu.Item>
</DropdownMenu.Content> </DropdownMenu.Content>
</div> </div>
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
</script> </script>
{#key mounted} {#key mounted}
<div class="m-auto w-full max-w-6xl px-8 lg:px-24 pb-16"> <div class="m-auto w-full max-w-6xl px-8 lg:px-24 pb-10">
<div class="flex justify-start"> <div class="flex justify-start">
<div class="flex -space-x-4 mb-1" in:fade={{ duration: 200 }}> <div class="flex -space-x-4 mb-1" in:fade={{ duration: 200 }}>
{#each models as model, modelIdx} {#each models as model, modelIdx}
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
</div> </div>
{/if} {/if}
{:else} {:else}
<div class=" font-medium text-gray-400 dark:text-gray-500"> <div class=" font-medium text-gray-400 dark:text-gray-500 line-clamp-1">
{$i18n.t('How can I help you today?')} {$i18n.t('How can I help you today?')}
</div> </div>
{/if} {/if}
......
...@@ -152,6 +152,7 @@ ...@@ -152,6 +152,7 @@
toast.error(error); toast.error(error);
// opts.callback({ success: false, error, modelName: opts.modelName }); // opts.callback({ success: false, error, modelName: opts.modelName });
break;
} }
} }
......
...@@ -140,6 +140,7 @@ ...@@ -140,6 +140,7 @@
<option value="dark">🌑 {$i18n.t('Dark')}</option> <option value="dark">🌑 {$i18n.t('Dark')}</option>
<option value="oled-dark">🌃 {$i18n.t('OLED Dark')}</option> <option value="oled-dark">🌃 {$i18n.t('OLED Dark')}</option>
<option value="light">☀️ {$i18n.t('Light')}</option> <option value="light">☀️ {$i18n.t('Light')}</option>
<option value="her">🌷 Her</option>
<!-- <option value="rose-pine dark">🪻 {$i18n.t('Rosé Pine')}</option> <!-- <option value="rose-pine dark">🪻 {$i18n.t('Rosé Pine')}</option>
<option value="rose-pine-dawn light">🌷 {$i18n.t('Rosé Pine Dawn')}</option> --> <option value="rose-pine-dawn light">🌷 {$i18n.t('Rosé Pine Dawn')}</option> -->
</select> </select>
......
<script lang="ts">
import { basicSetup, EditorView } from 'codemirror';
import { keymap, placeholder } from '@codemirror/view';
import { Compartment, EditorState } from '@codemirror/state';
import { acceptCompletion } from '@codemirror/autocomplete';
import { indentWithTab } from '@codemirror/commands';
import { indentUnit } from '@codemirror/language';
import { python } from '@codemirror/lang-python';
import { oneDark } from '@codemirror/theme-one-dark';
import { onMount, createEventDispatcher } from 'svelte';
import { formatPythonCode } from '$lib/apis/utils';
import { toast } from 'svelte-sonner';
const dispatch = createEventDispatcher();
export let boilerplate = '';
export let value = '';
let codeEditor;
let isDarkMode = false;
let editorTheme = new Compartment();
export const formatPythonCodeHandler = async () => {
if (codeEditor) {
const res = await formatPythonCode(value).catch((error) => {
toast.error(error);
return null;
});
if (res && res.code) {
const formattedCode = res.code;
codeEditor.dispatch({
changes: [{ from: 0, to: codeEditor.state.doc.length, insert: formattedCode }]
});
toast.success('Code formatted successfully');
return true;
}
return false;
}
return false;
};
let extensions = [
basicSetup,
keymap.of([{ key: 'Tab', run: acceptCompletion }, indentWithTab]),
python(),
indentUnit.of(' '),
placeholder('Enter your code here...'),
EditorView.updateListener.of((e) => {
if (e.docChanged) {
value = e.state.doc.toString();
}
}),
editorTheme.of([])
];
onMount(() => {
console.log(value);
if (value === '') {
value = boilerplate;
}
// Check if html class has dark mode
isDarkMode = document.documentElement.classList.contains('dark');
// python code editor, highlight python code
codeEditor = new EditorView({
state: EditorState.create({
doc: value,
extensions: extensions
}),
parent: document.getElementById('code-textarea')
});
if (isDarkMode) {
codeEditor.dispatch({
effects: editorTheme.reconfigure(oneDark)
});
}
// listen to html class changes this should fire only when dark mode is toggled
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
const _isDarkMode = document.documentElement.classList.contains('dark');
if (_isDarkMode !== isDarkMode) {
isDarkMode = _isDarkMode;
if (_isDarkMode) {
codeEditor.dispatch({
effects: editorTheme.reconfigure(oneDark)
});
} else {
codeEditor.dispatch({
effects: editorTheme.reconfigure()
});
}
}
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
const keydownHandler = async (e) => {
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
e.preventDefault();
dispatch('save');
}
// Format code when Ctrl + Shift + F is pressed
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'f') {
e.preventDefault();
await formatPythonCodeHandler();
}
};
document.addEventListener('keydown', keydownHandler);
return () => {
observer.disconnect();
document.removeEventListener('keydown', keydownHandler);
};
});
</script>
<div id="code-textarea" class="h-full w-full" />
<script lang="ts">
import { onMount, createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
import { flyAndScale } from '$lib/utils/transitions';
const dispatch = createEventDispatcher();
export let title = 'Confirm your action';
export let message = 'This action cannot be undone. Do you wish to continue?';
export let show = false;
let modalElement = null;
let mounted = false;
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
console.log('Escape');
show = false;
}
};
onMount(() => {
mounted = true;
});
$: if (mounted) {
if (show) {
window.addEventListener('keydown', handleKeyDown);
document.body.style.overflow = 'hidden';
} else {
window.removeEventListener('keydown', handleKeyDown);
document.body.style.overflow = 'unset';
}
}
</script>
{#if show}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
bind:this={modalElement}
class=" fixed top-0 right-0 left-0 bottom-0 bg-black/60 w-full min-h-screen h-screen flex justify-center z-[9999] overflow-hidden overscroll-contain"
in:fade={{ duration: 10 }}
on:mousedown={() => {
show = false;
}}
>
<div
class=" m-auto rounded-2xl max-w-full w-[32rem] mx-2 bg-gray-50 dark:bg-gray-950 shadow-3xl border border-gray-850"
in:flyAndScale
on:mousedown={(e) => {
e.stopPropagation();
}}
>
<div class="px-[1.75rem] py-6">
<div class=" text-lg font-semibold dark:text-gray-200 mb-2.5">{title}</div>
<slot>
<div class=" text-sm text-gray-500">
{message}
</div>
</slot>
<div class="mt-6 flex justify-between gap-1.5">
<button
class="bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-white font-medium w-full py-2.5 rounded-lg transition"
on:click={() => {
show = false;
}}
type="button"
>
Cancel
</button>
<button
class="bg-gray-900 hover:bg-gray-850 text-gray-100 dark:bg-gray-100 dark:hover:bg-white dark:text-gray-800 font-medium w-full py-2.5 rounded-lg transition"
on:click={() => {
show = false;
dispatch('confirm');
}}
type="button"
>
Confirm
</button>
</div>
</div>
</div>
</div>
{/if}
<style>
.modal-content {
animation: scaleUp 0.1s ease-out forwards;
}
@keyframes scaleUp {
from {
transform: scale(0.985);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
</style>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment