ltcai 1.4.0 → 1.6.0
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.
- package/README.md +125 -88
- package/docs/CHANGELOG.md +101 -0
- package/docs/images/architecture.png +0 -0
- package/docs/images/enterprise.png +0 -0
- package/docs/images/graph.png +0 -0
- package/docs/images/hero.gif +0 -0
- package/docs/images/model-recommendation.png +0 -0
- package/docs/images/onboarding.png +0 -0
- package/docs/images/organization.png +0 -0
- package/docs/images/skills.png +0 -0
- package/docs/images/tmp_frames/frame_00.png +0 -0
- package/docs/images/tmp_frames/frame_01.png +0 -0
- package/docs/images/tmp_frames/frame_02.png +0 -0
- package/docs/images/tmp_frames/frame_03.png +0 -0
- package/docs/images/tmp_frames/hero_00.png +0 -0
- package/docs/images/tmp_frames/hero_01.png +0 -0
- package/docs/images/tmp_frames/hero_02.png +0 -0
- package/docs/images/tmp_frames/hero_03.png +0 -0
- package/docs/images/workspace.png +0 -0
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/admin.py +17 -0
- package/latticeai/api/models.py +16 -0
- package/latticeai/api/workspace.py +11 -0
- package/latticeai/core/enterprise_admin.py +158 -0
- package/latticeai/core/workspace_os.py +1 -1
- package/latticeai/services/model_catalog.py +289 -0
- package/latticeai/services/model_recommendation.py +183 -0
- package/latticeai/services/model_runtime.py +11 -263
- package/package.json +2 -2
- package/static/scripts/chat.js +66 -0
- package/static/scripts/workspace.js +260 -18
- package/static/workspace.css +67 -0
- package/static/workspace.html +83 -2
|
@@ -86,271 +86,19 @@ def configure_model_runtime(**deps) -> None:
|
|
|
86
86
|
globals().update({key: value for key, value in deps.items() if key in globals()})
|
|
87
87
|
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"label": "Install OpenAI-compatible SDK",
|
|
101
|
-
},
|
|
102
|
-
"groq": {
|
|
103
|
-
"command": [sys.executable, "-m", "pip", "install", "openai"],
|
|
104
|
-
"label": "Install OpenAI-compatible SDK",
|
|
105
|
-
},
|
|
106
|
-
"together": {
|
|
107
|
-
"command": [sys.executable, "-m", "pip", "install", "openai"],
|
|
108
|
-
"label": "Install OpenAI-compatible SDK",
|
|
109
|
-
},
|
|
110
|
-
"xai": {
|
|
111
|
-
"command": [sys.executable, "-m", "pip", "install", "openai"],
|
|
112
|
-
"label": "Install OpenAI-compatible SDK",
|
|
113
|
-
},
|
|
114
|
-
"ollama": {
|
|
115
|
-
"command": ["brew", "install", "ollama"],
|
|
116
|
-
"label": "Install Ollama",
|
|
117
|
-
"requires_binary": "brew",
|
|
118
|
-
},
|
|
119
|
-
"vllm": {
|
|
120
|
-
"command": [sys.executable, "-m", "pip", "install", "vllm", "huggingface_hub[cli]"],
|
|
121
|
-
"label": "Install vLLM runtime",
|
|
122
|
-
},
|
|
123
|
-
"lmstudio": {
|
|
124
|
-
"command": ["brew", "install", "--cask", "lm-studio"],
|
|
125
|
-
"label": "Install LM Studio",
|
|
126
|
-
"requires_binary": "brew",
|
|
127
|
-
},
|
|
128
|
-
"llamacpp": {
|
|
129
|
-
"command": ["brew", "install", "llama.cpp"],
|
|
130
|
-
"label": "Install llama.cpp",
|
|
131
|
-
"requires_binary": "brew",
|
|
132
|
-
},
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
ENGINE_MODEL_CATALOG = {
|
|
136
|
-
"local_mlx": [
|
|
137
|
-
{"id": "mlx-community/SmolLM-1.7B-Instruct-4bit", "name": "SmolLM 1.7B", "family": "SmolLM", "tag": "local-light", "size": "963MB", "pullable": True},
|
|
138
|
-
{"id": "mlx-community/gemma-3-1b-it-4bit", "name": "Gemma 3 1B", "family": "Gemma 3", "tag": "local-light", "size": "733MB", "pullable": True},
|
|
139
|
-
{"id": "mlx-community/Llama-3.2-1B-Instruct-4bit", "name": "Llama 3.2 1B", "family": "Llama 3.x", "tag": "local-light", "size": "1.3GB", "pullable": True},
|
|
140
|
-
{"id": "mlx-community/gemma-2-2b-it-4bit", "name": "Gemma 2 2B", "family": "Gemma 2", "tag": "local-light", "size": "1.6GB", "pullable": True},
|
|
141
|
-
{"id": "mlx-community/gemma-4-e2b-4bit", "name": "Gemma 4 E2B Base", "family": "Gemma 4", "tag": "local-vlm", "size": "3.6GB", "pullable": True},
|
|
142
|
-
{"id": "mlx-community/gemma-4-e2b-it-4bit", "name": "Gemma 4 E2B Instruct", "family": "Gemma 4", "tag": "local-vlm", "size": "3.6GB", "pullable": True},
|
|
143
|
-
{"id": "mlx-community/gemma-4-e4b-4bit", "name": "Gemma 4 E4B Base", "family": "Gemma 4", "tag": "local-vlm", "size": "5.2GB", "pullable": True},
|
|
144
|
-
{"id": "mlx-community/gemma-4-e4b-it-4bit", "name": "Gemma 4 E4B Instruct", "family": "Gemma 4", "tag": "local-vlm", "size": "5.2GB", "pullable": True},
|
|
145
|
-
{"id": "mlx-community/Qwen3-VL-4B-Instruct-4bit", "name": "Qwen3-VL 4B", "family": "Qwen3-VL", "tag": "local-vlm", "size": "2.7GB", "pullable": True},
|
|
146
|
-
{"id": "mlx-community/Qwen3-VL-8B-Instruct-4bit", "name": "Qwen3-VL 8B", "family": "Qwen3-VL", "tag": "local-vlm", "size": "4.8GB", "pullable": True},
|
|
147
|
-
{"id": "mlx-community/Qwen2.5-VL-7B-Instruct-4bit", "name": "Qwen2.5-VL 7B", "family": "Qwen2.5-VL", "tag": "local-vlm", "size": "4.4GB", "pullable": True},
|
|
148
|
-
{"id": "mlx-community/gemma-3-4b-it-4bit", "name": "Gemma 3 4B", "family": "Gemma 3", "tag": "local-vlm", "size": "3.3GB", "pullable": True},
|
|
149
|
-
{"id": "mlx-community/Llama-3.2-3B-Instruct-4bit", "name": "Llama 3.2 3B", "family": "Llama 3.x", "tag": "local-general", "size": "2.0GB", "pullable": True},
|
|
150
|
-
{"id": "mlx-community/Llama-3.1-8B-Instruct-4bit", "name": "Llama 3.1 8B", "family": "Llama 3.1", "tag": "local-general", "size": "4.7GB", "pullable": True},
|
|
151
|
-
{"id": "mlx-community/gemma-2-9b-it-4bit", "name": "Gemma 2 9B", "family": "Gemma 2", "tag": "local-general", "size": "5.4GB", "pullable": True},
|
|
152
|
-
{"id": "mlx-community/gemma-3-12b-it-4bit", "name": "Gemma 3 12B", "family": "Gemma 3", "tag": "local-vlm", "size": "8.0GB", "pullable": True},
|
|
153
|
-
{"id": "mlx-community/Phi-3.5-mini-instruct-4bit", "name": "Phi 3.5 Mini", "family": "Phi", "tag": "local-coding", "size": "2.2GB", "pullable": True},
|
|
154
|
-
{"id": "mlx-community/Phi-4-mini-instruct-4bit", "name": "Phi 4 Mini", "family": "Phi", "tag": "local-coding", "size": "2.2GB", "pullable": True},
|
|
155
|
-
{"id": "mlx-community/phi-4-4bit", "name": "Phi 4", "family": "Phi", "tag": "local-coding", "size": "8.3GB", "pullable": True},
|
|
156
|
-
{"id": "mlx-community/Mistral-7B-Instruct-v0.3-4bit", "name": "Mistral 7B Instruct v0.3", "family": "Mistral", "tag": "local-general", "size": "4.1GB", "pullable": True},
|
|
157
|
-
{"id": "mlx-community/Ministral-8B-Instruct-2410-4bit", "name": "Ministral 8B Instruct", "family": "Mistral", "tag": "local-general", "size": "4.5GB", "pullable": True},
|
|
158
|
-
{"id": "mlx-community/Mistral-Small-24B-Instruct-2501-4bit", "name": "Mistral Small 24B", "family": "Mistral", "tag": "local-large", "size": "13.3GB", "pullable": True},
|
|
159
|
-
{"id": "mlx-community/Qwen2.5-Coder-32B-Instruct-4bit", "name": "Qwen2.5 Coder 32B", "family": "Qwen2.5", "tag": "local-coding", "size": "18.5GB", "pullable": True},
|
|
160
|
-
{"id": "mlx-community/Qwen3-VL-30B-A3B-Instruct-4bit", "name": "Qwen3-VL 30B A3B", "family": "Qwen3-VL", "tag": "local-vlm", "size": "18GB", "pullable": True},
|
|
161
|
-
{"id": "mlx-community/gemma-3-27b-it-4bit", "name": "Gemma 3 27B", "family": "Gemma 3", "tag": "local-vlm", "size": "17GB", "pullable": True},
|
|
162
|
-
{"id": "mlx-community/gemma-4-26b-a4b-it-4bit", "name": "Gemma 4 26B A4B Instruct", "family": "Gemma 4", "tag": "local-vlm", "size": "15.6GB", "pullable": True},
|
|
163
|
-
{"id": "mlx-community/gemma-4-31b-it-4bit", "name": "Gemma 4 31B Instruct", "family": "Gemma 4", "tag": "local-vlm", "size": "18.4GB", "pullable": True},
|
|
164
|
-
{"id": "mlx-community/gpt-oss-20b-MXFP4-Q8", "name": "GPT-OSS 20B", "family": "GPT-OSS", "tag": "local-reasoning", "size": "12.1GB", "pullable": True},
|
|
165
|
-
{"id": "mlx-community/gpt-oss-120b-MXFP4-Q4", "name": "GPT-OSS 120B", "family": "GPT-OSS", "tag": "local-large", "size": "62.3GB", "pullable": True},
|
|
166
|
-
{"id": "mlx-community/Llama-3.3-70B-Instruct-4bit", "name": "Llama 3.3 70B", "family": "Llama 3.x", "tag": "local-general", "size": "40GB+", "pullable": True},
|
|
167
|
-
{"id": "mlx-community/Llama-3.1-70B-Instruct-4bit", "name": "Llama 3.1 70B", "family": "Llama 3.1", "tag": "local-general", "size": "40GB+", "pullable": True},
|
|
168
|
-
],
|
|
169
|
-
"ollama": [
|
|
170
|
-
{"id": "ollama:qwen3-vl:4b", "name": "Qwen3-VL 4B via Ollama", "family": "Qwen3-VL", "tag": "local-vlm", "size": "pull required", "pullable": True},
|
|
171
|
-
{"id": "ollama:qwen3-vl:8b", "name": "Qwen3-VL 8B via Ollama", "family": "Qwen3-VL", "tag": "local-vlm", "size": "pull required", "pullable": True},
|
|
172
|
-
{"id": "ollama:qwen3-vl:30b", "name": "Qwen3-VL 30B via Ollama", "family": "Qwen3-VL", "tag": "local-vlm", "size": "pull required", "pullable": True},
|
|
173
|
-
{"id": "ollama:gpt-oss:20b", "name": "GPT-OSS 20B via Ollama", "family": "GPT-OSS", "tag": "local-reasoning", "size": "pull required", "pullable": True},
|
|
174
|
-
{"id": "ollama:gpt-oss:120b", "name": "GPT-OSS 120B via Ollama", "family": "GPT-OSS", "tag": "local-large", "size": "pull required", "pullable": True},
|
|
175
|
-
{"id": "ollama:hf.co/ggml-org/gemma-4-31B-it-GGUF:Q4_K_M", "name": "Gemma 4 31B Q4 via Ollama", "family": "Gemma 4", "tag": "local-vlm", "size": "18.7GB", "pullable": True},
|
|
176
|
-
{"id": "ollama:qwen3:8b", "name": "Qwen3 8B via Ollama", "family": "Qwen", "tag": "local-server", "size": "pull required", "pullable": True},
|
|
177
|
-
{"id": "ollama:qwen2.5-coder:14b", "name": "Qwen2.5 Coder 14B via Ollama", "family": "Qwen", "tag": "local-coding", "size": "pull required", "pullable": True},
|
|
178
|
-
{"id": "ollama:gemma3:1b", "name": "Gemma 3 1B via Ollama", "family": "Gemma", "tag": "local-light", "size": "pull required", "pullable": True},
|
|
179
|
-
{"id": "ollama:gemma3:4b", "name": "Gemma 3 4B via Ollama", "family": "Gemma", "tag": "local-server", "size": "pull required", "pullable": True},
|
|
180
|
-
{"id": "ollama:gemma3:4b-it-q4_K_M", "name": "Gemma 3 4B q4_K_M via Ollama", "family": "Gemma", "tag": "quantized", "size": "pull required", "pullable": True},
|
|
181
|
-
{"id": "ollama:gemma3:12b", "name": "Gemma 3 12B via Ollama", "family": "Gemma", "tag": "local-server", "size": "pull required", "pullable": True},
|
|
182
|
-
{"id": "ollama:gemma3:12b-it-q4_K_M", "name": "Gemma 3 12B q4_K_M via Ollama", "family": "Gemma", "tag": "quantized", "size": "pull required", "pullable": True},
|
|
183
|
-
{"id": "ollama:gemma3:27b", "name": "Gemma 3 27B via Ollama", "family": "Gemma", "tag": "local-large", "size": "pull required", "pullable": True},
|
|
184
|
-
{"id": "ollama:llama3.2:1b", "name": "Llama 3.2 1B via Ollama", "family": "Llama 3.x", "tag": "local-light", "size": "pull required", "pullable": True},
|
|
185
|
-
{"id": "ollama:llama3.2:3b", "name": "Llama 3.2 3B via Ollama", "family": "Llama 3.x", "tag": "local-server", "size": "pull required", "pullable": True},
|
|
186
|
-
{"id": "ollama:llama3.1:8b", "name": "Llama 3.1 8B via Ollama", "family": "Llama 3.1", "tag": "local-server", "size": "pull required", "pullable": True},
|
|
187
|
-
{"id": "ollama:llama3.1:8b-instruct-q4_0", "name": "Llama 3.1 8B q4_0 via Ollama", "family": "Llama 3.1", "tag": "quantized", "size": "pull required", "pullable": True},
|
|
188
|
-
{"id": "ollama:llama3.1:8b-instruct-q8_0", "name": "Llama 3.1 8B q8_0 via Ollama", "family": "Llama 3.1", "tag": "quantized", "size": "pull required", "pullable": True},
|
|
189
|
-
{"id": "ollama:llama3.1:70b", "name": "Llama 3.1 70B via Ollama", "family": "Llama 3.1", "tag": "local-server", "size": "pull required", "pullable": True},
|
|
190
|
-
{"id": "ollama:llama3.3:70b", "name": "Llama 3.3 70B via Ollama", "family": "Llama 3.x", "tag": "local-large", "size": "pull required", "pullable": True},
|
|
191
|
-
{"id": "ollama:mistral:7b", "name": "Mistral 7B via Ollama", "family": "Mistral", "tag": "local-server", "size": "pull required", "pullable": True},
|
|
192
|
-
{"id": "ollama:mixtral:8x7b", "name": "Mixtral 8x7B via Ollama", "family": "Mistral", "tag": "local-large", "size": "pull required", "pullable": True},
|
|
193
|
-
{"id": "ollama:phi4-mini", "name": "Phi 4 Mini via Ollama", "family": "Phi", "tag": "local-coding", "size": "pull required", "pullable": True},
|
|
194
|
-
{"id": "ollama:phi4", "name": "Phi 4 via Ollama", "family": "Phi", "tag": "local-coding", "size": "pull required", "pullable": True},
|
|
195
|
-
{"id": "ollama:smollm2:1.7b", "name": "SmolLM2 1.7B via Ollama", "family": "SmolLM", "tag": "local-light", "size": "pull required", "pullable": True},
|
|
196
|
-
],
|
|
197
|
-
"vllm": [
|
|
198
|
-
{"id": "vllm:openai/gpt-oss-20b", "name": "GPT-OSS 20B via vLLM", "family": "GPT-OSS", "tag": "local-reasoning", "size": "server model", "pullable": True},
|
|
199
|
-
{"id": "vllm:openai/gpt-oss-120b", "name": "GPT-OSS 120B via vLLM", "family": "GPT-OSS", "tag": "local-large", "size": "server model", "pullable": True},
|
|
200
|
-
{"id": "vllm:Qwen/Qwen3-VL-4B-Instruct", "name": "Qwen3-VL 4B via vLLM", "family": "Qwen3-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
201
|
-
{"id": "vllm:Qwen/Qwen3-VL-8B-Instruct", "name": "Qwen3-VL 8B via vLLM", "family": "Qwen3-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
202
|
-
{"id": "vllm:Qwen/Qwen3-VL-30B-A3B-Instruct", "name": "Qwen3-VL 30B A3B via vLLM", "family": "Qwen3-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
203
|
-
{"id": "vllm:Qwen/Qwen2.5-VL-7B-Instruct", "name": "Qwen2.5-VL 7B via vLLM", "family": "Qwen2.5-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
204
|
-
{"id": "vllm:google/gemma-2-2b", "name": "Gemma 2 2B Base via vLLM", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
205
|
-
{"id": "vllm:google/gemma-2-2b-it", "name": "Gemma 2 2B via vLLM", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
206
|
-
{"id": "vllm:google/gemma-2-9b", "name": "Gemma 2 9B Base via vLLM", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
207
|
-
{"id": "vllm:google/gemma-2-9b-it", "name": "Gemma 2 9B via vLLM", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
208
|
-
{"id": "vllm:google/gemma-3-4b-it", "name": "Gemma 3 4B via vLLM", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
209
|
-
{"id": "vllm:google/gemma-3-12b-it", "name": "Gemma 3 12B via vLLM", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
210
|
-
{"id": "vllm:microsoft/Phi-3.5-mini-instruct", "name": "Phi 3.5 Mini via vLLM", "family": "Phi", "tag": "local-coding", "size": "server model", "pullable": True},
|
|
211
|
-
{"id": "vllm:microsoft/Phi-4-mini-instruct", "name": "Phi 4 Mini via vLLM", "family": "Phi", "tag": "local-coding", "size": "server model", "pullable": True},
|
|
212
|
-
{"id": "vllm:microsoft/phi-4", "name": "Phi 4 via vLLM", "family": "Phi", "tag": "local-coding", "size": "server model", "pullable": True},
|
|
213
|
-
{"id": "vllm:mistralai/Mistral-7B-Instruct-v0.3", "name": "Mistral 7B via vLLM", "family": "Mistral", "tag": "local-server", "size": "server model", "pullable": True},
|
|
214
|
-
{"id": "vllm:mistralai/Ministral-8B-Instruct-2410", "name": "Ministral 8B via vLLM", "family": "Mistral", "tag": "local-server", "size": "server model", "pullable": True},
|
|
215
|
-
{"id": "vllm:mistralai/Mistral-Small-24B-Instruct-2501", "name": "Mistral Small 24B via vLLM", "family": "Mistral", "tag": "local-large", "size": "server model", "pullable": True},
|
|
216
|
-
{"id": "vllm:meta-llama/Llama-3.2-3B-Instruct", "name": "Llama 3.2 3B via vLLM", "family": "Llama 3.x", "tag": "local-server", "size": "server model", "pullable": True},
|
|
217
|
-
{"id": "vllm:meta-llama/Llama-3.1-8B-Instruct", "name": "Llama 3.1 8B via vLLM", "family": "Llama 3.1", "tag": "local-server", "size": "server model", "pullable": True},
|
|
218
|
-
{"id": "vllm:meta-llama/Llama-3.3-70B-Instruct", "name": "Llama 3.3 70B via vLLM", "family": "Llama 3.x", "tag": "local-large", "size": "server model", "pullable": True},
|
|
219
|
-
{"id": "vllm:meta-llama/Llama-3.1-70B-Instruct", "name": "Llama 3.1 70B via vLLM", "family": "Llama 3.1", "tag": "local-server", "size": "server model", "pullable": True},
|
|
220
|
-
],
|
|
221
|
-
"lmstudio": [
|
|
222
|
-
{"id": "lmstudio:openai/gpt-oss-20b", "name": "GPT-OSS 20B via LM Studio", "family": "GPT-OSS", "tag": "local-reasoning", "size": "server model", "pullable": True},
|
|
223
|
-
{"id": "lmstudio:openai/gpt-oss-120b", "name": "GPT-OSS 120B via LM Studio", "family": "GPT-OSS", "tag": "local-large", "size": "server model", "pullable": True},
|
|
224
|
-
{"id": "lmstudio:ggml-org/gemma-4-31B-it-GGUF", "name": "Gemma 4 31B 4-bit via LM Studio", "family": "Gemma 4", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
225
|
-
{"id": "lmstudio:Qwen/Qwen3-VL-4B-Instruct", "name": "Qwen3-VL 4B via LM Studio", "family": "Qwen3-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
226
|
-
{"id": "lmstudio:Qwen/Qwen3-VL-8B-Instruct", "name": "Qwen3-VL 8B via LM Studio", "family": "Qwen3-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
227
|
-
{"id": "lmstudio:Qwen/Qwen3-VL-30B-A3B-Instruct", "name": "Qwen3-VL 30B A3B via LM Studio", "family": "Qwen3-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
228
|
-
{"id": "lmstudio:Qwen/Qwen2.5-VL-7B-Instruct", "name": "Qwen2.5-VL 7B via LM Studio", "family": "Qwen2.5-VL", "tag": "local-vlm", "size": "server model", "pullable": True},
|
|
229
|
-
{"id": "lmstudio:google/gemma-2-2b-it", "name": "Gemma 2 2B via LM Studio", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
230
|
-
{"id": "lmstudio:google/gemma-2-9b-it", "name": "Gemma 2 9B via LM Studio", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
231
|
-
{"id": "lmstudio:google/gemma-3-4b-it", "name": "Gemma 3 4B via LM Studio", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
232
|
-
{"id": "lmstudio:google/gemma-3-12b-it", "name": "Gemma 3 12B via LM Studio", "family": "Gemma", "tag": "local-server", "size": "server model", "pullable": True},
|
|
233
|
-
{"id": "lmstudio:microsoft/Phi-3.5-mini-instruct", "name": "Phi 3.5 Mini via LM Studio", "family": "Phi", "tag": "local-coding", "size": "server model", "pullable": True},
|
|
234
|
-
{"id": "lmstudio:microsoft/Phi-4-mini-instruct", "name": "Phi 4 Mini via LM Studio", "family": "Phi", "tag": "local-coding", "size": "server model", "pullable": True},
|
|
235
|
-
{"id": "lmstudio:microsoft/phi-4", "name": "Phi 4 via LM Studio", "family": "Phi", "tag": "local-coding", "size": "server model", "pullable": True},
|
|
236
|
-
{"id": "lmstudio:mistralai/Mistral-7B-Instruct-v0.3", "name": "Mistral 7B via LM Studio", "family": "Mistral", "tag": "local-server", "size": "server model", "pullable": True},
|
|
237
|
-
{"id": "lmstudio:mistralai/Ministral-8B-Instruct-2410", "name": "Ministral 8B via LM Studio", "family": "Mistral", "tag": "local-server", "size": "server model", "pullable": True},
|
|
238
|
-
{"id": "lmstudio:mistralai/Mistral-Small-24B-Instruct-2501", "name": "Mistral Small 24B via LM Studio", "family": "Mistral", "tag": "local-large", "size": "server model", "pullable": True},
|
|
239
|
-
{"id": "lmstudio:meta-llama/Llama-3.2-3B-Instruct", "name": "Llama 3.2 3B via LM Studio", "family": "Llama 3.x", "tag": "local-server", "size": "server model", "pullable": True},
|
|
240
|
-
{"id": "lmstudio:meta-llama/Llama-3.1-8B-Instruct", "name": "Llama 3.1 8B via LM Studio", "family": "Llama 3.1", "tag": "local-server", "size": "server model", "pullable": True},
|
|
241
|
-
{"id": "lmstudio:meta-llama/Llama-3.3-70B-Instruct", "name": "Llama 3.3 70B via LM Studio", "family": "Llama 3.x", "tag": "local-large", "size": "server model", "pullable": True},
|
|
242
|
-
{"id": "lmstudio:meta-llama/Llama-3.1-70B-Instruct", "name": "Llama 3.1 70B via LM Studio", "family": "Llama 3.1", "tag": "local-server", "size": "server model", "pullable": True},
|
|
243
|
-
],
|
|
244
|
-
"llamacpp": [
|
|
245
|
-
{"id": "llamacpp:ggml-org/gpt-oss-20b-GGUF", "name": "GPT-OSS 20B GGUF via llama.cpp", "family": "GPT-OSS", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
246
|
-
{"id": "llamacpp:ggml-org/gpt-oss-120b-GGUF", "name": "GPT-OSS 120B GGUF via llama.cpp", "family": "GPT-OSS", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
247
|
-
{"id": "llamacpp:ggml-org/gemma-4-31B-it-GGUF", "name": "Gemma 4 31B GGUF via llama.cpp", "family": "Gemma 4", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
248
|
-
{"id": "llamacpp:Qwen/Qwen3-VL-4B-Instruct-GGUF", "name": "Qwen3-VL 4B GGUF via llama.cpp", "family": "Qwen3-VL", "tag": "gguf-vlm", "size": "gguf", "pullable": True},
|
|
249
|
-
{"id": "llamacpp:Qwen/Qwen3-VL-8B-Instruct-GGUF", "name": "Qwen3-VL 8B GGUF via llama.cpp", "family": "Qwen3-VL", "tag": "gguf-vlm", "size": "gguf", "pullable": True},
|
|
250
|
-
{"id": "llamacpp:unsloth/gemma-2-2b-it-GGUF", "name": "Gemma 2 2B GGUF via llama.cpp", "family": "Gemma", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
251
|
-
{"id": "llamacpp:unsloth/gemma-2-9b-it-GGUF", "name": "Gemma 2 9B GGUF via llama.cpp", "family": "Gemma", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
252
|
-
{"id": "llamacpp:unsloth/gemma-3-4b-it-GGUF", "name": "Gemma 3 4B GGUF via llama.cpp", "family": "Gemma", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
253
|
-
{"id": "llamacpp:bartowski/Mistral-7B-Instruct-v0.3-GGUF", "name": "Mistral 7B GGUF via llama.cpp", "family": "Mistral", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
254
|
-
{"id": "llamacpp:bartowski/Phi-3.5-mini-instruct-GGUF", "name": "Phi 3.5 Mini GGUF via llama.cpp", "family": "Phi", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
255
|
-
{"id": "llamacpp:bartowski/phi-4-GGUF", "name": "Phi 4 GGUF via llama.cpp", "family": "Phi", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
256
|
-
{"id": "llamacpp:bartowski/Llama-3.2-3B-Instruct-GGUF", "name": "Llama 3.2 3B GGUF via llama.cpp", "family": "Llama 3.x", "tag": "gguf-q4", "size": "gguf", "pullable": True},
|
|
257
|
-
{"id": "llamacpp:bartowski/Llama-3.1-8B-Instruct-GGUF", "name": "Llama 3.1 8B GGUF via llama.cpp", "family": "Llama 3.1", "tag": "local-server", "size": "gguf", "pullable": True},
|
|
258
|
-
{"id": "llamacpp:bartowski/Llama-3.3-70B-Instruct-GGUF", "name": "Llama 3.3 70B GGUF via llama.cpp", "family": "Llama 3.x", "tag": "local-large", "size": "gguf", "pullable": True},
|
|
259
|
-
{"id": "llamacpp:bartowski/Llama-3.1-70B-Instruct-GGUF", "name": "Llama 3.1 70B GGUF via llama.cpp", "family": "Llama 3.1", "tag": "local-server", "size": "gguf", "pullable": True},
|
|
260
|
-
],
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
MODEL_ENGINE_ALIASES = {
|
|
264
|
-
"gpt-oss-20b": {
|
|
265
|
-
"local_mlx": "mlx-community/gpt-oss-20b-MXFP4-Q8",
|
|
266
|
-
"ollama": "gpt-oss:20b",
|
|
267
|
-
"vllm": "openai/gpt-oss-20b",
|
|
268
|
-
"lmstudio": "openai/gpt-oss-20b",
|
|
269
|
-
"llamacpp": "ggml-org/gpt-oss-20b-GGUF",
|
|
270
|
-
},
|
|
271
|
-
"openai/gpt-oss-20b": {
|
|
272
|
-
"local_mlx": "mlx-community/gpt-oss-20b-MXFP4-Q8",
|
|
273
|
-
"ollama": "gpt-oss:20b",
|
|
274
|
-
"vllm": "openai/gpt-oss-20b",
|
|
275
|
-
"lmstudio": "openai/gpt-oss-20b",
|
|
276
|
-
"llamacpp": "ggml-org/gpt-oss-20b-GGUF",
|
|
277
|
-
},
|
|
278
|
-
"gpt-oss-120b": {
|
|
279
|
-
"local_mlx": "mlx-community/gpt-oss-120b-MXFP4-Q4",
|
|
280
|
-
"ollama": "gpt-oss:120b",
|
|
281
|
-
"vllm": "openai/gpt-oss-120b",
|
|
282
|
-
"lmstudio": "openai/gpt-oss-120b",
|
|
283
|
-
"llamacpp": "ggml-org/gpt-oss-120b-GGUF",
|
|
284
|
-
},
|
|
285
|
-
"openai/gpt-oss-120b": {
|
|
286
|
-
"local_mlx": "mlx-community/gpt-oss-120b-MXFP4-Q4",
|
|
287
|
-
"ollama": "gpt-oss:120b",
|
|
288
|
-
"vllm": "openai/gpt-oss-120b",
|
|
289
|
-
"lmstudio": "openai/gpt-oss-120b",
|
|
290
|
-
"llamacpp": "ggml-org/gpt-oss-120b-GGUF",
|
|
291
|
-
},
|
|
292
|
-
"gemma-4-31b-it-4bit": {
|
|
293
|
-
"local_mlx": "mlx-community/gemma-4-31b-it-4bit",
|
|
294
|
-
"ollama": "hf.co/ggml-org/gemma-4-31B-it-GGUF:Q4_K_M",
|
|
295
|
-
"vllm": "suitch/gemma-4-31B-it-4bit",
|
|
296
|
-
"lmstudio": "ggml-org/gemma-4-31B-it-GGUF",
|
|
297
|
-
"llamacpp": "ggml-org/gemma-4-31B-it-GGUF",
|
|
298
|
-
},
|
|
299
|
-
"suitch/gemma-4-31b-it-4bit": {
|
|
300
|
-
"local_mlx": "mlx-community/gemma-4-31b-it-4bit",
|
|
301
|
-
"ollama": "hf.co/ggml-org/gemma-4-31B-it-GGUF:Q4_K_M",
|
|
302
|
-
"vllm": "suitch/gemma-4-31B-it-4bit",
|
|
303
|
-
"lmstudio": "ggml-org/gemma-4-31B-it-GGUF",
|
|
304
|
-
"llamacpp": "ggml-org/gemma-4-31B-it-GGUF",
|
|
305
|
-
},
|
|
306
|
-
"mlx-community/gemma-4-31b-it-4bit": {
|
|
307
|
-
"local_mlx": "mlx-community/gemma-4-31b-it-4bit",
|
|
308
|
-
"ollama": "hf.co/ggml-org/gemma-4-31B-it-GGUF:Q4_K_M",
|
|
309
|
-
"vllm": "suitch/gemma-4-31B-it-4bit",
|
|
310
|
-
"lmstudio": "ggml-org/gemma-4-31B-it-GGUF",
|
|
311
|
-
"llamacpp": "ggml-org/gemma-4-31B-it-GGUF",
|
|
312
|
-
},
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
_VERSIONED_MODEL_PATTERNS = (
|
|
316
|
-
("gemma", re.compile(r"\bgemma[-\s]?(\d+(?:\.\d+)?)", re.IGNORECASE)),
|
|
317
|
-
("qwen", re.compile(r"\bqwen[-\s]?(\d+(?:\.\d+)?)", re.IGNORECASE)),
|
|
318
|
-
("llama", re.compile(r"\bllama[-\s]?(\d+(?:\.\d+)?)", re.IGNORECASE)),
|
|
319
|
-
("phi", re.compile(r"\bphi[-\s]?(\d+(?:\.\d+)?)", re.IGNORECASE)),
|
|
89
|
+
# Catalog data + version-dedup helpers live in ``model_catalog``; re-exported
|
|
90
|
+
# here so existing ``from ...model_runtime import ENGINE_MODEL_CATALOG`` imports
|
|
91
|
+
# keep working.
|
|
92
|
+
from latticeai.services.model_catalog import ( # noqa: F401 (re-export)
|
|
93
|
+
ENGINE_INSTALLERS,
|
|
94
|
+
ENGINE_MODEL_CATALOG,
|
|
95
|
+
MODEL_ENGINE_ALIASES,
|
|
96
|
+
_VERSIONED_MODEL_PATTERNS,
|
|
97
|
+
_model_family_version,
|
|
98
|
+
_version_tuple,
|
|
99
|
+
filter_lower_family_versions,
|
|
320
100
|
)
|
|
321
101
|
|
|
322
|
-
|
|
323
|
-
def _version_tuple(raw: str) -> tuple[int, ...]:
|
|
324
|
-
return tuple(int(part) for part in raw.split(".") if part.isdigit())
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
def _model_family_version(model: Dict[str, object]) -> Optional[tuple[str, tuple[int, ...]]]:
|
|
328
|
-
text = " ".join(str(model.get(key) or "") for key in ("family", "name", "id"))
|
|
329
|
-
for family, pattern in _VERSIONED_MODEL_PATTERNS:
|
|
330
|
-
match = pattern.search(text)
|
|
331
|
-
if match:
|
|
332
|
-
version = _version_tuple(match.group(1))
|
|
333
|
-
if version:
|
|
334
|
-
return family, version
|
|
335
|
-
return None
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
def filter_lower_family_versions(models: List[Dict[str, object]]) -> List[Dict[str, object]]:
|
|
339
|
-
max_versions: Dict[str, tuple[int, ...]] = {}
|
|
340
|
-
detected: List[tuple[Dict[str, object], Optional[tuple[str, tuple[int, ...]]]]] = []
|
|
341
|
-
for model in models:
|
|
342
|
-
version_info = _model_family_version(model)
|
|
343
|
-
detected.append((model, version_info))
|
|
344
|
-
if not version_info:
|
|
345
|
-
continue
|
|
346
|
-
family, version = version_info
|
|
347
|
-
if version > max_versions.get(family, (0,)):
|
|
348
|
-
max_versions[family] = version
|
|
349
|
-
return [
|
|
350
|
-
model for model, version_info in detected
|
|
351
|
-
if not version_info or version_info[1] >= max_versions.get(version_info[0], version_info[1])
|
|
352
|
-
]
|
|
353
|
-
|
|
354
102
|
def _update_env_file(env_file: Path, key: str, value: str) -> None:
|
|
355
103
|
lines = []
|
|
356
104
|
found = False
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ltcai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Lattice AI Workspace OS for local-first graph, memory, agent, workflow, and skill operations",
|
|
5
5
|
"homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dev": "python3 ltcai_cli.py --reload",
|
|
20
20
|
"build": "npm run build:python",
|
|
21
21
|
"build:python": "python3 -m build",
|
|
22
|
-
"check:python": "python3 -m py_compile ltcai_cli.py server.py latticeai/server_app.py latticeai/api/chat.py latticeai/api/computer_use.py latticeai/api/deps.py latticeai/api/garden.py latticeai/api/local_files.py latticeai/api/permissions.py latticeai/api/setup.py latticeai/api/static_routes.py latticeai/api/tools.py latticeai/services/app_context.py latticeai/services/model_runtime.py latticeai/services/tool_dispatch.py latticeai/services/upload_service.py latticeai/core/tool_registry.py latticeai/core/agent_prompts.py latticeai/core/workspace_os.py knowledge_graph.py knowledge_graph_api.py local_knowledge_api.py llm_router.py p_reinforce.py telegram_bot.py tools.py codex_telegram_bot.py",
|
|
22
|
+
"check:python": "python3 -m py_compile ltcai_cli.py server.py latticeai/server_app.py latticeai/api/chat.py latticeai/api/computer_use.py latticeai/api/deps.py latticeai/api/garden.py latticeai/api/local_files.py latticeai/api/permissions.py latticeai/api/setup.py latticeai/api/static_routes.py latticeai/api/tools.py latticeai/services/app_context.py latticeai/services/model_runtime.py latticeai/services/model_catalog.py latticeai/services/model_recommendation.py latticeai/services/tool_dispatch.py latticeai/services/upload_service.py latticeai/core/tool_registry.py latticeai/core/enterprise.py latticeai/core/enterprise_admin.py latticeai/core/agent_prompts.py latticeai/core/workspace_os.py knowledge_graph.py knowledge_graph_api.py local_knowledge_api.py llm_router.py p_reinforce.py telegram_bot.py tools.py codex_telegram_bot.py",
|
|
23
23
|
"test": "python3 -m pytest tests/ -v",
|
|
24
24
|
"test:unit": "python3 -m pytest tests/unit/ -v",
|
|
25
25
|
"test:integration": "python3 -m pytest tests/integration/ -v",
|
package/static/scripts/chat.js
CHANGED
|
@@ -1016,10 +1016,76 @@ const chatViewport = document.getElementById('chat-viewport');
|
|
|
1016
1016
|
<p>${escapeHtml(rec.reason || '현재 PC 환경과 선택한 워크스페이스 기준으로 추천했습니다.')}</p>
|
|
1017
1017
|
</article>
|
|
1018
1018
|
</div>
|
|
1019
|
+
<div id="onboarding-model-compat" class="onboarding-model-compat"></div>
|
|
1019
1020
|
`, `
|
|
1020
1021
|
<button class="onboarding-secondary" onclick="renderOnboardingCustomModelSelect()">개인이 원하는 설정으로 시작</button>
|
|
1021
1022
|
<button class="onboarding-primary" onclick="runOnboardingSetup()">추천 설정으로 시작하기</button>
|
|
1022
1023
|
`);
|
|
1024
|
+
// Best-effort: surface the hardware-aware tri-state model catalog.
|
|
1025
|
+
loadCompatibleModels();
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
async function loadCompatibleModels() {
|
|
1029
|
+
const container = document.getElementById('onboarding-model-compat');
|
|
1030
|
+
if (!container) return;
|
|
1031
|
+
try {
|
|
1032
|
+
const res = await apiFetch('/models/recommendations');
|
|
1033
|
+
const data = await res.json();
|
|
1034
|
+
if (!res.ok) return;
|
|
1035
|
+
const rec = (data && data.recommendations) || {};
|
|
1036
|
+
const profile = (data && data.profile) || {};
|
|
1037
|
+
const families = rec.families || [];
|
|
1038
|
+
if (!families.length) return;
|
|
1039
|
+
const counts = rec.counts || {};
|
|
1040
|
+
const badge = (status) => {
|
|
1041
|
+
const map = {
|
|
1042
|
+
recommended: ['추천', '#16a34a'],
|
|
1043
|
+
compatible: ['실행 가능', '#d97706'],
|
|
1044
|
+
not_recommended: ['권장 안 함', '#9ca3af'],
|
|
1045
|
+
};
|
|
1046
|
+
const [label, color] = map[status] || ['', '#9ca3af'];
|
|
1047
|
+
return `<span style="display:inline-block;padding:1px 8px;border-radius:999px;font-size:11px;font-weight:700;color:#fff;background:${color}">${label}</span>`;
|
|
1048
|
+
};
|
|
1049
|
+
const ram = (m) => (m.required_ram_gb != null) ? `~${m.required_ram_gb}GB RAM (est.)` : '';
|
|
1050
|
+
const nextStep = (engine) => engine === 'ollama'
|
|
1051
|
+
? 'Next: ollama pull'
|
|
1052
|
+
: engine === 'local_mlx' ? 'Next: download & load' : 'Next: connect engine';
|
|
1053
|
+
|
|
1054
|
+
// Top pick callout
|
|
1055
|
+
const top = rec.top_pick;
|
|
1056
|
+
const topHtml = top ? `
|
|
1057
|
+
<div style="border:1px solid #16a34a;background:#f0fdf4;border-radius:10px;padding:10px 12px;margin:8px 0">
|
|
1058
|
+
<div style="font-weight:700">⭐ Best for this PC — ${escapeHtml(top.name || top.id)} ${badge('recommended')}</div>
|
|
1059
|
+
<div style="font-size:12px;opacity:0.8;margin-top:3px">${escapeHtml(top.reason || '')}</div>
|
|
1060
|
+
<div style="font-size:12px;margin-top:4px">${escapeHtml(top.size || '')} · ${escapeHtml(ram(top))} · ${escapeHtml(nextStep(rec.engine))}</div>
|
|
1061
|
+
</div>` : '';
|
|
1062
|
+
|
|
1063
|
+
const rows = families.map((fam) => {
|
|
1064
|
+
const best = fam.best;
|
|
1065
|
+
const items = (fam.models || []).map((m) => `
|
|
1066
|
+
<div style="display:flex;justify-content:space-between;gap:8px;padding:3px 0;font-size:12px;opacity:${m.status === 'not_recommended' ? 0.55 : 1}">
|
|
1067
|
+
<span>${escapeHtml(m.name || m.id)}</span>
|
|
1068
|
+
<span style="white-space:nowrap">${escapeHtml(m.size || '')} · ${escapeHtml(ram(m))} ${badge(m.status)}</span>
|
|
1069
|
+
</div>`).join('');
|
|
1070
|
+
return `
|
|
1071
|
+
<details style="margin:6px 0;border:1px solid var(--border,#e5e7eb);border-radius:8px;padding:8px 10px">
|
|
1072
|
+
<summary style="cursor:pointer;font-weight:600">${escapeHtml(fam.family)} ${best ? badge(best.status) : ''}${best ? ` <span style="font-weight:400;opacity:0.7">${escapeHtml(best.name || '')}</span>` : ''}</summary>
|
|
1073
|
+
<div style="margin-top:6px">${items}</div>
|
|
1074
|
+
</details>`;
|
|
1075
|
+
}).join('');
|
|
1076
|
+
|
|
1077
|
+
const engineLabel = rec.engine === 'local_mlx' ? 'MLX (Apple Silicon)' : rec.engine;
|
|
1078
|
+
const machine = `${profile.os || ''} · RAM ${rec.ram_gb || '?'}GB · ${rec.apple_silicon ? 'Apple Silicon' : (profile.gpu && profile.gpu.vendor) || 'CPU'} · engine ${engineLabel}`;
|
|
1079
|
+
container.innerHTML = `
|
|
1080
|
+
<h3 style="margin:14px 0 4px">이 PC에 맞는 로컬 모델</h3>
|
|
1081
|
+
<p style="font-size:12px;opacity:0.7;margin:0 0 4px">${escapeHtml(machine)}</p>
|
|
1082
|
+
<p style="font-size:12px;opacity:0.7;margin:0 0 6px">${badge('recommended')} ${counts.recommended || 0} · ${badge('compatible')} ${counts.compatible || 0} · ${badge('not_recommended')} ${counts.not_recommended || 0} · estimates are conservative, verify before loading</p>
|
|
1083
|
+
${topHtml}
|
|
1084
|
+
${rows}
|
|
1085
|
+
<p style="font-size:12px;opacity:0.65;margin:8px 0 0">로컬 모델이 부족하면 클라우드 모델(OpenAI·OpenRouter·Groq 등, API 키 필요)을 선택할 수 있습니다.</p>`;
|
|
1086
|
+
} catch (e) {
|
|
1087
|
+
/* best-effort enhancement; never break onboarding */
|
|
1088
|
+
}
|
|
1023
1089
|
}
|
|
1024
1090
|
|
|
1025
1091
|
function recommendedSetupItems() {
|