lemonade-sdk 8.1.7__tar.gz → 8.1.8__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.

Potentially problematic release.


This version of lemonade-sdk might be problematic. Click here for more details.

Files changed (86) hide show
  1. {lemonade_sdk-8.1.7/src/lemonade_sdk.egg-info → lemonade_sdk-8.1.8}/PKG-INFO +15 -63
  2. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/README.md +14 -26
  3. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/setup.py +0 -39
  4. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/cli.py +0 -4
  5. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/report/table.py +1 -1
  6. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/llamacpp.py +16 -1
  7. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/serve.py +39 -9
  8. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/static/js/chat.js +79 -15
  9. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/static/js/models.js +11 -0
  10. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/static/js/shared.js +11 -3
  11. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/static/styles.css +31 -7
  12. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/static/webapp.html +4 -4
  13. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/wrapped_server.py +8 -0
  14. lemonade_sdk-8.1.8/src/lemonade/version.py +1 -0
  15. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_install/install.py +15 -49
  16. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8/src/lemonade_sdk.egg-info}/PKG-INFO +15 -63
  17. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_sdk.egg-info/SOURCES.txt +0 -3
  18. lemonade_sdk-8.1.8/src/lemonade_sdk.egg-info/requires.txt +44 -0
  19. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_server/cli.py +12 -9
  20. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_server/model_manager.py +48 -0
  21. lemonade_sdk-8.1.7/src/lemonade/tools/quark/quark_load.py +0 -173
  22. lemonade_sdk-8.1.7/src/lemonade/tools/quark/quark_quantize.py +0 -439
  23. lemonade_sdk-8.1.7/src/lemonade/tools/server/__init__.py +0 -0
  24. lemonade_sdk-8.1.7/src/lemonade/version.py +0 -1
  25. lemonade_sdk-8.1.7/src/lemonade_sdk.egg-info/requires.txt +0 -92
  26. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/LICENSE +0 -0
  27. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/NOTICE.md +0 -0
  28. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/pyproject.toml +0 -0
  29. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/setup.cfg +0 -0
  30. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/__init__.py +0 -0
  31. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/api.py +0 -0
  32. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/cache.py +0 -0
  33. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/__init__.py +0 -0
  34. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/build.py +0 -0
  35. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/cli_helpers.py +0 -0
  36. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/exceptions.py +0 -0
  37. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/filesystem.py +0 -0
  38. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/inference_engines.py +0 -0
  39. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/network.py +0 -0
  40. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/printing.py +0 -0
  41. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/status.py +0 -0
  42. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/system_info.py +0 -0
  43. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/common/test_helpers.py +0 -0
  44. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/profilers/__init__.py +0 -0
  45. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/profilers/memory_tracker.py +0 -0
  46. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/profilers/profiler.py +0 -0
  47. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/sequence.py +0 -0
  48. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/state.py +0 -0
  49. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/__init__.py +0 -0
  50. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/accuracy.py +0 -0
  51. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/adapter.py +0 -0
  52. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/bench.py +0 -0
  53. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/huggingface/bench.py +0 -0
  54. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/huggingface/load.py +0 -0
  55. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/huggingface/utils.py +0 -0
  56. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/humaneval.py +0 -0
  57. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/llamacpp/bench.py +0 -0
  58. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/llamacpp/load.py +0 -0
  59. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/llamacpp/utils.py +0 -0
  60. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/management_tools.py +0 -0
  61. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/mmlu.py +0 -0
  62. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/oga/__init__.py +0 -0
  63. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/oga/bench.py +0 -0
  64. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/oga/load.py +0 -0
  65. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/oga/utils.py +0 -0
  66. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/perplexity.py +0 -0
  67. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/prompt.py +0 -0
  68. {lemonade_sdk-8.1.7/src/lemonade/tools/quark → lemonade_sdk-8.1.8/src/lemonade/tools/report}/__init__.py +0 -0
  69. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/report/llm_report.py +0 -0
  70. {lemonade_sdk-8.1.7/src/lemonade/tools/report → lemonade_sdk-8.1.8/src/lemonade/tools/server}/__init__.py +0 -0
  71. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/static/favicon.ico +0 -0
  72. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/static/js/model-settings.js +0 -0
  73. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/tool_calls.py +0 -0
  74. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/tray.py +0 -0
  75. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/utils/port.py +0 -0
  76. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/utils/system_tray.py +0 -0
  77. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/utils/thread.py +0 -0
  78. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/server/webapp.py +0 -0
  79. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade/tools/tool.py +0 -0
  80. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_install/__init__.py +0 -0
  81. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_sdk.egg-info/dependency_links.txt +0 -0
  82. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_sdk.egg-info/entry_points.txt +0 -0
  83. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_sdk.egg-info/top_level.txt +0 -0
  84. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_server/pydantic_models.py +0 -0
  85. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_server/server_models.json +0 -0
  86. {lemonade_sdk-8.1.7 → lemonade_sdk-8.1.8}/src/lemonade_server/settings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lemonade-sdk
3
- Version: 8.1.7
3
+ Version: 8.1.8
4
4
  Summary: Lemonade SDK: Your LLM Aide for Validation and Deployment
5
5
  Author-email: lemonade@amd.com
6
6
  Requires-Python: >=3.10, <3.14
