@fugood/buttress-server 2.25.0-beta.23 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fugood/buttress-server",
3
- "version": "2.25.0-beta.23",
3
+ "version": "2.25.0-beta.31",
4
4
  "main": "lib/index.mjs",
5
5
  "types": "lib/index.d.mts",
6
6
  "type": "module",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@elysiajs/cors": "^1.1.1",
32
32
  "@elysiajs/node": "^1.4.2",
33
- "@fugood/llama.node": "^1.7.3",
33
+ "@fugood/llama.node": "^1.7.4",
34
34
  "@fugood/whisper.node": "^1.0.19",
35
35
  "@huggingface/gguf": "^0.3.2",
36
36
  "@iarna/toml": "^3.0.0",
@@ -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": "8b167250b57c5e9973e60de8266b880d15adcce6"
50
+ "gitHead": "e5a278376a30e9e6ede48391b0502882eafe00e1"
49
51
  }
@@ -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
  }