turbollm 1.6.1 → 1.6.2
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/LICENSE.md +105 -105
- package/README.md +7 -4
- package/bin/turbollm.mjs +25 -25
- package/dist/cli.js +194 -41
- package/dist/webdist/assets/{AgentsScreen-Bm0dlNUs.js → AgentsScreen-BviDj463.js} +1 -1
- package/dist/webdist/assets/ChatScreen-4a_6ZX6c.js +29 -0
- package/dist/webdist/assets/CustomizeScreen-BhZJK7xv.js +4 -0
- package/dist/webdist/assets/{DeveloperScreen-EeXXJhPl.js → DeveloperScreen-8CVekggw.js} +1 -1
- package/dist/webdist/assets/EnginesScreen-zHLzht8k.js +7 -0
- package/dist/webdist/assets/ModelDetailDialog-DjMSf0rz.js +29 -0
- package/dist/webdist/assets/{ModelDirs-ChNMfQlk.js → ModelDirs-CIOcl5qu.js} +1 -1
- package/dist/webdist/assets/ModelsScreen-v7kDcWmr.js +2 -0
- package/dist/webdist/assets/{SettingsScreen-fyDtvMAN.js → SettingsScreen-DnSgBps7.js} +1 -1
- package/dist/webdist/assets/alert-dialog-93rFXd1_.js +1 -0
- package/dist/webdist/assets/{arc-CuIEySlm.js → arc-BFc9YP9w.js} +1 -1
- package/dist/webdist/assets/{architectureDiagram-3BPJPVTR-CDtTHNKE.js → architectureDiagram-3BPJPVTR-Bd6WFbHz.js} +1 -1
- package/dist/webdist/assets/{arrow-left-BhWtMEXH.js → arrow-left--NjoPnor.js} +1 -1
- package/dist/webdist/assets/{blockDiagram-GPEHLZMM--Dy7JNXf.js → blockDiagram-GPEHLZMM-Dupawk92.js} +1 -1
- package/dist/webdist/assets/{c4Diagram-AAUBKEIU-XVnczljG.js → c4Diagram-AAUBKEIU-BMhAUE8i.js} +1 -1
- package/dist/webdist/assets/channel-BCSKocRg.js +1 -0
- package/dist/webdist/assets/check-Bu2UFiB0.js +1 -0
- package/dist/webdist/assets/chevron-right-kiIQKgde.js +1 -0
- package/dist/webdist/assets/{chunk-2J33WTMH-C077hTl3.js → chunk-2J33WTMH-BhxySqcq.js} +1 -1
- package/dist/webdist/assets/{chunk-4BX2VUAB-DKdVCoaf.js → chunk-4BX2VUAB-B-UGkx88.js} +1 -1
- package/dist/webdist/assets/{chunk-55IACEB6-COscQ2lU.js → chunk-55IACEB6-BDvjmk8T.js} +1 -1
- package/dist/webdist/assets/{chunk-727SXJPM-DWN7NXCr.js → chunk-727SXJPM-BhyFFQxZ.js} +1 -1
- package/dist/webdist/assets/{chunk-AQP2D5EJ-DunZhDts.js → chunk-AQP2D5EJ-VTSW3fZJ.js} +1 -1
- package/dist/webdist/assets/{chunk-FMBD7UC4-Cs40cRbK.js → chunk-FMBD7UC4-QKx1b_-m.js} +1 -1
- package/dist/webdist/assets/{chunk-ND2GUHAM-DpXYV_RZ.js → chunk-ND2GUHAM-DZANzpY0.js} +1 -1
- package/dist/webdist/assets/{chunk-QZHKN3VN-D6BC_875.js → chunk-QZHKN3VN-DVZIy115.js} +1 -1
- package/dist/webdist/assets/circle-check-C4aACGyb.js +1 -0
- package/dist/webdist/assets/circle-x-koFsrlGA.js +1 -0
- package/dist/webdist/assets/classDiagram-4FO5ZUOK-B_Eb_jRj.js +1 -0
- package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-B_Eb_jRj.js +1 -0
- package/dist/webdist/assets/common-CQVogVIs.js +1 -0
- package/dist/webdist/assets/{copy-button-BDBGYJyK.js → copy-button-3_2Us2zb.js} +1 -1
- package/dist/webdist/assets/{cose-bilkent-S5V4N54A-CBdxwvXL.js → cose-bilkent-S5V4N54A-Ci07N3_4.js} +1 -1
- package/dist/webdist/assets/{dagre-BM42HDAG--TuZmFxK.js → dagre-BM42HDAG-45qc0phu.js} +1 -1
- package/dist/webdist/assets/{diagram-2AECGRRQ-CBd1wCAj.js → diagram-2AECGRRQ-DA3u3hzE.js} +1 -1
- package/dist/webdist/assets/{diagram-5GNKFQAL-CGhx3UWE.js → diagram-5GNKFQAL-B3wpvPKp.js} +1 -1
- package/dist/webdist/assets/{diagram-KO2AKTUF-Cao3Duro.js → diagram-KO2AKTUF-h1qR3ckq.js} +1 -1
- package/dist/webdist/assets/{diagram-LMA3HP47-WjRqqdMT.js → diagram-LMA3HP47-B3uU2roT.js} +1 -1
- package/dist/webdist/assets/{diagram-OG6HWLK6-2ox056u5.js → diagram-OG6HWLK6-CibVtZrO.js} +1 -1
- package/dist/webdist/assets/dialog-Dn3dxmMP.js +1 -0
- package/dist/webdist/assets/{erDiagram-TEJ5UH35-ArZ5ZZJa.js → erDiagram-TEJ5UH35-VsHZBAOZ.js} +1 -1
- package/dist/webdist/assets/{flowDiagram-I6XJVG4X-B9tLKPOZ.js → flowDiagram-I6XJVG4X-DhYah8sF.js} +1 -1
- package/dist/webdist/assets/{ganttDiagram-6RSMTGT7-C-N7wsLt.js → ganttDiagram-6RSMTGT7-RPkNEJnH.js} +1 -1
- package/dist/webdist/assets/{gitGraphDiagram-PVQCEYII-WMWkUM9v.js → gitGraphDiagram-PVQCEYII-JknfsYQp.js} +1 -1
- package/dist/webdist/assets/index-5NYGYU_t.css +1 -0
- package/dist/webdist/assets/{index-BEuak5p5.js → index-K2ZQBdky.js} +4 -4
- package/dist/webdist/assets/{infoDiagram-5YYISTIA-cGx1kqp-.js → infoDiagram-5YYISTIA-BeGMPySd.js} +1 -1
- package/dist/webdist/assets/{ishikawaDiagram-YF4QCWOH-CKuSQqaZ.js → ishikawaDiagram-YF4QCWOH-D38Q1-tz.js} +1 -1
- package/dist/webdist/assets/{journeyDiagram-JHISSGLW-3nxSzaVj.js → journeyDiagram-JHISSGLW-CG8TFzp6.js} +1 -1
- package/dist/webdist/assets/{kanban-definition-UN3LZRKU-_hSS8ZRB.js → kanban-definition-UN3LZRKU-CNgUZ1rd.js} +1 -1
- package/dist/webdist/assets/{linear-DcWs5d6j.js → linear-DYIxmEeo.js} +1 -1
- package/dist/webdist/assets/{mermaid.core-vZsS4NJL.js → mermaid.core-CZhJJFjL.js} +4 -4
- package/dist/webdist/assets/{mindmap-definition-RKZ34NQL-DB5Mtp7f.js → mindmap-definition-RKZ34NQL-BIVYSbvh.js} +1 -1
- package/dist/webdist/assets/pencil-iVnKKeCp.js +1 -0
- package/dist/webdist/assets/{personas-DdUgL1dH.js → personas-DslX_qdt.js} +4 -4
- package/dist/webdist/assets/{pieDiagram-4H26LBE5-C1qmat-q.js → pieDiagram-4H26LBE5-CU9qALXo.js} +1 -1
- package/dist/webdist/assets/plus-mSm32jpN.js +1 -0
- package/dist/webdist/assets/{quadrantDiagram-W4KKPZXB-Boa-e85b.js → quadrantDiagram-W4KKPZXB-AE50YmvR.js} +1 -1
- package/dist/webdist/assets/{radix-4XwKfE88.js → radix-9WP-OkMY.js} +2 -2
- package/dist/webdist/assets/refresh-cw-C04dn1r1.js +1 -0
- package/dist/webdist/assets/{requirementDiagram-4Y6WPE33-Bmp1KNz5.js → requirementDiagram-4Y6WPE33-Crymka5P.js} +1 -1
- package/dist/webdist/assets/{sankeyDiagram-5OEKKPKP-BW5ZiXqU.js → sankeyDiagram-5OEKKPKP-DRviwCen.js} +1 -1
- package/dist/webdist/assets/save-BT2nzRB6.js +1 -0
- package/dist/webdist/assets/{sequenceDiagram-3UESZ5HK-Dqsa-4BM.js → sequenceDiagram-3UESZ5HK-DuBllsfJ.js} +1 -1
- package/dist/webdist/assets/skeleton-BfMJjCGZ.js +1 -0
- package/dist/webdist/assets/{stateDiagram-AJRCARHV-BBfHSXy1.js → stateDiagram-AJRCARHV-Cj4BwRLl.js} +1 -1
- package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-Y25sKBZm.js +1 -0
- package/dist/webdist/assets/{timeline-definition-PNZ67QCA-BHarWHkU.js → timeline-definition-PNZ67QCA-BWnH2-RY.js} +1 -1
- package/dist/webdist/assets/trash-2-Ce39UFy5.js +1 -0
- package/dist/webdist/assets/{vendor-CKtmMAvG.js → vendor-W5GIuFcv.js} +1 -1
- package/dist/webdist/assets/{vennDiagram-CIIHVFJN-DTvjLJ1x.js → vennDiagram-CIIHVFJN-GgdSx9c7.js} +1 -1
- package/dist/webdist/assets/{wardley-L42UT6IY-DOFy2Cyi.js → wardley-L42UT6IY-C9XKbMb6.js} +1 -1
- package/dist/webdist/assets/{wardleyDiagram-YWT4CUSO-FMOMz9fW.js → wardleyDiagram-YWT4CUSO-ZxceNtWm.js} +1 -1
- package/dist/webdist/assets/{wrench-C8ZOI3oB.js → wrench-Ceqe74n2.js} +1 -1
- package/dist/webdist/assets/{xychartDiagram-2RQKCTM6-pxISvXSk.js → xychartDiagram-2RQKCTM6-C-mAbbHW.js} +1 -1
- package/dist/webdist/favicon.svg +4 -4
- package/dist/webdist/index.html +20 -20
- package/package.json +1 -1
- package/dist/webdist/assets/ChatScreen-De7mfm87.js +0 -57
- package/dist/webdist/assets/CustomizeScreen-BhJkwqO1.js +0 -4
- package/dist/webdist/assets/EnginesScreen-4MCxOhkl.js +0 -7
- package/dist/webdist/assets/ModelDetailDialog-BhySVphP.js +0 -1
- package/dist/webdist/assets/ModelsScreen-DSZhXs2J.js +0 -1
- package/dist/webdist/assets/channel-C4W_mju9.js +0 -1
- package/dist/webdist/assets/check-BJnna3cY.js +0 -1
- package/dist/webdist/assets/chevron-right-DJQHNjeM.js +0 -1
- package/dist/webdist/assets/circle-check-CYzq3xdq.js +0 -1
- package/dist/webdist/assets/circle-x-A-lKHO2r.js +0 -1
- package/dist/webdist/assets/classDiagram-4FO5ZUOK-CcUXUVK5.js +0 -1
- package/dist/webdist/assets/classDiagram-v2-Q7XG4LA2-CcUXUVK5.js +0 -1
- package/dist/webdist/assets/common-Bs-nRFXO.js +0 -1
- package/dist/webdist/assets/dialog-CxAGijbe.js +0 -1
- package/dist/webdist/assets/index-CJj8sGhF.css +0 -1
- package/dist/webdist/assets/pencil-BC_D38u5.js +0 -1
- package/dist/webdist/assets/plus-CYdaHYzw.js +0 -1
- package/dist/webdist/assets/refresh-cw-CAf-srhC.js +0 -1
- package/dist/webdist/assets/save-CuovAu9V.js +0 -1
- package/dist/webdist/assets/skeleton-sJWGKoPW.js +0 -1
- package/dist/webdist/assets/stateDiagram-v2-BHNVJYJU-DHCBzQwe.js +0 -1
- package/dist/webdist/assets/trash-2-BxB6A4uU.js +0 -1
package/LICENSE.md
CHANGED
|
@@ -1,105 +1,105 @@
|
|
|
1
|
-
# Functional Source License, Version 1.1, ALv2 Future License
|
|
2
|
-
|
|
3
|
-
## Abbreviation
|
|
4
|
-
|
|
5
|
-
FSL-1.1-ALv2
|
|
6
|
-
|
|
7
|
-
## Notice
|
|
8
|
-
|
|
9
|
-
Copyright 2026 Mohit Soni
|
|
10
|
-
|
|
11
|
-
## Terms and Conditions
|
|
12
|
-
|
|
13
|
-
### Licensor ("We")
|
|
14
|
-
|
|
15
|
-
The party offering the Software under these Terms and Conditions.
|
|
16
|
-
|
|
17
|
-
### The Software
|
|
18
|
-
|
|
19
|
-
The "Software" is each version of the software that we make available under
|
|
20
|
-
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
-
Conditions with the Software.
|
|
22
|
-
|
|
23
|
-
### License Grant
|
|
24
|
-
|
|
25
|
-
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
-
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
-
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
-
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
-
|
|
30
|
-
### Permitted Purpose
|
|
31
|
-
|
|
32
|
-
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
-
means making the Software available to others in a commercial product or
|
|
34
|
-
service that:
|
|
35
|
-
|
|
36
|
-
1. substitutes for the Software;
|
|
37
|
-
|
|
38
|
-
2. substitutes for any other product or service we offer using the Software
|
|
39
|
-
that exists as of the date we make the Software available; or
|
|
40
|
-
|
|
41
|
-
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
-
|
|
43
|
-
Permitted Purposes specifically include using the Software:
|
|
44
|
-
|
|
45
|
-
1. for your internal use and access;
|
|
46
|
-
|
|
47
|
-
2. for non-commercial education;
|
|
48
|
-
|
|
49
|
-
3. for non-commercial research; and
|
|
50
|
-
|
|
51
|
-
4. in connection with professional services that you provide to a licensee
|
|
52
|
-
using the Software in accordance with these Terms and Conditions.
|
|
53
|
-
|
|
54
|
-
### Patents
|
|
55
|
-
|
|
56
|
-
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
-
patents, the license grant above includes a license under our patents. If you
|
|
58
|
-
make a claim against any party that the Software infringes or contributes to
|
|
59
|
-
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
-
immediately.
|
|
61
|
-
|
|
62
|
-
### Redistribution
|
|
63
|
-
|
|
64
|
-
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
-
the Software.
|
|
66
|
-
|
|
67
|
-
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
-
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
-
remove any copyright notices provided in or with the Software.
|
|
70
|
-
|
|
71
|
-
### Disclaimer
|
|
72
|
-
|
|
73
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
-
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
-
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
-
|
|
77
|
-
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
-
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
-
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
-
|
|
81
|
-
### Trademarks
|
|
82
|
-
|
|
83
|
-
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
-
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
-
trademarks, trade names, service marks or product names.
|
|
86
|
-
|
|
87
|
-
## Grant of Future License
|
|
88
|
-
|
|
89
|
-
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
-
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
-
the date we make the Software available. On or after that date, you may use the
|
|
92
|
-
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
-
will apply:
|
|
94
|
-
|
|
95
|
-
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
-
this file except in compliance with the License.
|
|
97
|
-
|
|
98
|
-
You may obtain a copy of the License at
|
|
99
|
-
|
|
100
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
-
|
|
102
|
-
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
-
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
-
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
-
specific language governing permissions and limitations under the License.
|
|
1
|
+
# Functional Source License, Version 1.1, ALv2 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-ALv2
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Mohit Soni
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
package/README.md
CHANGED
|
@@ -136,9 +136,10 @@ the detail:
|
|
|
136
136
|
- **Use the folders you already have.** Point TurboLLM at any directory of GGUFs — your
|
|
137
137
|
existing LM Studio / Ollama / manual downloads — **no re-downloading.** It parses GGUF
|
|
138
138
|
metadata (arch, params, quant, context, vision) for every file.
|
|
139
|
-
- **Browse & download from Hugging Face**, in-app:
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
- **Browse & download from Hugging Face**, in-app: a live, sortable list (trending / downloads
|
|
140
|
+
/ likes / recently updated / newest) alongside a permanent detail pane — pick a quant, read
|
|
141
|
+
the **rendered model card**, and download with **resume + SHA-256 verification**. Gated
|
|
142
|
+
models (Llama, Gemma) work via your own HF token, which **never leaves your machine**.
|
|
142
143
|
- **Import from any URL** — not just Hugging Face. Paste a direct `.gguf` link (model-author
|
|
143
144
|
sites, mirrors, private servers); it disk-space-checks and downloads through the same manager.
|
|
144
145
|
- **Quant recommendation per GPU** and a **VRAM-fit verdict** so you pick a quant that
|
|
@@ -319,7 +320,9 @@ the engine as a swappable component.
|
|
|
319
320
|
support are hidden; ones it adds (e.g. low-bit KV cache, NextN) light up.
|
|
320
321
|
|
|
321
322
|
No prebuilt for your OS? The **build-from-source guide** checks your toolchain (git / CMake /
|
|
322
|
-
CUDA / MSVC), hands you the exact build commands
|
|
323
|
+
CUDA / a compiler — MSVC on Windows, gcc/clang on Linux), hands you the exact build commands
|
|
324
|
+
(or a 1-click **"Build it for me"** on Windows and Linux), then drops you into the folder scan
|
|
325
|
+
above.
|
|
323
326
|
|
|
324
327
|
**Auto-provisioned default.** Don't want to fetch anything? On first run TurboLLM downloads
|
|
325
328
|
the right upstream prebuilt for your GPU automatically — and a **backend picker** lets you
|
package/bin/turbollm.mjs
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Hand-written launcher shim — NOT bundled by tsup. It runs before the bundled
|
|
3
|
-
// daemon (dist/cli.js) loads, so it can do two things that must happen before
|
|
4
|
-
// node:sqlite is imported (the bundle hoists that import, emitting an experimental
|
|
5
|
-
// warning that PowerShell renders as a scary red error block on every run):
|
|
6
|
-
// 1. Guard the Node version with a friendly message (node:sqlite needs Node 22+).
|
|
7
|
-
// 2. Register a 'warning' filter that swallows the node:sqlite experimental notice
|
|
8
|
-
// while still printing every other warning.
|
|
9
|
-
// Then it hands off to the real CLI via dynamic import (same process; argv intact).
|
|
10
|
-
const major = Number(process.versions.node.split('.')[0])
|
|
11
|
-
if (major < 22) {
|
|
12
|
-
process.stderr.write(
|
|
13
|
-
`TurboLLM requires Node.js 22 or newer.\n` +
|
|
14
|
-
`You are running Node.js ${process.versions.node}.\n` +
|
|
15
|
-
`Please upgrade: https://nodejs.org\n`,
|
|
16
|
-
)
|
|
17
|
-
process.exit(1)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
process.on('warning', (w) => {
|
|
21
|
-
if (w.name === 'ExperimentalWarning' && /SQLite/i.test(w.message)) return
|
|
22
|
-
process.stderr.write(`${w.stack ?? `${w.name}: ${w.message}`}\n`)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
await import('../dist/cli.js')
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Hand-written launcher shim — NOT bundled by tsup. It runs before the bundled
|
|
3
|
+
// daemon (dist/cli.js) loads, so it can do two things that must happen before
|
|
4
|
+
// node:sqlite is imported (the bundle hoists that import, emitting an experimental
|
|
5
|
+
// warning that PowerShell renders as a scary red error block on every run):
|
|
6
|
+
// 1. Guard the Node version with a friendly message (node:sqlite needs Node 22+).
|
|
7
|
+
// 2. Register a 'warning' filter that swallows the node:sqlite experimental notice
|
|
8
|
+
// while still printing every other warning.
|
|
9
|
+
// Then it hands off to the real CLI via dynamic import (same process; argv intact).
|
|
10
|
+
const major = Number(process.versions.node.split('.')[0])
|
|
11
|
+
if (major < 22) {
|
|
12
|
+
process.stderr.write(
|
|
13
|
+
`TurboLLM requires Node.js 22 or newer.\n` +
|
|
14
|
+
`You are running Node.js ${process.versions.node}.\n` +
|
|
15
|
+
`Please upgrade: https://nodejs.org\n`,
|
|
16
|
+
)
|
|
17
|
+
process.exit(1)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
process.on('warning', (w) => {
|
|
21
|
+
if (w.name === 'ExperimentalWarning' && /SQLite/i.test(w.message)) return
|
|
22
|
+
process.stderr.write(`${w.stack ?? `${w.name}: ${w.message}`}\n`)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
await import('../dist/cli.js')
|
package/dist/cli.js
CHANGED
|
@@ -1427,7 +1427,12 @@ function readinessTimeoutMs(kind) {
|
|
|
1427
1427
|
return kind === "vllm" || kind === "sglang" ? 6e5 : 12e4;
|
|
1428
1428
|
}
|
|
1429
1429
|
function pyEngineEnv(kind, dataDir, binPath) {
|
|
1430
|
-
if (kind !== "mlx" && kind !== "vllm" && kind !== "sglang")
|
|
1430
|
+
if (kind !== "mlx" && kind !== "vllm" && kind !== "sglang") {
|
|
1431
|
+
if (process.platform === "win32") return void 0;
|
|
1432
|
+
const dir = dirname2(binPath);
|
|
1433
|
+
const existing = process.env.LD_LIBRARY_PATH;
|
|
1434
|
+
return { ...process.env, LD_LIBRARY_PATH: existing ? `${dir}:${existing}` : dir };
|
|
1435
|
+
}
|
|
1431
1436
|
const hfHome = join9(dataDir, "hf-cache");
|
|
1432
1437
|
const hubCache = join9(hfHome, "hub");
|
|
1433
1438
|
mkdirSync6(hubCache, { recursive: true });
|
|
@@ -4148,6 +4153,28 @@ var HfError = class extends Error {
|
|
|
4148
4153
|
}
|
|
4149
4154
|
code;
|
|
4150
4155
|
};
|
|
4156
|
+
var SORT_PARAM = {
|
|
4157
|
+
trending: "trendingScore",
|
|
4158
|
+
downloads: "downloads",
|
|
4159
|
+
likes: "likes",
|
|
4160
|
+
modified: "lastModified",
|
|
4161
|
+
created: "createdAt"
|
|
4162
|
+
};
|
|
4163
|
+
function libraryFilterFor(engineKind) {
|
|
4164
|
+
if (engineKind === "mlx") return "filter=mlx&";
|
|
4165
|
+
if (engineKind === "vllm") return "";
|
|
4166
|
+
return "filter=gguf&";
|
|
4167
|
+
}
|
|
4168
|
+
function toSearchItem(m) {
|
|
4169
|
+
return {
|
|
4170
|
+
repo: m.id ?? m.modelId ?? "",
|
|
4171
|
+
downloads: m.downloads ?? 0,
|
|
4172
|
+
likes: m.likes ?? 0,
|
|
4173
|
+
updatedAt: m.lastModified ?? m.createdAt ?? "",
|
|
4174
|
+
gated: m.gated === true || m.gated === "auto" || m.gated === "manual",
|
|
4175
|
+
tags: Array.isArray(m.tags) ? m.tags : []
|
|
4176
|
+
};
|
|
4177
|
+
}
|
|
4151
4178
|
var SPLIT_RE2 = /^(.*)-(\d{5})-of-(\d{5})\.gguf$/i;
|
|
4152
4179
|
var HfClient = class {
|
|
4153
4180
|
constructor(tokenFn, version2) {
|
|
@@ -4157,24 +4184,26 @@ var HfClient = class {
|
|
|
4157
4184
|
tokenFn;
|
|
4158
4185
|
version;
|
|
4159
4186
|
cache = /* @__PURE__ */ new Map();
|
|
4160
|
-
/** Search repos (spec 10 §2). Returns up to 30 rows
|
|
4161
|
-
*
|
|
4162
|
-
*
|
|
4163
|
-
*
|
|
4164
|
-
|
|
4165
|
-
async searchModels(query, engineKind) {
|
|
4187
|
+
/** Search repos by text (spec 10 §2). Returns up to 30 rows. `sort` defaults to HF's own
|
|
4188
|
+
* relevance ranking ('best-match' — omits `sort=` entirely, a genuinely different order
|
|
4189
|
+
* from `sort=downloads`, not just an alias for it). Format filter adapts to the active
|
|
4190
|
+
* engine kind (never hardcoded to GGUF) — see {@link libraryFilterFor}. */
|
|
4191
|
+
async searchModels(query, engineKind, sort = "best-match") {
|
|
4166
4192
|
const q = query.trim();
|
|
4167
|
-
const
|
|
4168
|
-
const url = `${BASE}/api/models?search=${encodeURIComponent(q)}${
|
|
4193
|
+
const sortParam = sort === "best-match" ? "" : `sort=${SORT_PARAM[sort]}&direction=-1&`;
|
|
4194
|
+
const url = `${BASE}/api/models?search=${encodeURIComponent(q)}&${libraryFilterFor(engineKind)}${sortParam}limit=30&full=false`;
|
|
4169
4195
|
const raw = await this.getJson(url);
|
|
4170
|
-
return raw.map(
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4196
|
+
return raw.map(toSearchItem);
|
|
4197
|
+
}
|
|
4198
|
+
/** Browse repos with no search term (spec 10 §7 rewrite) — the live equivalent of
|
|
4199
|
+
* https://huggingface.co/models?library=gguf&sort=trending, replacing what used to be a
|
|
4200
|
+
* hardcoded "Featured" list. 'best-match' has no meaning without a query, so it falls
|
|
4201
|
+
* back to 'trending'. Format filter adapts to the active engine kind, same as search. */
|
|
4202
|
+
async browseModels(sort, engineKind, limit = 30) {
|
|
4203
|
+
const effective = sort === "best-match" ? "trending" : sort;
|
|
4204
|
+
const url = `${BASE}/api/models?${libraryFilterFor(engineKind)}sort=${SORT_PARAM[effective]}&direction=-1&limit=${limit}&full=false`;
|
|
4205
|
+
const raw = await this.getJson(url);
|
|
4206
|
+
return raw.map(toSearchItem);
|
|
4178
4207
|
}
|
|
4179
4208
|
/** Repo detail (spec 10 §3): card data + the GGUF file tree, with split parts
|
|
4180
4209
|
* grouped and quant/mmproj detected per file. */
|
|
@@ -9123,6 +9152,36 @@ var ALL = [
|
|
|
9123
9152
|
// install endpoint of its own.
|
|
9124
9153
|
installEndpoint: ""
|
|
9125
9154
|
},
|
|
9155
|
+
{
|
|
9156
|
+
// Upstream publishes NO Linux CUDA prebuilt (download.ts availableBackends() — Linux
|
|
9157
|
+
// NVIDIA users get Vulkan from the main llama.cpp entry above). Now that the guided
|
|
9158
|
+
// build (ADR-100/build-runner.ts) runs on Linux too, offer official llama.cpp + CUDA
|
|
9159
|
+
// there as its own "build from source" card — same guided-build flow as ik_llama.cpp/
|
|
9160
|
+
// TurboQuant below, just pointed at the official repo. Windows/macOS never see this
|
|
9161
|
+
// (platforms:['linux']): Windows already gets a CUDA prebuilt, and macOS has no CUDA.
|
|
9162
|
+
id: "llama.cpp-cuda-linux",
|
|
9163
|
+
name: "llama.cpp (CUDA)",
|
|
9164
|
+
kind: "llama-server",
|
|
9165
|
+
description: "Official llama.cpp compiled with CUDA for NVIDIA GPUs on Linux \u2014 no prebuilt is published upstream, so this uses the guided in-app build.",
|
|
9166
|
+
provision: "github-release",
|
|
9167
|
+
homepage: "https://github.com/ggml-org/llama.cpp",
|
|
9168
|
+
repo: "ggml-org/llama.cpp",
|
|
9169
|
+
platforms: ["linux"],
|
|
9170
|
+
support: "experimental",
|
|
9171
|
+
installEndpoint: "",
|
|
9172
|
+
note: "Builds the official repo with -DGGML_CUDA=ON and bundles its CUDA runtime libraries next to the binary, so it runs standalone. Manages like any other engine afterward (rebuild on a newer commit, disable, delete).",
|
|
9173
|
+
variants: [
|
|
9174
|
+
{
|
|
9175
|
+
id: "llama.cpp-cuda-source",
|
|
9176
|
+
label: "CUDA (NVIDIA) \u2014 build from source",
|
|
9177
|
+
repo: "ggml-org/llama.cpp",
|
|
9178
|
+
requires: { platform: ["linux"], gpuVendor: ["nvidia"] },
|
|
9179
|
+
stability: "experimental",
|
|
9180
|
+
speed: "fast",
|
|
9181
|
+
hasPrebuilt: false
|
|
9182
|
+
}
|
|
9183
|
+
]
|
|
9184
|
+
},
|
|
9126
9185
|
{
|
|
9127
9186
|
id: "vllm",
|
|
9128
9187
|
name: "vLLM",
|
|
@@ -9377,7 +9436,8 @@ var INSTALL_URLS = {
|
|
|
9377
9436
|
cmake: "https://cmake.org/download/",
|
|
9378
9437
|
cuda: "https://developer.nvidia.com/cuda-downloads",
|
|
9379
9438
|
// The "Desktop development with C++" workload from the VS Build Tools installer.
|
|
9380
|
-
msvc: "https://visualstudio.microsoft.com/downloads/"
|
|
9439
|
+
msvc: "https://visualstudio.microsoft.com/downloads/",
|
|
9440
|
+
gcc: "https://gcc.gnu.org/install/"
|
|
9381
9441
|
};
|
|
9382
9442
|
async function runVersion(cmd, args, env) {
|
|
9383
9443
|
const { stdout, stderr } = await execFileP5(cmd, args, {
|
|
@@ -9400,6 +9460,10 @@ function parseNvccVersion(out) {
|
|
|
9400
9460
|
const m = out.match(/release\s+([\d.]+)/i);
|
|
9401
9461
|
return m ? m[1] : "";
|
|
9402
9462
|
}
|
|
9463
|
+
function parseCompilerVersion(out) {
|
|
9464
|
+
const m = out.match(/(?:g\+\+|gcc|clang(?:\+\+)?)[^\d]*(\d+(?:\.\d+)*)/i);
|
|
9465
|
+
return m ? m[1] : "";
|
|
9466
|
+
}
|
|
9403
9467
|
async function checkGit(env) {
|
|
9404
9468
|
let found = false;
|
|
9405
9469
|
let version2;
|
|
@@ -9461,13 +9525,30 @@ async function checkMsvc(env) {
|
|
|
9461
9525
|
installUrl: INSTALL_URLS.msvc
|
|
9462
9526
|
};
|
|
9463
9527
|
}
|
|
9528
|
+
async function checkGcc(env) {
|
|
9529
|
+
let found = false;
|
|
9530
|
+
let version2;
|
|
9531
|
+
try {
|
|
9532
|
+
version2 = parseCompilerVersion(await runVersion("g++", ["--version"], env)) || void 0;
|
|
9533
|
+
found = true;
|
|
9534
|
+
} catch {
|
|
9535
|
+
try {
|
|
9536
|
+
version2 = parseCompilerVersion(await runVersion("clang++", ["--version"], env)) || void 0;
|
|
9537
|
+
found = true;
|
|
9538
|
+
} catch {
|
|
9539
|
+
found = false;
|
|
9540
|
+
}
|
|
9541
|
+
}
|
|
9542
|
+
return { id: "gcc", name: "C++ compiler (g++/clang++)", found, version: version2, installUrl: INSTALL_URLS.gcc };
|
|
9543
|
+
}
|
|
9464
9544
|
async function checkBuildPrereqs(toolchainDirs = []) {
|
|
9465
|
-
|
|
9466
|
-
|
|
9545
|
+
const platform = process.platform;
|
|
9546
|
+
if (platform !== "win32" && platform !== "linux") {
|
|
9547
|
+
return { supported: false, os: "other", tools: [] };
|
|
9467
9548
|
}
|
|
9468
9549
|
const env = buildEnv(toolchainDirs);
|
|
9469
|
-
const tools = await Promise.all([checkGit(env), checkCmake(env), checkCuda(env), checkMsvc(env)]);
|
|
9470
|
-
return { supported: true, tools };
|
|
9550
|
+
const tools = platform === "win32" ? await Promise.all([checkGit(env), checkCmake(env), checkCuda(env), checkMsvc(env)]) : await Promise.all([checkGit(env), checkCmake(env), checkCuda(env), checkGcc(env)]);
|
|
9551
|
+
return { supported: true, os: platform === "win32" ? "windows" : "linux", tools };
|
|
9471
9552
|
}
|
|
9472
9553
|
|
|
9473
9554
|
// src/engines/build-runner.ts
|
|
@@ -9497,8 +9578,9 @@ function sourceBuildDirOf(binPath, enginesRoot) {
|
|
|
9497
9578
|
if (!m) return null;
|
|
9498
9579
|
return join19(enginesRoot, "build", m[1]);
|
|
9499
9580
|
}
|
|
9500
|
-
function pickGenerator(hasNinja) {
|
|
9501
|
-
|
|
9581
|
+
function pickGenerator(hasNinja, isWindows) {
|
|
9582
|
+
if (hasNinja) return "Ninja";
|
|
9583
|
+
return isWindows ? "NMake Makefiles" : "Unix Makefiles";
|
|
9502
9584
|
}
|
|
9503
9585
|
var CMAKE_CONFIGURE_ARGS = ["-DGGML_CUDA=ON", "-DCMAKE_BUILD_TYPE=Release"];
|
|
9504
9586
|
function vcvarsBatch(vcvars, cmakeArgs) {
|
|
@@ -9573,6 +9655,56 @@ function copyCudaRuntimeDlls(env, destDir, log) {
|
|
|
9573
9655
|
if (copied > 0) log(`Bundled ${copied} CUDA runtime DLL(s) next to the binary so the engine is self-contained.`);
|
|
9574
9656
|
return copied;
|
|
9575
9657
|
}
|
|
9658
|
+
var CUDA_RUNTIME_SO_PREFIXES = ["libcudart.so", "libcublas.so", "libcublasLt.so", "libnvrtc.so", "libnvrtc-builtins.so", "libnvJitLink.so"];
|
|
9659
|
+
function cudaSoSourceDirs(env) {
|
|
9660
|
+
const key = Object.keys(env).find((k) => k.toLowerCase() === "path") ?? "PATH";
|
|
9661
|
+
const pathDirs = (env[key] ?? "").split(delimiter2).filter(Boolean);
|
|
9662
|
+
const nvccDir = pathDirs.find((dir) => {
|
|
9663
|
+
try {
|
|
9664
|
+
return existsSync17(join19(dir, "nvcc"));
|
|
9665
|
+
} catch {
|
|
9666
|
+
return false;
|
|
9667
|
+
}
|
|
9668
|
+
});
|
|
9669
|
+
if (!nvccDir) return [];
|
|
9670
|
+
const toolkitRoot = dirname6(nvccDir);
|
|
9671
|
+
return [join19(toolkitRoot, "lib64"), join19(toolkitRoot, "lib"), join19(toolkitRoot, "targets", "x86_64-linux", "lib")].filter((d) => {
|
|
9672
|
+
try {
|
|
9673
|
+
return existsSync17(d);
|
|
9674
|
+
} catch {
|
|
9675
|
+
return false;
|
|
9676
|
+
}
|
|
9677
|
+
});
|
|
9678
|
+
}
|
|
9679
|
+
function copyCudaRuntimeLibs(env, destDir, log) {
|
|
9680
|
+
const sources = cudaSoSourceDirs(env);
|
|
9681
|
+
if (sources.length === 0) {
|
|
9682
|
+
log("Note: could not find the CUDA toolkit shared libraries to bundle \u2014 the engine may need LD_LIBRARY_PATH set to run.");
|
|
9683
|
+
return 0;
|
|
9684
|
+
}
|
|
9685
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9686
|
+
let copied = 0;
|
|
9687
|
+
for (const dir of sources) {
|
|
9688
|
+
let names;
|
|
9689
|
+
try {
|
|
9690
|
+
names = readdirSync5(dir);
|
|
9691
|
+
} catch {
|
|
9692
|
+
continue;
|
|
9693
|
+
}
|
|
9694
|
+
for (const name of names) {
|
|
9695
|
+
if (seen.has(name)) continue;
|
|
9696
|
+
if (!CUDA_RUNTIME_SO_PREFIXES.some((p) => name.startsWith(p))) continue;
|
|
9697
|
+
try {
|
|
9698
|
+
copyFileSync(join19(dir, name), join19(destDir, name));
|
|
9699
|
+
seen.add(name);
|
|
9700
|
+
copied++;
|
|
9701
|
+
} catch {
|
|
9702
|
+
}
|
|
9703
|
+
}
|
|
9704
|
+
}
|
|
9705
|
+
if (copied > 0) log(`Bundled ${copied} CUDA runtime librar${copied === 1 ? "y" : "ies"} next to the binary so the engine is self-contained.`);
|
|
9706
|
+
return copied;
|
|
9707
|
+
}
|
|
9576
9708
|
async function findVcvarsall() {
|
|
9577
9709
|
try {
|
|
9578
9710
|
const programFilesX86 = process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)";
|
|
@@ -9691,10 +9823,11 @@ function neutralizeGratuitousAsm(srcDir, log) {
|
|
|
9691
9823
|
}
|
|
9692
9824
|
}
|
|
9693
9825
|
async function runBuild(req, hooks, signal) {
|
|
9826
|
+
const isWindows = process.platform === "win32";
|
|
9694
9827
|
const env = { ...buildEnv(req.toolchainDirs), GIT_TERMINAL_PROMPT: "0", GCM_INTERACTIVE: "never" };
|
|
9695
9828
|
hooks.phase("preparing");
|
|
9696
9829
|
const prereqs = await checkBuildPrereqs(req.toolchainDirs);
|
|
9697
|
-
if (!prereqs.supported) throw new Error("In-app build is currently Windows
|
|
9830
|
+
if (!prereqs.supported) throw new Error("In-app build is currently Windows or Linux (with CUDA) only.");
|
|
9698
9831
|
const missing = prereqs.tools.filter((t) => (t.id === "git" || t.id === "cmake" || t.id === "cuda") && !t.found);
|
|
9699
9832
|
if (missing.length > 0) {
|
|
9700
9833
|
const names = missing.map((t) => t.name).join(", ");
|
|
@@ -9702,10 +9835,17 @@ async function runBuild(req, hooks, signal) {
|
|
|
9702
9835
|
`Missing build prerequisite(s): ${names}. Install them, or \u2014 if they live in a conda env / custom path \u2014 add that folder under Build environment so TurboLLM can find them.`
|
|
9703
9836
|
);
|
|
9704
9837
|
}
|
|
9705
|
-
|
|
9706
|
-
if (
|
|
9838
|
+
let vcvars = null;
|
|
9839
|
+
if (isWindows) {
|
|
9840
|
+
vcvars = await findVcvarsall();
|
|
9841
|
+
if (!vcvars) {
|
|
9842
|
+
throw new Error(
|
|
9843
|
+
'Could not locate the Visual Studio C++ build environment (vcvarsall.bat). Install the "Desktop development with C++" workload from the Visual Studio Build Tools.'
|
|
9844
|
+
);
|
|
9845
|
+
}
|
|
9846
|
+
} else if (!prereqs.tools.some((t) => t.id === "gcc" && t.found)) {
|
|
9707
9847
|
throw new Error(
|
|
9708
|
-
|
|
9848
|
+
"Could not find a C++ compiler. Install one (e.g. `sudo apt install build-essential` on Debian/Ubuntu) and retry."
|
|
9709
9849
|
);
|
|
9710
9850
|
}
|
|
9711
9851
|
const buildRoot = join19(req.enginesRoot, "build", buildDirName(req.repoUrl, req.branch));
|
|
@@ -9721,24 +9861,35 @@ async function runBuild(req, hooks, signal) {
|
|
|
9721
9861
|
const commit = (await runStep("git", ["-C", srcDir, "rev-parse", "HEAD"], { env, signal, onLine: () => {
|
|
9722
9862
|
} })).trim();
|
|
9723
9863
|
neutralizeGratuitousAsm(srcDir, hooks.log);
|
|
9724
|
-
const generator = pickGenerator(onPath(env, "ninja.exe"));
|
|
9864
|
+
const generator = pickGenerator(onPath(env, isWindows ? "ninja.exe" : "ninja"), isWindows);
|
|
9725
9865
|
hooks.log(
|
|
9726
|
-
generator === "Ninja" ? "Using the Ninja generator (drives nvcc directly \u2014 no Visual Studio CUDA integration needed)." : "Ninja not found on PATH \u2014 using the NMake generator (works, but single-threaded and slower; add a folder containing ninja.exe under Build environment for much faster builds)."
|
|
9866
|
+
generator === "Ninja" ? "Using the Ninja generator (drives nvcc directly \u2014 no Visual Studio CUDA integration needed)." : isWindows ? "Ninja not found on PATH \u2014 using the NMake generator (works, but single-threaded and slower; add a folder containing ninja.exe under Build environment for much faster builds)." : "Ninja not found on PATH \u2014 using Unix Makefiles (works, but single-threaded and slower; add a folder containing ninja under Build environment for much faster builds)."
|
|
9727
9867
|
);
|
|
9728
9868
|
hooks.phase("configuring");
|
|
9729
|
-
const
|
|
9730
|
-
|
|
9731
|
-
|
|
9869
|
+
const configureArgs = ["-G", generator, "-B", buildSubdir, "-S", srcDir, ...CMAKE_CONFIGURE_ARGS];
|
|
9870
|
+
if (isWindows) {
|
|
9871
|
+
const configureBat = join19(buildRoot, "_tllm_configure.bat");
|
|
9872
|
+
writeFileSync8(configureBat, vcvarsBatch(vcvars, configureArgs));
|
|
9873
|
+
await runStep("cmd.exe", ["/c", configureBat], { cwd: buildRoot, env, signal, onLine: hooks.log });
|
|
9874
|
+
} else {
|
|
9875
|
+
await runStep("cmake", configureArgs, { cwd: buildRoot, env, signal, onLine: hooks.log });
|
|
9876
|
+
}
|
|
9732
9877
|
hooks.phase("compiling");
|
|
9733
|
-
const
|
|
9734
|
-
|
|
9735
|
-
|
|
9878
|
+
const compileArgs = ["--build", buildSubdir, "-j", "--target", "llama-server"];
|
|
9879
|
+
if (isWindows) {
|
|
9880
|
+
const compileBat = join19(buildRoot, "_tllm_build.bat");
|
|
9881
|
+
writeFileSync8(compileBat, vcvarsBatch(vcvars, compileArgs));
|
|
9882
|
+
await runStep("cmd.exe", ["/c", compileBat], { cwd: buildRoot, env, signal, onLine: hooks.log });
|
|
9883
|
+
} else {
|
|
9884
|
+
await runStep("cmake", compileArgs, { cwd: buildRoot, env, signal, onLine: hooks.log });
|
|
9885
|
+
}
|
|
9736
9886
|
hooks.phase("registering");
|
|
9737
9887
|
const binPath = resolveServerBinary(buildSubdir) ?? resolveServerBinary(buildRoot);
|
|
9738
9888
|
if (!binPath) {
|
|
9739
9889
|
throw new Error("Build finished but no llama-server binary was found in the output \u2014 see the log above.");
|
|
9740
9890
|
}
|
|
9741
|
-
copyCudaRuntimeDlls(env, dirname6(binPath), hooks.log);
|
|
9891
|
+
if (isWindows) copyCudaRuntimeDlls(env, dirname6(binPath), hooks.log);
|
|
9892
|
+
else copyCudaRuntimeLibs(env, dirname6(binPath), hooks.log);
|
|
9742
9893
|
return { binPath, commit, buildRoot };
|
|
9743
9894
|
}
|
|
9744
9895
|
|
|
@@ -10353,8 +10504,8 @@ function registerApi(app2, d) {
|
|
|
10353
10504
|
app2.post("/api/v1/build/run", async (c) => {
|
|
10354
10505
|
if (!isLocalRequest(c, d))
|
|
10355
10506
|
return err2(c, 403, "forbidden", "Building an engine is only available on the machine running TurboLLM.");
|
|
10356
|
-
if (process.platform !== "win32")
|
|
10357
|
-
return err2(c, 409, "unsupported_platform", "In-app build is currently Windows
|
|
10507
|
+
if (process.platform !== "win32" && process.platform !== "linux")
|
|
10508
|
+
return err2(c, 409, "unsupported_platform", "In-app build is currently Windows or Linux (with CUDA) only.");
|
|
10358
10509
|
const b = await body2(c);
|
|
10359
10510
|
const repoUrl = (b.repoUrl ?? "").trim();
|
|
10360
10511
|
if (!/^https?:\/\//i.test(repoUrl))
|
|
@@ -11270,11 +11421,13 @@ function registerApi(app2, d) {
|
|
|
11270
11421
|
});
|
|
11271
11422
|
return c.json(modelDirsPayload(d));
|
|
11272
11423
|
});
|
|
11424
|
+
const SORT_OPTIONS = ["best-match", "trending", "downloads", "likes", "modified", "created"];
|
|
11273
11425
|
app2.get("/api/v1/hf/search", async (c) => {
|
|
11274
11426
|
const q = (c.req.query("q") ?? "").trim();
|
|
11275
|
-
|
|
11427
|
+
const rawSort = c.req.query("sort") ?? "";
|
|
11428
|
+
const sort = SORT_OPTIONS.includes(rawSort) ? rawSort : "best-match";
|
|
11276
11429
|
try {
|
|
11277
|
-
const results = await d.hf.searchModels(q, d.registry.active()?.kind);
|
|
11430
|
+
const results = q ? await d.hf.searchModels(q, d.registry.active()?.kind, sort) : await d.hf.browseModels(sort, d.registry.active()?.kind);
|
|
11278
11431
|
const withLocal = results.map((r) => ({ ...r, localCount: localCountFor(d, r.repo) }));
|
|
11279
11432
|
return c.json({ results: withLocal });
|
|
11280
11433
|
} catch (e) {
|