@@ -45,42 +45,6 @@ Requires-Dist: human-eval-windows==1.0.4; extra == "dev"
45
45
  Requires-Dist: lm-eval[api]; extra == "dev"
46
46
  Provides-Extra: model-generate
47
47
  Requires-Dist: model-generate==1.5.0; (platform_system == "Windows" and python_version == "3.10") and extra == "model-generate"
48
- Provides-Extra: oga-hybrid
49
- Requires-Dist: lemonade-sdk[oga-ryzenai]; extra == "oga-hybrid"
50
- Provides-Extra: oga-unified
51
- Requires-Dist: lemonade-sdk[oga-ryzenai]; extra == "oga-unified"
52
- Provides-Extra: oga-hybrid-minimal
53
- Requires-Dist: lemonade-sdk[oga-ryzenai]; extra == "oga-hybrid-minimal"
54
- Provides-Extra: oga-cpu-minimal
55
- Requires-Dist: lemonade-sdk[oga-cpu]; extra == "oga-cpu-minimal"
56
- Provides-Extra: oga-npu-minimal
57
- Requires-Dist: lemonade-sdk[oga-ryzenai]; extra == "oga-npu-minimal"
58
- Provides-Extra: llm
59
- Requires-Dist: lemonade-sdk[dev]; extra == "llm"
60
- Provides-Extra: llm-oga-cpu
61
- Requires-Dist: lemonade-sdk[dev,oga-cpu]; extra == "llm-oga-cpu"
62
- Provides-Extra: llm-oga-npu
63
- Requires-Dist: onnx==1.16.0; extra == "llm-oga-npu"
64
- Requires-Dist: onnxruntime==1.18.0; extra == "llm-oga-npu"
65
- Requires-Dist: numpy==1.26.4; extra == "llm-oga-npu"
66
- Requires-Dist: protobuf>=6.30.1; extra == "llm-oga-npu"
67
- Requires-Dist: lemonade-sdk[dev]; extra == "llm-oga-npu"
68
- Provides-Extra: llm-oga-hybrid
69
- Requires-Dist: onnx==1.16.1; extra == "llm-oga-hybrid"
70
- Requires-Dist: numpy==1.26.4; extra == "llm-oga-hybrid"
71
- Requires-Dist: protobuf>=6.30.1; extra == "llm-oga-hybrid"
72
- Provides-Extra: llm-oga-unified
73
- Requires-Dist: lemonade-sdk[dev,llm-oga-hybrid]; extra == "llm-oga-unified"
74
- Provides-Extra: llm-oga-igpu
75
- Requires-Dist: onnxruntime-genai-directml==0.6.0; extra == "llm-oga-igpu"
76
- Requires-Dist: onnxruntime-directml<1.22.0,>=1.19.0; extra == "llm-oga-igpu"
77
- Requires-Dist: transformers<4.45.0; extra == "llm-oga-igpu"
78
- Requires-Dist: lemonade-sdk[dev]; extra == "llm-oga-igpu"
79
- Provides-Extra: llm-oga-cuda
80
- Requires-Dist: onnxruntime-genai-cuda==0.8.2; extra == "llm-oga-cuda"
81
- Requires-Dist: onnxruntime-gpu>=1.22.0; extra == "llm-oga-cuda"
82
- Requires-Dist: transformers<=4.51.3; extra == "llm-oga-cuda"
83
- Requires-Dist: lemonade-sdk[dev]; extra == "llm-oga-cuda"
84
48
  Dynamic: author-email
85
49
  Dynamic: description
86
50
  Dynamic: description-content-type
@@ -94,41 +58,29 @@ Dynamic: summary
94
58
 
95
59
  <p align="center">
96
60
  <a href="https://discord.gg/5xXzkMu8Zk">
97
- <img src="https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white" alt="Discord" />
98
- </a>
61
+ <img src="https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white" alt="Discord" /></a>
99
62
  <a href="https://github.com/lemonade-sdk/lemonade/tree/main/test" title="Check out our tests">
100
- <img src="https://github.com/lemonade-sdk/lemonade/actions/workflows/test_lemonade.yml/badge.svg" alt="Lemonade tests" />
101
- </a>
63
+ <img src="https://github.com/lemonade-sdk/lemonade/actions/workflows/test_lemonade.yml/badge.svg" alt="Lemonade tests" /></a>
102
64
  <a href="docs/README.md#installation" title="Check out our instructions">
103
- <img src="https://img.shields.io/badge/Windows-11-0078D6?logo=windows&logoColor=white" alt="Windows 11" />
104
- </a>
65
+ <img src="https://img.shields.io/badge/Windows-11-0078D6?logo=windows&logoColor=white" alt="Windows 11" /></a>
105
66
  <a href="https://lemonade-server.ai/#linux" title="Ubuntu 24.04 & 25.04 Supported">
106
- <img src="https://img.shields.io/badge/Ubuntu-24.04%20%7C%2025.04-E95420?logo=ubuntu&logoColor=white" alt="Ubuntu 24.04 | 25.04" />
107
- </a>
67
+ <img src="https://img.shields.io/badge/Ubuntu-24.04%20%7C%2025.04-E95420?logo=ubuntu&logoColor=white" alt="Ubuntu 24.04 | 25.04" /></a>
108
68
  <a href="docs/README.md#installation" title="Check out our instructions">
