llmstudio 0.3__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {llmstudio-0.3 → llmstudio-0.3.2}/PKG-INFO +5 -5
- {llmstudio-0.3 → llmstudio-0.3.2}/README.md +1 -1
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/.env.template +4 -6
- llmstudio-0.3.2/llmstudio/cli.py +112 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/engine/__init__.py +6 -8
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/engine/config.yaml +10 -81
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/engine/providers/__init__.py +0 -1
- llmstudio-0.3.2/llmstudio/engine/providers/anthropic.py +91 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/engine/providers/azure.py +15 -11
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/engine/providers/ollama.py +33 -2
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/engine/providers/openai.py +14 -7
- llmstudio-0.3.2/llmstudio/engine/providers/provider.py +377 -0
- llmstudio-0.3.2/llmstudio/llm/__init__.py +102 -0
- llmstudio-0.3.2/llmstudio/llm/langchain.py +57 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/tests/engine/test_engine.py +2 -2
- llmstudio-0.3.2/llmstudio/tracking/__init__.py +96 -0
- llmstudio-0.3.2/llmstudio/tracking/crud.py +29 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/tracking/database.py +10 -3
- llmstudio-0.3.2/llmstudio/tracking/models.py +22 -0
- llmstudio-0.3.2/llmstudio/tracking/schemas.py +36 -0
- llmstudio-0.3.2/llmstudio/tracking/tracker.py +24 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/__init__.py +8 -7
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/package.json +1 -0
- llmstudio-0.3.2/llmstudio/ui/src/app/(llm)/dashboard/hooks/useDashboardFetch.tsx +33 -0
- llmstudio-0.3.2/llmstudio/ui/src/app/(llm)/dashboard/page.tsx +118 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/DataTable/DataTable.tsx +1 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/DataTable/columns.tsx +66 -8
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/hooks/useChat.tsx +3 -3
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/hooks/useExport.tsx +11 -8
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/hooks/useLogsFetch.tsx +3 -1
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/hooks/useModelFetch.tsx +3 -1
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/hooks/useParameterFetch.tsx +1 -1
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/store.tsx +4 -4
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/Header/index.tsx +6 -1
- llmstudio-0.3.2/llmstudio/ui/tailwind.config.js +192 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/pyproject.toml +5 -5
- llmstudio-0.3/llmstudio/cli.py +0 -51
- llmstudio-0.3/llmstudio/engine/providers/anthropic.py +0 -54
- llmstudio-0.3/llmstudio/engine/providers/cohere.py +0 -55
- llmstudio-0.3/llmstudio/engine/providers/provider.py +0 -205
- llmstudio-0.3/llmstudio/llm/__init__.py +0 -37
- llmstudio-0.3/llmstudio/tracking/__init__.py +0 -115
- llmstudio-0.3/llmstudio/tracking/crud.py +0 -61
- llmstudio-0.3/llmstudio/tracking/models.py +0 -62
- llmstudio-0.3/llmstudio/tracking/schemas.py +0 -73
- llmstudio-0.3/llmstudio/tracking/tracker.py +0 -30
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable/ColumnHeader.tsx +0 -71
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable/FacetedFilter.tsx +0 -147
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable/Pagination.tsx +0 -97
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable/UserNav.tsx +0 -58
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable/ViewOptions.tsx +0 -59
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template/RowActions.tsx +0 -69
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template/Toolbar.tsx +0 -61
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template/columns.tsx +0 -123
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template/data/data.tsx +0 -71
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template/data/schema.tsx +0 -13
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template/data/tasks.json +0 -702
- llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template/index.tsx +0 -126
- llmstudio-0.3/llmstudio/ui/tailwind.config.js +0 -76
- llmstudio-0.3/llmstudio/ui/tailwind.config.ts +0 -20
- {llmstudio-0.3 → llmstudio-0.3.2}/LICENSE +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/__init__.py +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/client.py +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/tests/__init__.py +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/tests/conftest.py +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/tests/engine/test_providers.py +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/.eslintrc.json +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/.gitignore +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/.prettierrc.json +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/components.json +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/global.d.ts +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/next.config.js +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/package-lock.json +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/postcss.config.js +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/logo.json +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/ai.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/arrow.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/compare.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/home.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/load.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/magic.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/play.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/playground.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/plus.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/settings.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/public/svg/sparkles.svg +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/compare/page.tsx +0 -0
- {llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template → llmstudio-0.3.2/llmstudio/ui/src/app/(llm)/playground/components/DataTable}/ColumnHeader.tsx +0 -0
- {llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template → llmstudio-0.3.2/llmstudio/ui/src/app/(llm)/playground/components/DataTable}/FacetedFilter.tsx +0 -0
- {llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template → llmstudio-0.3.2/llmstudio/ui/src/app/(llm)/playground/components/DataTable}/Pagination.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/DataTable/RowActions.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/DataTable/Toolbar.tsx +0 -0
- {llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template → llmstudio-0.3.2/llmstudio/ui/src/app/(llm)/playground/components/DataTable}/UserNav.tsx +0 -0
- {llmstudio-0.3/llmstudio/ui/src/app/(llm)/playground/components/DataTable Template → llmstudio-0.3.2/llmstudio/ui/src/app/(llm)/playground/components/DataTable}/ViewOptions.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/Input.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/LogSheet.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/ModelItem.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/ModelSelector.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/Output.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/Parameters.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/components/index.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/(llm)/playground/page.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/favicon.ico +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/globals.css +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/layout.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/app/page.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/CodeBlock/index.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/CopyButton/index.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/Markdown/index.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/Theme/index.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/Toaster/index.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/theme-provider.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/accordion.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/alert-dialog.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/alert.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/aspect-ratio.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/avatar.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/badge.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/button.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/calendar.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/card.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/checkbox.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/collapsible.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/command.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/context-menu.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/dialog.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/dropdown-menu.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/form.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/hover-card.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/input.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/label.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/menubar.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/navigation-menu.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/popover.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/progress.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/radio-group.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/scroll-area.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/select.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/separator.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/sheet.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/skeleton.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/slider.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/switch.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/table.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/tabs.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/textarea.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/toast.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/toaster.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/toggle-group.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/toggle.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/tooltip.tsx +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/components/ui/use-toast.ts +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/src/lib/utils.ts +0 -0
- {llmstudio-0.3 → llmstudio-0.3.2}/llmstudio/ui/tsconfig.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: llmstudio
|
|
3
|
-
Version: 0.3
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Prompt Perfection at Your Fingertips
|
|
5
5
|
Home-page: https://llmstudio.ai/
|
|
6
6
|
License: MIT
|
|
@@ -14,14 +14,14 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
17
|
+
Requires-Dist: aiohttp (>=3.9.1,<4.0.0)
|
|
18
|
+
Requires-Dist: anthropic (>=0.16.0,<0.17.0)
|
|
19
19
|
Requires-Dist: fastapi (>=0.108.0,<0.109.0)
|
|
20
|
-
Requires-Dist: langchain (>=0.0.352,<0.0.353)
|
|
21
20
|
Requires-Dist: openai (>=1.6.1,<2.0.0)
|
|
22
21
|
Requires-Dist: pydantic (>=2.5.3,<3.0.0)
|
|
23
22
|
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
|
24
23
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
24
|
+
Requires-Dist: sqlalchemy (>=2.0.27,<3.0.0)
|
|
25
25
|
Requires-Dist: tiktoken (>=0.5.2,<0.6.0)
|
|
26
26
|
Requires-Dist: tokenizer (>=3.4.3,<4.0.0)
|
|
27
27
|
Requires-Dist: uvicorn (>=0.25.0,<0.26.0)
|
|
@@ -123,7 +123,7 @@ Step into the future of AI with LLMstudio, by watching our [introduction video](
|
|
|
123
123
|
## 👨💻 Contributing
|
|
124
124
|
|
|
125
125
|
- Head on to our [Contribution Guide](https://github.com/TensorOpsAI/LLMstudio/tree/main/CONTRIBUTING.md) to see how you can help LLMstudio.
|
|
126
|
-
- Join our [Discord](https://discord.gg/
|
|
126
|
+
- Join our [Discord](https://discord.gg/GkAfPZR9wy) to talk with other LLMstudio enthusiasts.
|
|
127
127
|
|
|
128
128
|
## Training
|
|
129
129
|
|
|
@@ -91,7 +91,7 @@ Step into the future of AI with LLMstudio, by watching our [introduction video](
|
|
|
91
91
|
## 👨💻 Contributing
|
|
92
92
|
|
|
93
93
|
- Head on to our [Contribution Guide](https://github.com/TensorOpsAI/LLMstudio/tree/main/CONTRIBUTING.md) to see how you can help LLMstudio.
|
|
94
|
-
- Join our [Discord](https://discord.gg/
|
|
94
|
+
- Join our [Discord](https://discord.gg/GkAfPZR9wy) to talk with other LLMstudio enthusiasts.
|
|
95
95
|
|
|
96
96
|
## Training
|
|
97
97
|
|
|
@@ -4,11 +4,9 @@ COHERE_API_KEY="your-cohere-api-key"
|
|
|
4
4
|
AZURE_API_KEY=""
|
|
5
5
|
AZURE_API_ENDPOINT=""
|
|
6
6
|
AZURE_API_VERSION=""
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
UI_HOST = "localhost"
|
|
10
|
-
UI_PORT = 3000
|
|
7
|
+
LLMSTUDIO_ENGINE_HOST="localhost"
|
|
8
|
+
LLMSTUDIO_UI_HOST = "localhost"
|
|
11
9
|
LOG_LEVEL = "info"
|
|
12
|
-
|
|
13
|
-
TRACKING_PORT=8080
|
|
10
|
+
LLMSTUDIO_TRACKING_HOST="localhost"
|
|
14
11
|
BACKEND_TRACKING_URI="sqlite:///./llmstudio_mgmt.db"
|
|
12
|
+
#BACKEND_TRACKING_URI="postgresql://user:1234@0.0.0.0:5556/llmstudio"
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import signal
|
|
3
|
+
import socket
|
|
4
|
+
from threading import Thread
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
import requests
|
|
8
|
+
from dotenv import load_dotenv
|
|
9
|
+
|
|
10
|
+
from llmstudio.engine import run_engine_app
|
|
11
|
+
from llmstudio.tracking import run_tracking_app
|
|
12
|
+
from llmstudio.ui import run_ui_app
|
|
13
|
+
|
|
14
|
+
load_dotenv(os.path.join(os.getcwd(), ".env"))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def assign_port():
|
|
18
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
19
|
+
s.bind(("", 0))
|
|
20
|
+
return s.getsockname()[1]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
os.environ["LLMSTUDIO_ENGINE_PORT"] = str(assign_port())
|
|
24
|
+
os.environ["NEXT_PUBLIC_LLMSTUDIO_ENGINE_PORT"] = os.environ.get(
|
|
25
|
+
"LLMSTUDIO_ENGINE_PORT"
|
|
26
|
+
)
|
|
27
|
+
os.environ["LLMSTUDIO_TRACKING_PORT"] = str(assign_port())
|
|
28
|
+
os.environ["NEXT_PUBLIC_LLMSTUDIO_TRACKING_PORT"] = os.environ.get(
|
|
29
|
+
"LLMSTUDIO_TRACKING_PORT"
|
|
30
|
+
)
|
|
31
|
+
os.environ["LLMSTUDIO_UI_PORT"] = str(assign_port())
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def is_server_running(host, port, path="/health"):
|
|
35
|
+
try:
|
|
36
|
+
response = requests.get(f"http://{host}:{port}{path}")
|
|
37
|
+
if response.status_code == 200 and response.json().get("status") == "healthy":
|
|
38
|
+
return True
|
|
39
|
+
except requests.ConnectionError:
|
|
40
|
+
pass
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def start_server():
|
|
45
|
+
engine_port = int(os.environ.get("LLMSTUDIO_ENGINE_PORT"))
|
|
46
|
+
tracking_port = int(os.environ.get("LLMSTUDIO_TRACKING_PORT"))
|
|
47
|
+
engine_host = os.environ.get("LLMSTUDIO_ENGINE_HOST", "localhost")
|
|
48
|
+
tracking_host = os.environ.get("LLMSTUDIO_TRACKING_HOST", "localhost")
|
|
49
|
+
|
|
50
|
+
if not is_server_running(engine_host, engine_port):
|
|
51
|
+
engine_thread = Thread(target=run_engine_app, daemon=True)
|
|
52
|
+
engine_thread.start()
|
|
53
|
+
|
|
54
|
+
if not is_server_running(tracking_host, tracking_port):
|
|
55
|
+
tracking_thread = Thread(target=run_tracking_app, daemon=True)
|
|
56
|
+
tracking_thread.start()
|
|
57
|
+
|
|
58
|
+
def handle_shutdown(signum, frame):
|
|
59
|
+
print("Shutting down gracefully...")
|
|
60
|
+
os._exit(0)
|
|
61
|
+
|
|
62
|
+
signal.signal(signal.SIGINT, handle_shutdown)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@click.group()
|
|
66
|
+
def main():
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@main.command()
|
|
71
|
+
@click.option("--ui", is_flag=True, help="Start the UI server.")
|
|
72
|
+
def server(ui):
|
|
73
|
+
def handle_shutdown(signum, frame):
|
|
74
|
+
print("Shutting down gracefully...")
|
|
75
|
+
os._exit(0)
|
|
76
|
+
|
|
77
|
+
# Register the signal handler
|
|
78
|
+
signal.signal(signal.SIGINT, handle_shutdown)
|
|
79
|
+
|
|
80
|
+
engine_host = os.getenv("LLMSTUDIO_ENGINE_HOST", "localhost")
|
|
81
|
+
tracking_host = os.getenv("LLMSTUDIO_TRACKING_HOST", "localhost")
|
|
82
|
+
engine_port = int(os.getenv("LLMSTUDIO_ENGINE_PORT"))
|
|
83
|
+
tracking_port = int(os.getenv("LLMSTUDIO_TRACKING_PORT"))
|
|
84
|
+
|
|
85
|
+
# Start the engine if it's not already running
|
|
86
|
+
if not is_server_running(engine_host, engine_port):
|
|
87
|
+
engine_thread = Thread(target=run_engine_app, daemon=True)
|
|
88
|
+
engine_thread.start()
|
|
89
|
+
else:
|
|
90
|
+
print(f"Engine server already running on {engine_host}:{engine_port}")
|
|
91
|
+
|
|
92
|
+
# Start the tracking if it's not already running
|
|
93
|
+
if not is_server_running(tracking_host, tracking_port):
|
|
94
|
+
tracking_thread = Thread(target=run_tracking_app, daemon=True)
|
|
95
|
+
tracking_thread.start()
|
|
96
|
+
else:
|
|
97
|
+
print(f"Tracking server already running on {tracking_host}:{tracking_port}")
|
|
98
|
+
|
|
99
|
+
# Start the UI if requested and not already running
|
|
100
|
+
if ui:
|
|
101
|
+
ui_port = int(os.getenv("LLMSTUDIO_UI_PORT"))
|
|
102
|
+
if not is_server_running("localhost", ui_port):
|
|
103
|
+
ui_thread = Thread(target=run_ui_app, daemon=True)
|
|
104
|
+
ui_thread.start()
|
|
105
|
+
ui_thread.join()
|
|
106
|
+
else:
|
|
107
|
+
print(f"UI server already running on localhost:{ui_port}")
|
|
108
|
+
|
|
109
|
+
if engine_thread:
|
|
110
|
+
engine_thread.join()
|
|
111
|
+
if tracking_thread:
|
|
112
|
+
tracking_thread.join()
|
|
@@ -18,10 +18,6 @@ ENGINE_HEALTH_ENDPOINT = "/health"
|
|
|
18
18
|
ENGINE_TITLE = "LLMstudio Engine API"
|
|
19
19
|
ENGINE_DESCRIPTION = "The core API for LLM interactions"
|
|
20
20
|
ENGINE_VERSION = "0.1.0"
|
|
21
|
-
ENGINE_HOST = os.getenv("ENGINE_HOST", "localhost")
|
|
22
|
-
ENGINE_PORT = int(os.getenv("ENGINE_PORT", 8000))
|
|
23
|
-
ENGINE_URL = f"http://{ENGINE_HOST}:{ENGINE_PORT}"
|
|
24
|
-
LOG_LEVEL = os.getenv("LOG_LEVEL", "critical")
|
|
25
21
|
|
|
26
22
|
|
|
27
23
|
# Models for Configuration
|
|
@@ -89,7 +85,7 @@ def create_engine_app(config: EngineConfig = _load_engine_config()) -> FastAPI:
|
|
|
89
85
|
|
|
90
86
|
app.add_middleware(
|
|
91
87
|
CORSMiddleware,
|
|
92
|
-
allow_origins=["
|
|
88
|
+
allow_origins=["*"],
|
|
93
89
|
allow_credentials=True,
|
|
94
90
|
allow_methods=["*"],
|
|
95
91
|
allow_headers=["*"],
|
|
@@ -168,13 +164,15 @@ def create_engine_app(config: EngineConfig = _load_engine_config()) -> FastAPI:
|
|
|
168
164
|
|
|
169
165
|
|
|
170
166
|
def run_engine_app():
|
|
171
|
-
print(
|
|
167
|
+
print(
|
|
168
|
+
f"Running Engine on http://{os.getenv('LLMSTUDIO_ENGINE_HOST')}:{os.getenv('LLMSTUDIO_ENGINE_PORT')}"
|
|
169
|
+
)
|
|
172
170
|
try:
|
|
173
171
|
engine = create_engine_app()
|
|
174
172
|
uvicorn.run(
|
|
175
173
|
engine,
|
|
176
|
-
host=
|
|
177
|
-
port=
|
|
174
|
+
host=os.getenv("LLMSTUDIO_ENGINE_HOST"),
|
|
175
|
+
port=int(os.getenv("LLMSTUDIO_ENGINE_PORT")),
|
|
178
176
|
)
|
|
179
177
|
except Exception as e:
|
|
180
178
|
print(f"Error running the Engine app: {e}")
|
|
@@ -7,6 +7,16 @@ providers:
|
|
|
7
7
|
keys:
|
|
8
8
|
- ANTHROPIC_API_KEY
|
|
9
9
|
models:
|
|
10
|
+
claude-3-opus-20240229:
|
|
11
|
+
mode: chat
|
|
12
|
+
max_tokens: 200000
|
|
13
|
+
input_token_cost: 0.000015
|
|
14
|
+
output_token_cost: 0.000075
|
|
15
|
+
claude-3-sonnet-2024022:
|
|
16
|
+
mode: chat
|
|
17
|
+
max_tokens: 200000
|
|
18
|
+
input_token_cost: 0.000003
|
|
19
|
+
output_token_cost: 0.000015
|
|
10
20
|
claude-2.1:
|
|
11
21
|
mode: chat
|
|
12
22
|
max_tokens: 200000
|
|
@@ -22,11 +32,6 @@ providers:
|
|
|
22
32
|
max_tokens: 100000
|
|
23
33
|
input_token_cost: 0.00000163
|
|
24
34
|
output_token_cost: 0.00000551
|
|
25
|
-
claude-instant-1:
|
|
26
|
-
mode: chat
|
|
27
|
-
max_tokens: 100000
|
|
28
|
-
input_token_cost: 0.00000163
|
|
29
|
-
output_token_cost: 0.00000551
|
|
30
35
|
parameters:
|
|
31
36
|
temperature:
|
|
32
37
|
name: "Temperature"
|
|
@@ -191,82 +196,6 @@ providers:
|
|
|
191
196
|
min: 0
|
|
192
197
|
max: 2
|
|
193
198
|
step: 0.01
|
|
194
|
-
cohere:
|
|
195
|
-
id: cohere
|
|
196
|
-
name: Cohere
|
|
197
|
-
chat: true
|
|
198
|
-
embed: true
|
|
199
|
-
keys:
|
|
200
|
-
- COHERE_API_KEY
|
|
201
|
-
models:
|
|
202
|
-
command-nightly:
|
|
203
|
-
mode: chat
|
|
204
|
-
max_tokens: 4096
|
|
205
|
-
input_token_cost: 0.000015
|
|
206
|
-
output_token_cost: 0.000015
|
|
207
|
-
command:
|
|
208
|
-
mode: chat
|
|
209
|
-
max_tokens: 4096
|
|
210
|
-
input_token_cost: 0.000015
|
|
211
|
-
output_token_cost: 0.000015
|
|
212
|
-
command-light:
|
|
213
|
-
mode: chat
|
|
214
|
-
max_tokens: 4096
|
|
215
|
-
input_token_cost: 0.000015
|
|
216
|
-
output_token_cost: 0.000015
|
|
217
|
-
command-medium-beta:
|
|
218
|
-
mode: chat
|
|
219
|
-
max_tokens: 4096
|
|
220
|
-
input_token_cost: 0.000015
|
|
221
|
-
output_token_cost: 0.000015
|
|
222
|
-
command-xlarge-beta:
|
|
223
|
-
mode: chat
|
|
224
|
-
max_tokens: 4096
|
|
225
|
-
input_token_cost: 0.000015
|
|
226
|
-
output_token_cost: 0.000015
|
|
227
|
-
parameters:
|
|
228
|
-
temperature:
|
|
229
|
-
name: "Temperature"
|
|
230
|
-
type: float
|
|
231
|
-
default: 0.75
|
|
232
|
-
min: 0
|
|
233
|
-
max: 5
|
|
234
|
-
step: 0.01
|
|
235
|
-
max_tokens:
|
|
236
|
-
name: "Maximum length"
|
|
237
|
-
type: int
|
|
238
|
-
default: 256
|
|
239
|
-
min: 1
|
|
240
|
-
max: 4096
|
|
241
|
-
step: 1
|
|
242
|
-
p:
|
|
243
|
-
name: "P"
|
|
244
|
-
type: float
|
|
245
|
-
default: 0
|
|
246
|
-
min: 0
|
|
247
|
-
max: 0.99
|
|
248
|
-
step: 0.01
|
|
249
|
-
k:
|
|
250
|
-
name: "K"
|
|
251
|
-
type: int
|
|
252
|
-
default: 0
|
|
253
|
-
min: 0
|
|
254
|
-
max: 500
|
|
255
|
-
step: 1
|
|
256
|
-
frequency_penalty:
|
|
257
|
-
name: "Frequency Penalty"
|
|
258
|
-
type: float
|
|
259
|
-
default: 0
|
|
260
|
-
min: 0
|
|
261
|
-
max: 10
|
|
262
|
-
step: 0.1
|
|
263
|
-
presence_penalty:
|
|
264
|
-
name: "Presence Penalty"
|
|
265
|
-
type: float
|
|
266
|
-
default: 0
|
|
267
|
-
min: 0
|
|
268
|
-
max: 1
|
|
269
|
-
step: 0.01
|
|
270
199
|
azure:
|
|
271
200
|
id: azure
|
|
272
201
|
name: Azure
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from llmstudio.engine.providers.anthropic import AnthropicProvider
|
|
2
2
|
from llmstudio.engine.providers.azure import AzureProvider
|
|
3
|
-
from llmstudio.engine.providers.cohere import CohereProvider
|
|
4
3
|
from llmstudio.engine.providers.ollama import OllamaProvider
|
|
5
4
|
from llmstudio.engine.providers.openai import OpenAIProvider
|
|
6
5
|
from llmstudio.engine.providers.provider import provider_registry
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import Any, AsyncGenerator, Coroutine, Generator, Optional
|
|
6
|
+
|
|
7
|
+
import anthropic
|
|
8
|
+
from anthropic import Anthropic
|
|
9
|
+
from fastapi import HTTPException
|
|
10
|
+
from openai.types.chat import ChatCompletionChunk
|
|
11
|
+
from openai.types.chat.chat_completion_chunk import Choice, ChoiceDelta
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
from llmstudio.engine.providers.provider import ChatRequest, Provider, provider
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ClaudeParameters(BaseModel):
|
|
18
|
+
temperature: Optional[float] = Field(1, ge=0, le=1)
|
|
19
|
+
max_tokens: Optional[int] = Field(4096, ge=1)
|
|
20
|
+
top_p: Optional[float] = Field(1, ge=0, le=1)
|
|
21
|
+
top_k: Optional[int] = Field(5, ge=0, le=500)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class AnthropicRequest(ChatRequest):
|
|
25
|
+
parameters: Optional[ClaudeParameters] = ClaudeParameters()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@provider
|
|
29
|
+
class AnthropicProvider(Provider):
|
|
30
|
+
def __init__(self, config):
|
|
31
|
+
super().__init__(config)
|
|
32
|
+
self.API_KEY = os.getenv("ANTHROPIC_API_KEY")
|
|
33
|
+
|
|
34
|
+
def validate_request(self, request: AnthropicRequest):
|
|
35
|
+
return AnthropicRequest(**request)
|
|
36
|
+
|
|
37
|
+
async def generate_client(
|
|
38
|
+
self, request: AnthropicRequest
|
|
39
|
+
) -> Coroutine[Any, Any, Generator]:
|
|
40
|
+
"""Generate an Anthropic client"""
|
|
41
|
+
try:
|
|
42
|
+
client = Anthropic(api_key=request.api_key or self.API_KEY)
|
|
43
|
+
return await asyncio.to_thread(
|
|
44
|
+
client.messages.stream,
|
|
45
|
+
model=request.model,
|
|
46
|
+
messages=(
|
|
47
|
+
[{"role": "user", "content": request.chat_input}]
|
|
48
|
+
if isinstance(request.chat_input, str)
|
|
49
|
+
else request.chat_input
|
|
50
|
+
),
|
|
51
|
+
**request.parameters.dict(),
|
|
52
|
+
)
|
|
53
|
+
except anthropic._exceptions.APIError as e:
|
|
54
|
+
raise HTTPException(status_code=e.status_code, detail=e.response.json())
|
|
55
|
+
|
|
56
|
+
async def parse_response(
|
|
57
|
+
self, response: AsyncGenerator, **kwargs
|
|
58
|
+
) -> AsyncGenerator[str, None]:
|
|
59
|
+
with response as stream:
|
|
60
|
+
for chunk in stream:
|
|
61
|
+
if isinstance(
|
|
62
|
+
chunk,
|
|
63
|
+
anthropic.types.content_block_delta_event.ContentBlockDeltaEvent,
|
|
64
|
+
):
|
|
65
|
+
yield ChatCompletionChunk(
|
|
66
|
+
id=str(uuid.uuid4()),
|
|
67
|
+
choices=[
|
|
68
|
+
Choice(
|
|
69
|
+
delta=ChoiceDelta(
|
|
70
|
+
content=chunk.delta.text, role="assistant"
|
|
71
|
+
),
|
|
72
|
+
finish_reason=None,
|
|
73
|
+
index=0,
|
|
74
|
+
)
|
|
75
|
+
],
|
|
76
|
+
created=int(time.time()),
|
|
77
|
+
model=kwargs.get("request").model,
|
|
78
|
+
object="chat.completion.chunk",
|
|
79
|
+
).model_dump(),
|
|
80
|
+
elif isinstance(
|
|
81
|
+
chunk, anthropic.types.message_stop_event.MessageStopEvent
|
|
82
|
+
):
|
|
83
|
+
yield ChatCompletionChunk(
|
|
84
|
+
id=str(uuid.uuid4()),
|
|
85
|
+
choices=[
|
|
86
|
+
Choice(delta=ChoiceDelta(), finish_reason="stop", index=0)
|
|
87
|
+
],
|
|
88
|
+
created=int(time.time()),
|
|
89
|
+
model=kwargs.get("request").model,
|
|
90
|
+
object="chat.completion.chunk",
|
|
91
|
+
).model_dump(),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import os
|
|
3
|
-
from typing import Any, AsyncGenerator, Coroutine, Generator, Optional
|
|
3
|
+
from typing import Any, AsyncGenerator, Coroutine, Dict, Generator, List, Optional
|
|
4
4
|
|
|
5
5
|
import openai
|
|
6
6
|
from fastapi import HTTPException
|
|
@@ -12,7 +12,7 @@ from llmstudio.engine.providers.provider import ChatRequest, Provider, provider
|
|
|
12
12
|
|
|
13
13
|
class AzureParameters(BaseModel):
|
|
14
14
|
temperature: Optional[float] = Field(default=1, ge=0, le=2)
|
|
15
|
-
max_tokens: Optional[int] = Field(default=
|
|
15
|
+
max_tokens: Optional[int] = Field(default=2048, ge=1)
|
|
16
16
|
top_p: Optional[float] = Field(default=1, ge=0, le=1)
|
|
17
17
|
frequency_penalty: Optional[float] = Field(default=0, ge=0, le=1)
|
|
18
18
|
presence_penalty: Optional[float] = Field(default=0, ge=0, le=1)
|
|
@@ -20,8 +20,10 @@ class AzureParameters(BaseModel):
|
|
|
20
20
|
|
|
21
21
|
class AzureRequest(ChatRequest):
|
|
22
22
|
api_endpoint: Optional[str] = None
|
|
23
|
-
api_version: Optional[str] =
|
|
23
|
+
api_version: Optional[str] = None
|
|
24
24
|
parameters: Optional[AzureParameters] = AzureParameters()
|
|
25
|
+
functions: Optional[List[Dict[str, Any]]] = None
|
|
26
|
+
chat_input: Any
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
@provider
|
|
@@ -48,19 +50,21 @@ class AzureProvider(Provider):
|
|
|
48
50
|
return await asyncio.to_thread(
|
|
49
51
|
client.chat.completions.create,
|
|
50
52
|
model=request.model,
|
|
51
|
-
messages=
|
|
53
|
+
messages=(
|
|
54
|
+
[{"role": "user", "content": request.chat_input}]
|
|
55
|
+
if isinstance(request.chat_input, str)
|
|
56
|
+
else request.chat_input
|
|
57
|
+
),
|
|
58
|
+
functions=request.functions,
|
|
59
|
+
function_call="auto" if request.functions else None,
|
|
52
60
|
stream=True,
|
|
53
|
-
**request.parameters.
|
|
61
|
+
**request.parameters.model_dump(),
|
|
54
62
|
)
|
|
55
63
|
except openai._exceptions.APIError as e:
|
|
56
64
|
raise HTTPException(status_code=e.status_code, detail=e.response.json())
|
|
57
65
|
|
|
58
66
|
async def parse_response(
|
|
59
|
-
self, response: AsyncGenerator
|
|
67
|
+
self, response: AsyncGenerator, **kwargs
|
|
60
68
|
) -> AsyncGenerator[str, None]:
|
|
61
69
|
for chunk in response:
|
|
62
|
-
|
|
63
|
-
chunk.choices[0].finish_reason not in ["stop", "length"]
|
|
64
|
-
and chunk.choices[0].delta.content is not None
|
|
65
|
-
):
|
|
66
|
-
yield chunk.choices[0].delta.content
|
|
70
|
+
yield chunk.model_dump()
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import json
|
|
3
|
+
import time
|
|
4
|
+
import uuid
|
|
3
5
|
from typing import Any, AsyncGenerator, Coroutine, Generator, Optional
|
|
4
6
|
|
|
5
7
|
import requests
|
|
6
8
|
from fastapi import HTTPException
|
|
9
|
+
from openai.types.chat import ChatCompletionChunk
|
|
10
|
+
from openai.types.chat.chat_completion_chunk import Choice, ChoiceDelta
|
|
7
11
|
from pydantic import BaseModel, Field
|
|
8
12
|
|
|
9
13
|
from llmstudio.engine.providers.provider import ChatRequest, Provider, provider
|
|
@@ -39,6 +43,7 @@ class OllamaProvider(Provider):
|
|
|
39
43
|
json={
|
|
40
44
|
"model": request.model,
|
|
41
45
|
"prompt": request.chat_input,
|
|
46
|
+
"stream": True,
|
|
42
47
|
**request.parameters.dict(),
|
|
43
48
|
},
|
|
44
49
|
stream=True,
|
|
@@ -50,7 +55,7 @@ class OllamaProvider(Provider):
|
|
|
50
55
|
)
|
|
51
56
|
|
|
52
57
|
async def parse_response(
|
|
53
|
-
self, response: AsyncGenerator
|
|
58
|
+
self, response: AsyncGenerator, **kwargs
|
|
54
59
|
) -> AsyncGenerator[str, None]:
|
|
55
60
|
for line in response.iter_lines():
|
|
56
61
|
if not line:
|
|
@@ -59,5 +64,31 @@ class OllamaProvider(Provider):
|
|
|
59
64
|
if "error" in chunk:
|
|
60
65
|
raise HTTPException(status_code=500, detail=chunk["error"])
|
|
61
66
|
if chunk.get("done"):
|
|
67
|
+
print("done")
|
|
68
|
+
yield ChatCompletionChunk(
|
|
69
|
+
id=str(uuid.uuid4()),
|
|
70
|
+
choices=[
|
|
71
|
+
Choice(delta=ChoiceDelta(), finish_reason="stop", index=0)
|
|
72
|
+
],
|
|
73
|
+
created=int(time.time()),
|
|
74
|
+
model=kwargs.get("request").model,
|
|
75
|
+
object="chat.completion.chunk",
|
|
76
|
+
).model_dump()
|
|
62
77
|
break
|
|
63
|
-
|
|
78
|
+
|
|
79
|
+
if chunk["response"] is not None:
|
|
80
|
+
yield ChatCompletionChunk(
|
|
81
|
+
id=str(uuid.uuid4()),
|
|
82
|
+
choices=[
|
|
83
|
+
Choice(
|
|
84
|
+
delta=ChoiceDelta(
|
|
85
|
+
content=chunk["response"], role="assistant"
|
|
86
|
+
),
|
|
87
|
+
finish_reason=None,
|
|
88
|
+
index=0,
|
|
89
|
+
)
|
|
90
|
+
],
|
|
91
|
+
created=int(time.time()),
|
|
92
|
+
model=kwargs.get("request").model,
|
|
93
|
+
object="chat.completion.chunk",
|
|
94
|
+
).model_dump()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import os
|
|
3
|
-
from typing import Any, AsyncGenerator, Coroutine, Generator, Optional
|
|
3
|
+
from typing import Any, AsyncGenerator, Coroutine, Dict, Generator, List, Optional
|
|
4
4
|
|
|
5
5
|
import openai
|
|
6
6
|
from fastapi import HTTPException
|
|
@@ -12,7 +12,7 @@ from llmstudio.engine.providers.provider import ChatRequest, Provider, provider
|
|
|
12
12
|
|
|
13
13
|
class OpenAIParameters(BaseModel):
|
|
14
14
|
temperature: Optional[float] = Field(default=1, ge=0, le=2)
|
|
15
|
-
max_tokens: Optional[int] = Field(default=
|
|
15
|
+
max_tokens: Optional[int] = Field(default=2048, ge=1)
|
|
16
16
|
top_p: Optional[float] = Field(default=1, ge=0, le=1)
|
|
17
17
|
frequency_penalty: Optional[float] = Field(default=0, ge=0, le=1)
|
|
18
18
|
presence_penalty: Optional[float] = Field(default=0, ge=0, le=1)
|
|
@@ -20,6 +20,8 @@ class OpenAIParameters(BaseModel):
|
|
|
20
20
|
|
|
21
21
|
class OpenAIRequest(ChatRequest):
|
|
22
22
|
parameters: Optional[OpenAIParameters] = OpenAIParameters()
|
|
23
|
+
functions: Optional[List[Dict[str, Any]]] = None
|
|
24
|
+
chat_input: Any
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
@provider
|
|
@@ -40,16 +42,21 @@ class OpenAIProvider(Provider):
|
|
|
40
42
|
return await asyncio.to_thread(
|
|
41
43
|
client.chat.completions.create,
|
|
42
44
|
model=request.model,
|
|
43
|
-
messages=
|
|
45
|
+
messages=(
|
|
46
|
+
[{"role": "user", "content": request.chat_input}]
|
|
47
|
+
if isinstance(request.chat_input, str)
|
|
48
|
+
else request.chat_input
|
|
49
|
+
),
|
|
50
|
+
functions=request.functions,
|
|
51
|
+
function_call="auto" if request.functions else None,
|
|
44
52
|
stream=True,
|
|
45
|
-
**request.parameters.
|
|
53
|
+
**request.parameters.model_dump(),
|
|
46
54
|
)
|
|
47
55
|
except openai._exceptions.APIError as e:
|
|
48
56
|
raise HTTPException(status_code=e.status_code, detail=e.response.json())
|
|
49
57
|
|
|
50
58
|
async def parse_response(
|
|
51
|
-
self, response: AsyncGenerator
|
|
59
|
+
self, response: AsyncGenerator, **kwargs
|
|
52
60
|
) -> AsyncGenerator[str, None]:
|
|
53
61
|
for chunk in response:
|
|
54
|
-
|
|
55
|
-
yield chunk.choices[0].delta.content
|
|
62
|
+
yield chunk.model_dump()
|