@fugood/buttress-server 2.25.0-beta.26 → 2.25.0-beta.31
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/lib/index.d.mts +117 -4
- package/lib/index.mjs +43 -43
- package/package.json +4 -2
- package/public/status.html +162 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fugood/buttress-server",
|
|
3
|
-
"version": "2.25.0-beta.
|
|
3
|
+
"version": "2.25.0-beta.31",
|
|
4
4
|
"main": "lib/index.mjs",
|
|
5
5
|
"types": "lib/index.d.mts",
|
|
6
6
|
"type": "module",
|
|
@@ -39,11 +39,13 @@
|
|
|
39
39
|
"jose": "^5.9.6",
|
|
40
40
|
"ms": "^2.1.1",
|
|
41
41
|
"node-machine-id": "^1.1.12",
|
|
42
|
+
"onnxruntime-node": "1.24.3",
|
|
43
|
+
"sharp": "^0.34.1",
|
|
42
44
|
"zod": "^3.25.76"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
45
47
|
"tsdown": "^0.20.1",
|
|
46
48
|
"typescript": "^5.9.3"
|
|
47
49
|
},
|
|
48
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "e5a278376a30e9e6ede48391b0502882eafe00e1"
|
|
49
51
|
}
|
package/public/status.html
CHANGED
|
@@ -539,6 +539,48 @@
|
|
|
539
539
|
</div>
|
|
540
540
|
</div>
|
|
541
541
|
</div>
|
|
542
|
+
|
|
543
|
+
<!-- ONNX-STT Status (hidden unless active) -->
|
|
544
|
+
<div class="card" id="onnxSttCard" style="display:none">
|
|
545
|
+
<div class="card-header">
|
|
546
|
+
<span class="card-title">ONNX-STT Status</span>
|
|
547
|
+
<span class="badge badge-info" id="onnxSttGeneratorCount">0 generators</span>
|
|
548
|
+
</div>
|
|
549
|
+
<div id="onnxSttGenerators"></div>
|
|
550
|
+
<div class="section">
|
|
551
|
+
<div class="section-title collapsible" onclick="toggleSection(this)">Model Load History</div>
|
|
552
|
+
<div class="collapsible-content" id="onnxSttModelHistory">
|
|
553
|
+
<div class="empty-state">No model load history</div>
|
|
554
|
+
</div>
|
|
555
|
+
</div>
|
|
556
|
+
<div class="section">
|
|
557
|
+
<div class="section-title collapsible" onclick="toggleSection(this)">Transcription History</div>
|
|
558
|
+
<div class="collapsible-content" id="onnxSttTranscriptionHistory">
|
|
559
|
+
<div class="empty-state">No transcription history</div>
|
|
560
|
+
</div>
|
|
561
|
+
</div>
|
|
562
|
+
</div>
|
|
563
|
+
|
|
564
|
+
<!-- ONNX-TTS Status (hidden unless active) -->
|
|
565
|
+
<div class="card" id="onnxTtsCard" style="display:none">
|
|
566
|
+
<div class="card-header">
|
|
567
|
+
<span class="card-title">ONNX-TTS Status</span>
|
|
568
|
+
<span class="badge badge-info" id="onnxTtsGeneratorCount">0 generators</span>
|
|
569
|
+
</div>
|
|
570
|
+
<div id="onnxTtsGenerators"></div>
|
|
571
|
+
<div class="section">
|
|
572
|
+
<div class="section-title collapsible" onclick="toggleSection(this)">Model Load History</div>
|
|
573
|
+
<div class="collapsible-content" id="onnxTtsModelHistory">
|
|
574
|
+
<div class="empty-state">No model load history</div>
|
|
575
|
+
</div>
|
|
576
|
+
</div>
|
|
577
|
+
<div class="section">
|
|
578
|
+
<div class="section-title collapsible" onclick="toggleSection(this)">Synthesis History</div>
|
|
579
|
+
<div class="collapsible-content" id="onnxTtsSynthesisHistory">
|
|
580
|
+
<div class="empty-state">No synthesis history</div>
|
|
581
|
+
</div>
|
|
582
|
+
</div>
|
|
583
|
+
</div>
|
|
542
584
|
</div>
|
|
543
585
|
</div>
|
|
544
586
|
|
|
@@ -844,6 +886,59 @@
|
|
|
844
886
|
})
|
|
845
887
|
}
|
|
846
888
|
|
|
889
|
+
function formatBytes(bytes) {
|
|
890
|
+
if (!bytes || bytes === 0) return '-'
|
|
891
|
+
if (bytes < 1024) return bytes + ' B'
|
|
892
|
+
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'
|
|
893
|
+
if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB'
|
|
894
|
+
return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB'
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
function renderOnnxGenerators(containerId, countId, generators, label) {
|
|
898
|
+
const container = document.getElementById(containerId)
|
|
899
|
+
document.getElementById(countId).textContent = `${generators.length} generator${generators.length !== 1 ? 's' : ''}`
|
|
900
|
+
|
|
901
|
+
withScrollPreserve(container, () => {
|
|
902
|
+
if (generators.length === 0) {
|
|
903
|
+
container.innerHTML = `<div class="empty-state">No ${label} generators loaded</div>`
|
|
904
|
+
return
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
container.innerHTML = `
|
|
908
|
+
<div class="table-wrapper">
|
|
909
|
+
<div class="table-inner">
|
|
910
|
+
<table>
|
|
911
|
+
<thead>
|
|
912
|
+
<tr>
|
|
913
|
+
<th>ID</th>
|
|
914
|
+
<th>Model</th>
|
|
915
|
+
<th>DType</th>
|
|
916
|
+
<th>Provider</th>
|
|
917
|
+
<th>Device</th>
|
|
918
|
+
<th>Model Size</th>
|
|
919
|
+
<th>Pipelines</th>
|
|
920
|
+
</tr>
|
|
921
|
+
</thead>
|
|
922
|
+
<tbody>
|
|
923
|
+
${generators.map(g => `
|
|
924
|
+
<tr>
|
|
925
|
+
<td class="mono">${escapeHtml(g.id?.slice(0, 8) || '-')}</td>
|
|
926
|
+
<td>${formatModelName(g.repoId)}${g.vocoderRepoId ? '<br><span style="font-size:11px;color:var(--text-muted)">+ ' + formatModelName(g.vocoderRepoId) + '</span>' : ''}</td>
|
|
927
|
+
<td>${escapeHtml(typeof g.dtype === 'object' ? JSON.stringify(g.dtype) : g.dtype || '-')}</td>
|
|
928
|
+
<td><span class="badge ${g.provider === 'cpu' ? 'badge-info' : 'badge-success'}">${escapeHtml(g.provider || '-')}</span></td>
|
|
929
|
+
<td>${escapeHtml(g.device || '-')}</td>
|
|
930
|
+
<td>${formatBytes(g.modelBytes)}</td>
|
|
931
|
+
<td>${g.pipelines ?? 0}</td>
|
|
932
|
+
</tr>
|
|
933
|
+
`).join('')}
|
|
934
|
+
</tbody>
|
|
935
|
+
</table>
|
|
936
|
+
</div>
|
|
937
|
+
</div>
|
|
938
|
+
`
|
|
939
|
+
})
|
|
940
|
+
}
|
|
941
|
+
|
|
847
942
|
// Escape HTML
|
|
848
943
|
function escapeHtml(str) {
|
|
849
944
|
if (str == null) return ''
|
|
@@ -869,6 +964,8 @@
|
|
|
869
964
|
const llm = status.ggmlLlm || {}
|
|
870
965
|
const stt = status.ggmlStt || {}
|
|
871
966
|
const mlx = status.mlxLlm || {}
|
|
967
|
+
const onnxStt = status.onnxStt || {}
|
|
968
|
+
const onnxTts = status.onnxTts || {}
|
|
872
969
|
|
|
873
970
|
// LLM
|
|
874
971
|
renderLlmGenerators(llm.generators || [])
|
|
@@ -983,6 +1080,70 @@
|
|
|
983
1080
|
}
|
|
984
1081
|
},
|
|
985
1082
|
])
|
|
1083
|
+
|
|
1084
|
+
// ONNX-STT
|
|
1085
|
+
const hasOnnxStt = (onnxStt.generators?.length > 0) ||
|
|
1086
|
+
(onnxStt.history?.modelLoads?.length > 0) ||
|
|
1087
|
+
(onnxStt.history?.transcriptions?.length > 0)
|
|
1088
|
+
document.getElementById('onnxSttCard').style.display = hasOnnxStt ? '' : 'none'
|
|
1089
|
+
renderOnnxGenerators('onnxSttGenerators', 'onnxSttGeneratorCount', onnxStt.generators || [], 'ONNX STT')
|
|
1090
|
+
|
|
1091
|
+
renderHistory('onnxSttModelHistory', onnxStt.history?.modelLoads || [], [
|
|
1092
|
+
{ label: 'Time', render: i => `<span class="timestamp">${formatRelativeTime(i.timestamp)}</span>` },
|
|
1093
|
+
{ label: 'Model', render: i => formatModelName(i.repoId) },
|
|
1094
|
+
{ label: 'DType', render: i => escapeHtml(typeof i.dtype === 'object' ? JSON.stringify(i.dtype) : i.dtype || '-') },
|
|
1095
|
+
{ label: 'Provider', render: i => `<span class="badge ${i.provider === 'cpu' ? 'badge-info' : 'badge-success'}">${escapeHtml(i.provider || '-')}</span>` },
|
|
1096
|
+
{ label: 'Duration', render: i => `${(i.durationMs / 1000).toFixed(1)}s` },
|
|
1097
|
+
{ label: 'Status', render: i => i.success ?
|
|
1098
|
+
'<span class="badge badge-success">Success</span>' :
|
|
1099
|
+
`<span class="badge badge-error">Failed: ${escapeHtml(i.error || 'Unknown')}</span>`
|
|
1100
|
+
},
|
|
1101
|
+
])
|
|
1102
|
+
|
|
1103
|
+
renderHistory('onnxSttTranscriptionHistory', onnxStt.history?.transcriptions || [], [
|
|
1104
|
+
{ label: 'Time', render: i => `<span class="timestamp">${formatRelativeTime(i.timestamp)}</span>` },
|
|
1105
|
+
{ label: 'Model', render: i => formatModelName(i.repoId) },
|
|
1106
|
+
{ label: 'Provider', render: i => escapeHtml(i.provider || '-') },
|
|
1107
|
+
{ label: 'Segments', render: i => i.segmentCount ?? '-' },
|
|
1108
|
+
{ label: 'Text Len', render: i => i.textLength ?? '-' },
|
|
1109
|
+
{ label: 'Duration', render: i => `${(i.durationMs / 1000).toFixed(1)}s` },
|
|
1110
|
+
{ label: 'Status', render: i => i.success ?
|
|
1111
|
+
'<span class="badge badge-success">Success</span>' :
|
|
1112
|
+
`<span class="badge badge-error">Failed</span>`
|
|
1113
|
+
},
|
|
1114
|
+
])
|
|
1115
|
+
|
|
1116
|
+
// ONNX-TTS
|
|
1117
|
+
const hasOnnxTts = (onnxTts.generators?.length > 0) ||
|
|
1118
|
+
(onnxTts.history?.modelLoads?.length > 0) ||
|
|
1119
|
+
(onnxTts.history?.syntheses?.length > 0)
|
|
1120
|
+
document.getElementById('onnxTtsCard').style.display = hasOnnxTts ? '' : 'none'
|
|
1121
|
+
renderOnnxGenerators('onnxTtsGenerators', 'onnxTtsGeneratorCount', onnxTts.generators || [], 'ONNX TTS')
|
|
1122
|
+
|
|
1123
|
+
renderHistory('onnxTtsModelHistory', onnxTts.history?.modelLoads || [], [
|
|
1124
|
+
{ label: 'Time', render: i => `<span class="timestamp">${formatRelativeTime(i.timestamp)}</span>` },
|
|
1125
|
+
{ label: 'Model', render: i => formatModelName(i.repoId) },
|
|
1126
|
+
{ label: 'DType', render: i => escapeHtml(typeof i.dtype === 'object' ? JSON.stringify(i.dtype) : i.dtype || '-') },
|
|
1127
|
+
{ label: 'Provider', render: i => `<span class="badge ${i.provider === 'cpu' ? 'badge-info' : 'badge-success'}">${escapeHtml(i.provider || '-')}</span>` },
|
|
1128
|
+
{ label: 'Vocoder', render: i => i.vocoderRepoId ? formatModelName(i.vocoderRepoId) : '-' },
|
|
1129
|
+
{ label: 'Duration', render: i => `${(i.durationMs / 1000).toFixed(1)}s` },
|
|
1130
|
+
{ label: 'Status', render: i => i.success ?
|
|
1131
|
+
'<span class="badge badge-success">Success</span>' :
|
|
1132
|
+
`<span class="badge badge-error">Failed: ${escapeHtml(i.error || 'Unknown')}</span>`
|
|
1133
|
+
},
|
|
1134
|
+
])
|
|
1135
|
+
|
|
1136
|
+
renderHistory('onnxTtsSynthesisHistory', onnxTts.history?.syntheses || [], [
|
|
1137
|
+
{ label: 'Time', render: i => `<span class="timestamp">${formatRelativeTime(i.timestamp)}</span>` },
|
|
1138
|
+
{ label: 'Model', render: i => formatModelName(i.repoId) },
|
|
1139
|
+
{ label: 'Provider', render: i => escapeHtml(i.provider || '-') },
|
|
1140
|
+
{ label: 'Text Len', render: i => i.textLength ?? '-' },
|
|
1141
|
+
{ label: 'Duration', render: i => i.cached ? '<span class="badge badge-info">Cached</span>' : `${(i.durationMs / 1000).toFixed(1)}s` },
|
|
1142
|
+
{ label: 'Status', render: i => i.success ?
|
|
1143
|
+
'<span class="badge badge-success">Success</span>' :
|
|
1144
|
+
`<span class="badge badge-error">Failed</span>`
|
|
1145
|
+
},
|
|
1146
|
+
])
|
|
986
1147
|
}
|
|
987
1148
|
|
|
988
1149
|
// Fallback: Fetch status via HTTP polling
|
|
@@ -994,7 +1155,7 @@
|
|
|
994
1155
|
const response = await fetch('/buttress/status')
|
|
995
1156
|
const data = await response.json()
|
|
996
1157
|
// Direct JSON response (not tRPC wrapped)
|
|
997
|
-
if (data.ggmlLlm || data.ggmlStt || data.mlxLlm) {
|
|
1158
|
+
if (data.ggmlLlm || data.ggmlStt || data.mlxLlm || data.onnxStt || data.onnxTts) {
|
|
998
1159
|
updateUI(data)
|
|
999
1160
|
setConnectionStatus('connected')
|
|
1000
1161
|
}
|