109
- <img src="https://img.shields.io/badge/Python-3.10--3.13-blue?logo=python&logoColor=white" alt="Made with Python" />
110
- </a>
69
+ <img src="https://img.shields.io/badge/Python-3.10--3.13-blue?logo=python&logoColor=white" alt="Made with Python" /></a>
111
70
  <a href="https://github.com/lemonade-sdk/lemonade/blob/main/docs/contribute.md" title="Contribution Guide">
112
- <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" />
113
- </a>
71
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" /></a>
114
72
  <a href="https://github.com/lemonade-sdk/lemonade/releases/latest" title="Download the latest release">
115
- <img src="https://img.shields.io/github/v/release/lemonade-sdk/lemonade?include_prereleases" alt="Latest Release" />
116
- </a>
73
+ <img src="https://img.shields.io/github/v/release/lemonade-sdk/lemonade?include_prereleases" alt="Latest Release" /></a>
117
74
  <a href="https://tooomm.github.io/github-release-stats/?username=lemonade-sdk&repository=lemonade">
118
- <img src="https://img.shields.io/github/downloads/lemonade-sdk/lemonade/total.svg" alt="GitHub downloads" />
119
- </a>
75
+ <img src="https://img.shields.io/github/downloads/lemonade-sdk/lemonade/total.svg" alt="GitHub downloads" /></a>
120
76
  <a href="https://github.com/lemonade-sdk/lemonade/issues">
121
- <img src="https://img.shields.io/github/issues/lemonade-sdk/lemonade" alt="GitHub issues" />
122
- </a>
77
+ <img src="https://img.shields.io/github/issues/lemonade-sdk/lemonade" alt="GitHub issues" /></a>
123
78
  <a href="https://github.com/lemonade-sdk/lemonade/blob/main/LICENSE">
124
- <img src="https://img.shields.io/badge/License-Apache-yellow.svg" alt="License: Apache" />
125
- </a>
79
+ <img src="https://img.shields.io/badge/License-Apache-yellow.svg" alt="License: Apache" /></a>
126
80
  <a href="https://github.com/psf/black">
127
- <img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code style: black" />
128
- </a>
81
+ <img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code style: black" /></a>
129
82
  <a href="https://star-history.com/#lemonade-sdk/lemonade">
130
- <img src="https://img.shields.io/badge/Star%20History-View-brightgreen" alt="Star History Chart" />
131
- </a>
83
+ <img src="https://img.shields.io/badge/Star%20History-View-brightgreen" alt="Star History Chart" /></a>
132
84
  </p>
133
85
  <p align="center">
134
86
  <img src="https://github.com/lemonade-sdk/assets/blob/main/docs/banner.png?raw=true" alt="Lemonade Banner" />
@@ -156,7 +108,7 @@ Startups such as [Styrk AI](https://styrk.ai/styrk-ai-and-amd-guardrails-for-you
156
108
  ### Use it with your favorite OpenAI-compatible app!
157
109
 
158
110
  <p align="center">
159
- <a href="https://lemonade-server.ai/docs/server/apps/open-webui/" title="Open WebUI" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/openwebui.jpg" alt="Open WebUI" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/continue/" title="Continue" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/continue_dev.png" alt="Continue" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/amd/gaia" title="Gaia" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/gaia.ico" alt="Gaia" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/anythingLLM/" title="AnythingLLM" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/anything_llm.png" alt="AnythingLLM" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/ai-dev-gallery/" title="AI Dev Gallery" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_dev_gallery.webp" alt="AI Dev Gallery" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/lm-eval/" title="LM-Eval" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/lm_eval.png" alt="LM-Eval" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/codeGPT/" title="CodeGPT" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/codegpt.jpg" alt="CodeGPT" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/lemonade-sdk/lemonade/blob/main/docs/server/apps/ai-toolkit.md" title="AI Toolkit" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_toolkit.png" alt="AI Toolkit" width="60" /></a>
111
+ <a href="https://lemonade-server.ai/docs/server/apps/open-webui/" title="Open WebUI" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/openwebui.jpg" alt="Open WebUI" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/continue/" title="Continue" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/continue_dev.png" alt="Continue" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/amd/gaia" title="Gaia" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/gaia.ico" alt="Gaia" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/anythingLLM/" title="AnythingLLM" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/anything_llm.png" alt="AnythingLLM" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/ai-dev-gallery/" title="AI Dev Gallery" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_dev_gallery.webp" alt="AI Dev Gallery" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/lm-eval/" title="LM-Eval" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/lm_eval.png" alt="LM-Eval" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/lemonade-sdk/lemonade-arcade" title="Lemonade Arcade" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/lemonade-arcade/refs/heads/main/docs/assets/favicon.ico" alt="Lemonade Arcade" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/lemonade-sdk/lemonade/blob/main/docs/server/apps/ai-toolkit.md" title="AI Toolkit" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_toolkit.png" alt="AI Toolkit" width="60" /></a>
160
112
  </p>
161
113
 
162
114
  > [!TIP]
@@ -227,7 +179,7 @@ Lemonade supports the following configurations, while also making it easy to swi
227
179
  </tr>
228
180
  <tr>
229
181
  <td><b>gfx120X</b> (RDNA4)</td>
230
- <td>Windows only</td>
182
+ <td>Windows, Ubuntu</td>
231
183
  <td>Radeon AI PRO R9700, RX 9070 XT/GRE/9070, RX 9060 XT</td>
232
184
  </tr>
233
185
  <tr>
@@ -2,41 +2,29 @@
2
2
 
3
3
  <p align="center">
4
4
  <a href="https://discord.gg/5xXzkMu8Zk">
5
- <img src="https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white" alt="Discord" />
6
- </a>
5
+ <img src="https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white" alt="Discord" /></a>
7
6
  <a href="https://github.com/lemonade-sdk/lemonade/tree/main/test" title="Check out our tests">
8
- <img src="https://github.com/lemonade-sdk/lemonade/actions/workflows/test_lemonade.yml/badge.svg" alt="Lemonade tests" />
9
- </a>
7
+ <img src="https://github.com/lemonade-sdk/lemonade/actions/workflows/test_lemonade.yml/badge.svg" alt="Lemonade tests" /></a>
10
8
  <a href="docs/README.md#installation" title="Check out our instructions">
11
- <img src="https://img.shields.io/badge/Windows-11-0078D6?logo=windows&logoColor=white" alt="Windows 11" />
12
- </a>
9
+ <img src="https://img.shields.io/badge/Windows-11-0078D6?logo=windows&logoColor=white" alt="Windows 11" /></a>
13
10
  <a href="https://lemonade-server.ai/#linux" title="Ubuntu 24.04 & 25.04 Supported">
14
- <img src="https://img.shields.io/badge/Ubuntu-24.04%20%7C%2025.04-E95420?logo=ubuntu&logoColor=white" alt="Ubuntu 24.04 | 25.04" />
15
- </a>
11
+ <img src="https://img.shields.io/badge/Ubuntu-24.04%20%7C%2025.04-E95420?logo=ubuntu&logoColor=white" alt="Ubuntu 24.04 | 25.04" /></a>
16
12
  <a href="docs/README.md#installation" title="Check out our instructions">
17
- <img src="https://img.shields.io/badge/Python-3.10--3.13-blue?logo=python&logoColor=white" alt="Made with Python" />
18
- </a>
13
+ <img src="https://img.shields.io/badge/Python-3.10--3.13-blue?logo=python&logoColor=white" alt="Made with Python" /></a>
19
14
  <a href="https://github.com/lemonade-sdk/lemonade/blob/main/docs/contribute.md" title="Contribution Guide">
20
- <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" />
21
- </a>
15
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" /></a>
22
16
  <a href="https://github.com/lemonade-sdk/lemonade/releases/latest" title="Download the latest release">
23
- <img src="https://img.shields.io/github/v/release/lemonade-sdk/lemonade?include_prereleases" alt="Latest Release" />
24
- </a>
17
+ <img src="https://img.shields.io/github/v/release/lemonade-sdk/lemonade?include_prereleases" alt="Latest Release" /></a>
25
18
  <a href="https://tooomm.github.io/github-release-stats/?username=lemonade-sdk&repository=lemonade">
26
- <img src="https://img.shields.io/github/downloads/lemonade-sdk/lemonade/total.svg" alt="GitHub downloads" />
27
- </a>
19
+ <img src="https://img.shields.io/github/downloads/lemonade-sdk/lemonade/total.svg" alt="GitHub downloads" /></a>
28
20
  <a href="https://github.com/lemonade-sdk/lemonade/issues">
29
- <img src="https://img.shields.io/github/issues/lemonade-sdk/lemonade" alt="GitHub issues" />
30
- </a>
21
+ <img src="https://img.shields.io/github/issues/lemonade-sdk/lemonade" alt="GitHub issues" /></a>
31
22
  <a href="https://github.com/lemonade-sdk/lemonade/blob/main/LICENSE">
32
- <img src="https://img.shields.io/badge/License-Apache-yellow.svg" alt="License: Apache" />
33
- </a>
23
+ <img src="https://img.shields.io/badge/License-Apache-yellow.svg" alt="License: Apache" /></a>
34
24
  <a href="https://github.com/psf/black">
35
- <img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code style: black" />
36
- </a>
25
+ <img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code style: black" /></a>
37
26
  <a href="https://star-history.com/#lemonade-sdk/lemonade">
38
- <img src="https://img.shields.io/badge/Star%20History-View-brightgreen" alt="Star History Chart" />
39
- </a>
27
+ <img src="https://img.shields.io/badge/Star%20History-View-brightgreen" alt="Star History Chart" /></a>
40
28
  </p>
41
29
  <p align="center">
42
30
  <img src="https://github.com/lemonade-sdk/assets/blob/main/docs/banner.png?raw=true" alt="Lemonade Banner" />
@@ -64,7 +52,7 @@ Startups such as [Styrk AI](https://styrk.ai/styrk-ai-and-amd-guardrails-for-you
64
52
  ### Use it with your favorite OpenAI-compatible app!
65
53
 
66
54
  <p align="center">
67
- <a href="https://lemonade-server.ai/docs/server/apps/open-webui/" title="Open WebUI" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/openwebui.jpg" alt="Open WebUI" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/continue/" title="Continue" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/continue_dev.png" alt="Continue" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/amd/gaia" title="Gaia" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/gaia.ico" alt="Gaia" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/anythingLLM/" title="AnythingLLM" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/anything_llm.png" alt="AnythingLLM" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/ai-dev-gallery/" title="AI Dev Gallery" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_dev_gallery.webp" alt="AI Dev Gallery" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/lm-eval/" title="LM-Eval" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/lm_eval.png" alt="LM-Eval" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/codeGPT/" title="CodeGPT" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/codegpt.jpg" alt="CodeGPT" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/lemonade-sdk/lemonade/blob/main/docs/server/apps/ai-toolkit.md" title="AI Toolkit" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_toolkit.png" alt="AI Toolkit" width="60" /></a>
55
+ <a href="https://lemonade-server.ai/docs/server/apps/open-webui/" title="Open WebUI" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/openwebui.jpg" alt="Open WebUI" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/continue/" title="Continue" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/continue_dev.png" alt="Continue" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/amd/gaia" title="Gaia" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/gaia.ico" alt="Gaia" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/anythingLLM/" title="AnythingLLM" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/anything_llm.png" alt="AnythingLLM" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/ai-dev-gallery/" title="AI Dev Gallery" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_dev_gallery.webp" alt="AI Dev Gallery" width="60" /></a>&nbsp;&nbsp;<a href="https://lemonade-server.ai/docs/server/apps/lm-eval/" title="LM-Eval" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/lm_eval.png" alt="LM-Eval" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/lemonade-sdk/lemonade-arcade" title="Lemonade Arcade" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/lemonade-arcade/refs/heads/main/docs/assets/favicon.ico" alt="Lemonade Arcade" width="60" /></a>&nbsp;&nbsp;<a href="https://github.com/lemonade-sdk/lemonade/blob/main/docs/server/apps/ai-toolkit.md" title="AI Toolkit" target="_blank"><img src="https://raw.githubusercontent.com/lemonade-sdk/assets/refs/heads/main/partner_logos/ai_toolkit.png" alt="AI Toolkit" width="60" /></a>
68
56
  </p>
69
57
 
70
58
  > [!TIP]
@@ -135,7 +123,7 @@ Lemonade supports the following configurations, while also making it easy to swi
135
123
  </tr>
136
124
  <tr>
137
125
  <td><b>gfx120X</b> (RDNA4)</td>
138
- <td>Windows only</td>
126
+ <td>Windows, Ubuntu</td>
139
127
  <td>Radeon AI PRO R9700, RX 9070 XT/GRE/9070, RX 9060 XT</td>
140
128
  </tr>
141
129
  <tr>
@@ -17,7 +17,6 @@ setup(
17
17
  "lemonade.tools.huggingface",
18
18
  "lemonade.tools.oga",
19
19
  "lemonade.tools.llamacpp",
20
- "lemonade.tools.quark",
21
20
  "lemonade.tools.report",
22
21
  "lemonade.tools.server.utils",
23
22
  "lemonade.tools.server",
@@ -80,44 +79,6 @@ setup(
80
79
  "model-generate": [
81
80
  "model-generate==1.5.0; platform_system=='Windows' and python_version=='3.10'",
82
81
  ],
83
- # Keep backwards compatibility for old extras names
84
- "oga-hybrid": ["lemonade-sdk[oga-ryzenai]"],
85
- "oga-unified": ["lemonade-sdk[oga-ryzenai]"],
86
- "oga-hybrid-minimal": ["lemonade-sdk[oga-ryzenai]"],
87
- "oga-cpu-minimal": ["lemonade-sdk[oga-cpu]"],
88
- "oga-npu-minimal": ["lemonade-sdk[oga-ryzenai]"],
89
- "llm": ["lemonade-sdk[dev]"],
90
- "llm-oga-cpu": ["lemonade-sdk[dev,oga-cpu]"],
91
- # The following extras are deprecated and/or not commonly used
92
- "llm-oga-npu": [
93
- "onnx==1.16.0",
94
- # NPU requires specific onnxruntime version for Ryzen AI compatibility
95
- # This may conflict with other OGA extras that require >=1.22.0
96
- "onnxruntime==1.18.0",
97
- "numpy==1.26.4",
98
- "protobuf>=6.30.1",
99
- "lemonade-sdk[dev]",
100
- ],
101
- "llm-oga-hybrid": [
102
- # Note: `lemonade-install --ryzenai hybrid` is necessary
103
- # to complete installation for RAI 1.4.0.
104
- "onnx==1.16.1",
105
- "numpy==1.26.4",
106
- "protobuf>=6.30.1",
107
- ],
108
- "llm-oga-unified": ["lemonade-sdk[dev, llm-oga-hybrid]"],
109
- "llm-oga-igpu": [
110
- "onnxruntime-genai-directml==0.6.0",
111
- "onnxruntime-directml>=1.19.0,<1.22.0",
112
- "transformers<4.45.0",
113
- "lemonade-sdk[dev]",
114
- ],
115
- "llm-oga-cuda": [
116
- "onnxruntime-genai-cuda==0.8.2",
117
- "onnxruntime-gpu >=1.22.0",
118
- "transformers<=4.51.3",
119
- "lemonade-sdk[dev]",
120
- ],
121
82
  },
122
83
  classifiers=[],
123
84
  entry_points={
@@ -25,8 +25,6 @@ from lemonade.tools.humaneval import AccuracyHumaneval
25
25
  from lemonade.tools.perplexity import AccuracyPerplexity
26
26
  from lemonade.tools.accuracy import LMEvalHarness
27
27
  from lemonade.tools.prompt import LLMPrompt
28
- from lemonade.tools.quark.quark_load import QuarkLoad
29
- from lemonade.tools.quark.quark_quantize import QuarkQuantize
30
28
  from lemonade.tools.report.llm_report import LemonadeReport
31
29
 
32
30
 
@@ -45,8 +43,6 @@ def main():
45
43
  HuggingfaceBench,
46
44
  OgaLoad,
47
45
  OgaBench,
48
- QuarkQuantize,
49
- QuarkLoad,
50
46
  LemonadeReport,
51
47
  # Inherited from lemonade
52
48
  Cache,
@@ -591,7 +591,7 @@ class LemonadePerfTable(Table):
591
591
  _wrap("Total Generated Tokens", 9),
592
592
  Keys.RESPONSE_TOKENS,
593
593
  "d",
594
- stat_fn=sum,
594
+ stat_fn=lambda x: sum(_to_list(x)),
595
595
  ),
596
596
  SimpleStat(
597
597
  _wrap("Memory Used (GB)", 8), Keys.MAX_MEMORY_USED_GBYTE, ".3f"
@@ -6,6 +6,7 @@ import threading
6
6
  import platform
7
7
 
8
8
  from dotenv import load_dotenv
9
+ from fastapi import HTTPException, status
9
10
 
10
11
  from lemonade_server.pydantic_models import (
11
12
  PullConfig,
@@ -28,6 +29,20 @@ class LlamaTelemetry(WrappedServerTelemetry):
28
29
  Parse telemetry data from llama server output lines.
29
30
  """
30
31
 
32
+ if "vk::PhysicalDevice::createDevice: ErrorExtensionNotPresent" in line:
33
+ msg = (
34
+ "Your AMD GPU driver version is not compatible with this software.\n"
35
+ "Please update and try again: "
36
+ "https://www.amd.com/en/support/download/drivers.html"
37
+ )
38
+ logging.error(msg)
39
+ raise HTTPException(
40
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
41
+ detail=msg,
42
+ )
43
+ elif "error" in line.lower():
44
+ logging.error(line)
45
+
31
46
  # Parse Vulkan device detection
32
47
  vulkan_match = re.search(r"ggml_vulkan: Found (\d+) Vulkan devices?:", line)
33
48
  if vulkan_match:
@@ -182,7 +197,7 @@ class LlamaServer(WrappedServer):
182
197
  exe_dir = os.path.dirname(exe_path)
183
198
  env_file_path = os.path.join(exe_dir, ".env")
184
199
  if os.path.exists(env_file_path):
185
- load_dotenv(env_file_path, override=True)
200
+ load_dotenv(env_file_path, override=False)
186
201
  env.update(os.environ)
187
202
  logging.debug(f"Loaded environment variables from {env_file_path}")
188
203
 
@@ -133,6 +133,21 @@ class StopOnEvent:
133
133
  return self.stop_event.is_set()
134
134
 
135
135
 
136
+ class NoCacheStaticFiles(StaticFiles):
137
+ """Custom StaticFiles class with no-cache headers"""
138
+
139
+ def __init__(self, *args, **kwargs):
140
+ super().__init__(*args, **kwargs)
141
+
142
+ def file_response(self, *args, **kwargs) -> Response:
143
+ response = super().file_response(*args, **kwargs)
144
+ # Add no-cache headers for all static files
145
+ response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
146
+ response.headers["Pragma"] = "no-cache"
147
+ response.headers["Expires"] = "0"
148
+ return response
149
+
150
+
136
151
  class Server:
137
152
  """
138
153
  Open a web server that apps can use to communicate with the LLM.
@@ -198,7 +213,7 @@ class Server:
198
213
  # as the Web App
199
214
  static_dir = Path(__file__).parent / "static"
200
215
  self.app.mount(
201
- "/static", StaticFiles(directory=static_dir), name="static_assets"
216
+ "/static", NoCacheStaticFiles(directory=static_dir), name="static_assets"
202
217
  )
203
218
 
204
219
  # Performance stats that are set during /ws and can be
@@ -1145,18 +1160,33 @@ class Server:
1145
1160
  )
1146
1161
  self.input_tokens = len(input_ids[0])
1147
1162
 
1148
- # For non-llamacpp recipes, truncate inputs to ctx_size if needed
1149
- if self.llm_loaded.recipe != "llamacpp" and self.input_tokens > self.ctx_size:
1150
- # Truncate input ids
1151
- truncate_amount = self.input_tokens - self.ctx_size
1152
- input_ids = input_ids[: self.ctx_size]
1163
+ max_prompt_length = self.ctx_size # Default fallback
1164
+ # For OGA models, try to read the actual max prompt length from config
1165
+ if "oga-" in self.llm_loaded.recipe:
1166
+ try:
1167
+ if model.config and model.config.get("max_prompt_length"):
1168
+ max_prompt_length = model.config["max_prompt_length"]
1169
+ logging.debug(
1170
+ f"Using OGA model max_prompt_length: {max_prompt_length}"
1171
+ )
1172
+ # pylint: disable=broad-exception-caught
1173
+ except Exception as e:
1174
+ logging.debug(f"Could not read OGA model config, using ctx_size: {e}")
1153
1175
 
1176
+ # Apply truncation if input exceeds the limit
1177
+ if self.input_tokens > max_prompt_length:
1178
+ # Truncate input ids
1179
+ truncate_amount = self.input_tokens - max_prompt_length
1180
+ input_ids = input_ids[:max_prompt_length]
1154
1181
  # Update token count
1155
- self.input_tokens = len(input_ids)
1182
+ if "oga-" in self.llm_loaded.recipe:
1183
+ self.input_tokens = len(input_ids)
1184
+ else:
1185
+ self.input_tokens = len(input_ids[0])
1156
1186
 
1157
- # Show warning message
1187
+ # Log warning message instead of raising exception
1158
1188
  truncation_message = (
1159
- f"Input exceeded {self.ctx_size} tokens. "
1189
+ f"Input exceeded {max_prompt_length} tokens. "
1160
1190
  f"Truncated {truncate_amount} tokens from the beginning."
1161
1191
  )
1162
1192
  logging.warning(truncation_message)
@@ -1,6 +1,7 @@
1
1
  // Chat logic and functionality
2
2
  let messages = [];
3
3
  let attachedFiles = [];
4
+ let systemMessageElement = null;
4
5
 
5
6
  // Default model configuration
6
7
  const DEFAULT_MODEL = 'Qwen2.5-0.5B-Instruct-CPU';
@@ -28,6 +29,9 @@ document.addEventListener('DOMContentLoaded', function() {
28
29
  // Update attachment button state periodically
29
30
  updateAttachmentButtonState();
30
31
  setInterval(updateAttachmentButtonState, 1000);
32
+
33
+ // Display initial system message
34
+ displaySystemMessage();
31
35
  });
32
36
 
33
37
  function setupChatEventListeners() {
@@ -163,25 +167,30 @@ function updateAttachmentButtonState() {
163
167
  attachmentBtn.style.opacity = '0.5';
164
168
  attachmentBtn.style.cursor = 'not-allowed';
165
169
  attachmentBtn.title = 'Load a model first';
166
- return;
167
- }
168
-
169
- const isVision = isVisionModel(currentLoadedModel);
170
-
171
- if (isVision) {
172
- attachmentBtn.style.opacity = '1';
173
- attachmentBtn.style.cursor = 'pointer';
174
- attachmentBtn.title = 'Attach images';
175
170
  } else {
176
- attachmentBtn.style.opacity = '0.5';
177
- attachmentBtn.style.cursor = 'not-allowed';
178
- attachmentBtn.title = 'Image attachments not supported by this model';
171
+ const isVision = isVisionModel(currentLoadedModel);
172
+
173
+ if (isVision) {
174
+ attachmentBtn.style.opacity = '1';
175
+ attachmentBtn.style.cursor = 'pointer';
176
+ attachmentBtn.title = 'Attach images';
177
+ } else {
178
+ attachmentBtn.style.opacity = '0.5';
179
+ attachmentBtn.style.cursor = 'not-allowed';
180
+ attachmentBtn.title = 'Image attachments not supported by this model';
181
+ }
179
182
  }
183
+
184
+ // Update system message when model state changes
185
+ displaySystemMessage();
180
186
  }
181
187
 
182
188
  // Make updateAttachmentButtonState accessible globally
183
189
  window.updateAttachmentButtonState = updateAttachmentButtonState;
184
190
 
191
+ // Make displaySystemMessage accessible globally
192
+ window.displaySystemMessage = displaySystemMessage;
193
+
185
194
  // Auto-load default model and send message
186
195
  async function autoLoadDefaultModelAndSend() {
187
196
  // Check if default model is available and installed
@@ -217,6 +226,7 @@ async function autoLoadDefaultModelAndSend() {
217
226
  },
218
227
  onError: (error, failedModelId) => {
219
228
  console.error('Error auto-loading default model:', error);
229
+ showErrorBanner('Failed to load model: ' + error.message);
220
230
  }
221
231
  });
222
232
  }
@@ -277,7 +287,7 @@ function handleChatInputKeydown(e) {
277
287
  if (e.key === 'Escape' && attachedFiles.length > 0) {
278
288
  e.preventDefault();
279
289
  clearAttachments();
280
- } else if (e.key === 'Enter') {
290
+ } else if (e.key === 'Enter' && !e.shiftKey) {
281
291
  // Check if we have a loaded model
282
292
  if (currentLoadedModel && modelSelect.value !== '' && !modelSelect.disabled) {
283
293
  sendMessage();
@@ -438,7 +448,8 @@ function appendMessage(role, text, isMarkdown = false) {
438
448
  const bubble = document.createElement('div');
439
449
  bubble.className = 'chat-bubble ' + role;
440
450
 
441
- if (role === 'llm' && isMarkdown) {
451
+ // Check if isMarkdown is true, regardless of role
452
+ if (isMarkdown) {
442
453
  bubble.innerHTML = renderMarkdownWithThinkTokens(text);
443
454
  } else {
444
455
  bubble.textContent = text;
@@ -450,6 +461,53 @@ function appendMessage(role, text, isMarkdown = false) {
450
461
  return bubble; // Return the bubble element for streaming updates
451
462
  }
452
463
 
464
+ // Display system message based on current state
465
+ function displaySystemMessage() {
466
+ // Remove existing system message if it exists
467
+ if (systemMessageElement) {
468
+ systemMessageElement.remove();
469
+ systemMessageElement = null;
470
+ }
471
+
472
+ // Don't show system message if there are already user/LLM messages
473
+ if (messages.length > 0) {
474
+ return;
475
+ }
476
+
477
+ let messageText = '';
478
+
479
+ // Check if any models are installed
480
+ const hasInstalledModels = window.installedModels && window.installedModels.size > 0;
481
+
482
+ if (!hasInstalledModels) {
483
+ // No models installed - show first message
484
+ messageText = `Welcome to Lemonade! To get started:
485
+ 1. Head over to the Model Management tab.
486
+ 2. Use the 📥Download button to download a model.
487
+ 3. Use the 🚀Load button to load the model.
488
+ 4. Come back to this tab, and you are ready to chat with the model.`;
489
+ } else if (!currentLoadedModel) {
490
+ // Models available but none loaded - show second message
491
+ messageText = 'Welcome to Lemonade! Choose a model from the dropdown menu below to load it and start chatting.';
492
+ }
493
+
494
+ if (messageText) {
495
+ const div = document.createElement('div');
496
+ div.className = 'chat-message system';
497
+ div.setAttribute('data-system-message', 'true');
498
+
499
+ const bubble = document.createElement('div');
500
+ bubble.className = 'chat-bubble system';
501
+ bubble.textContent = messageText;
502
+
503
+ div.appendChild(bubble);
504
+ chatHistory.appendChild(div);
505
+ chatHistory.scrollTop = chatHistory.scrollHeight;
506
+
507
+ systemMessageElement = div;
508
+ }
509
+ }
510
+
453
511
  function updateMessageContent(bubbleElement, text, isMarkdown = false) {
454
512
  if (isMarkdown) {
455
513
  bubbleElement.innerHTML = renderMarkdownWithThinkTokens(text);
@@ -541,6 +599,12 @@ async function sendMessage() {
541
599
  const text = chatInput.value.trim();
542
600
  if (!text && attachedFiles.length === 0) return;
543
601
 
602
+ // Remove system message when user starts chatting
603
+ if (systemMessageElement) {
604
+ systemMessageElement.remove();
605
+ systemMessageElement = null;
606
+ }
607
+
544
608
  // Check if a model is loaded, if not, automatically load the default model
545
609
  if (!currentLoadedModel) {
546
610
  const allModels = window.SERVER_MODELS || {};
@@ -624,7 +688,7 @@ async function sendMessage() {
624
688
  displayText = displayText ? `${displayText}\n[Images: ${fileNames}]` : `[Images: ${fileNames}]`;
625
689
  }
626
690
 
627
- appendMessage('user', displayText);
691
+ appendMessage('user', displayText, true);
628
692
 
629
693
  // Add to messages array
630
694
  const userMessage = {
@@ -59,6 +59,11 @@ async function updateModelStatusIndicator() {
59
59
  window.initializeModelDropdown();
60
60
  }
61
61
 
62
+ // Update system message when model status changes
63
+ if (window.displaySystemMessage) {
64
+ window.displaySystemMessage();
65
+ }
66
+
62
67
  // Refresh model management UI if we're on the models tab
63
68
  const modelsTab = document.getElementById('content-models');
64
69
  if (modelsTab && modelsTab.classList.contains('active')) {
@@ -417,6 +422,7 @@ async function loadModel(modelId) {
417
422
  },
418
423
  onError: (error, failedModelId) => {
419
424
  console.error(`Failed to load model ${failedModelId}:`, error);
425
+ showErrorBanner('Failed to load model: ' + error.message);
420
426
  }
421
427
  });
422
428
  }
@@ -699,6 +705,11 @@ async function refreshModelMgmtUI() {
699
705
  if (window.initializeModelDropdown) {
700
706
  window.initializeModelDropdown();
701
707
  }
708
+
709
+ // Update system message when installed models change
710
+ if (window.displaySystemMessage) {
711
+ window.displaySystemMessage();
712
+ }
702
713
  }
703
714
 
704
715
  // Make refreshModelMgmtUI globally accessible
@@ -54,6 +54,14 @@ function renderMarkdown(text) {
54
54
 
55
55
  // Display an error message in the banner
56
56
  function showErrorBanner(msg) {
57
+ // If DOM isn't ready, wait for it
58
+ if (document.readyState === 'loading') {
59
+ document.addEventListener('DOMContentLoaded', () => {
60
+ showErrorBanner(msg);
61
+ });
62
+ return;
63
+ }
64
+
57
65
  const banner = document.getElementById('error-banner');
58
66
  if (!banner) return;
59
67
  const msgEl = document.getElementById('error-banner-msg');
@@ -303,12 +311,12 @@ async function loadModelStandardized(modelId, options = {}) {
303
311
  onLoadingEnd(modelId, false);
304
312
  }
305
313
 
306
- // Call error callback or show default error
314
+ // Call error callback and always show default error banner as fallback
307
315
  if (onError) {
308
316
  onError(error, modelId);
309
- } else {
310
- showErrorBanner('Failed to load model: ' + error.message);
311
317
  }
318
+ // Always show error banner to ensure user sees the error
319
+ showErrorBanner('Failed to load model: ' + error.message);
312
320
 
313
321
  return false;
314
322
  }