@happyvertical/smrt-svelte 0.30.0 → 0.31.1
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/AGENTS.md +4 -1
- package/dist/Provider.svelte +12 -2
- package/dist/Provider.svelte.d.ts.map +1 -1
- package/dist/components/admin/AgentSettingsShell.svelte +72 -4
- package/dist/components/admin/AgentSettingsShell.svelte.d.ts.map +1 -1
- package/dist/components/admin/__tests__/AgentSettingsShell.tablist.test.js +93 -0
- package/dist/components/forms/DateRangeInput.svelte +29 -5
- package/dist/components/forms/DateRangeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/DateTimeInput.svelte +34 -7
- package/dist/components/forms/DateTimeInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/FileUpload.svelte +3 -1
- package/dist/components/forms/FileUpload.svelte.d.ts.map +1 -1
- package/dist/components/forms/Form.svelte +72 -36
- package/dist/components/forms/Form.svelte.d.ts.map +1 -1
- package/dist/components/forms/FormMicButton.svelte +14 -11
- package/dist/components/forms/FormMicButton.svelte.d.ts.map +1 -1
- package/dist/components/forms/PhoneInput.svelte +29 -5
- package/dist/components/forms/PhoneInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextInput.svelte +35 -7
- package/dist/components/forms/TextInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/TextareaInput.svelte +29 -5
- package/dist/components/forms/TextareaInput.svelte.d.ts.map +1 -1
- package/dist/components/forms/__tests__/FileUpload.error-alert.test.js +37 -0
- package/dist/components/forms/__tests__/Form.stt-error.test.js +57 -0
- package/dist/components/forms/__tests__/FormMicButton.test.js +7 -0
- package/dist/components/forms/__tests__/mic-keyboard-a11y.test.js +74 -0
- package/dist/hooks/__tests__/stt-consumer.fixture.svelte +25 -0
- package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts +15 -0
- package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts.map +1 -0
- package/dist/hooks/__tests__/stt-ownership-harness.svelte +42 -0
- package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts +20 -0
- package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts.map +1 -0
- package/dist/hooks/__tests__/useSTT-ownership.test.js +102 -0
- package/dist/hooks/useSTT.svelte.d.ts.map +1 -1
- package/dist/hooks/useSTT.svelte.js +20 -6
- package/dist/hooks/useTTS.svelte.d.ts.map +1 -1
- package/dist/hooks/useTTS.svelte.js +20 -6
- package/dist/i18n/server.d.ts +5 -5
- package/dist/i18n/server.js +5 -5
- package/dist/internal/logger.d.ts +13 -0
- package/dist/internal/logger.d.ts.map +1 -0
- package/dist/internal/logger.js +12 -0
- package/dist/state/__tests__/app-state-ai-lifecycle.test.js +240 -0
- package/dist/state/app-state.svelte.d.ts +40 -8
- package/dist/state/app-state.svelte.d.ts.map +1 -1
- package/dist/state/app-state.svelte.js +224 -54
- package/package.json +6 -5
|
@@ -7,6 +7,34 @@
|
|
|
7
7
|
import { canEnableSmrtMode, detectCapabilities, getLLM, getSTT, getTTS, } from '../browser-ai/index.js';
|
|
8
8
|
import { createInitialState, } from './app-state.js';
|
|
9
9
|
import { getCachedLLM, getCachedSTT, getCachedTTS, setCachedLLM, setCachedSTT, setCachedTTS, updateLLMCacheState, updateSTTCacheState, updateTTSCacheState, } from './warm-clients.js';
|
|
10
|
+
/**
|
|
11
|
+
* Module-scope record of the single active listener teardown for each warm
|
|
12
|
+
* adapter. Warm adapters live in the module-level cache and survive Provider
|
|
13
|
+
* remounts, so their event-listener `Set`s would otherwise accumulate one
|
|
14
|
+
* closure set per manager that ever subscribed (R1 leak). Keying the teardown
|
|
15
|
+
* by **adapter identity at module scope** (not a per-manager `WeakSet`)
|
|
16
|
+
* guarantees at most one live subscription per shared adapter: before a new
|
|
17
|
+
* manager subscribes, the previous owner's listeners are removed.
|
|
18
|
+
*/
|
|
19
|
+
const sttAdapterTeardowns = new WeakMap();
|
|
20
|
+
const ttsAdapterTeardowns = new WeakMap();
|
|
21
|
+
/**
|
|
22
|
+
* Structural equality for two AI configs (R3). Used to no-op `setAIConfig` when
|
|
23
|
+
* an inline `ai={{…}}` literal re-renders with the same effective settings but a
|
|
24
|
+
* new object identity. A shallow JSON compare is sufficient: AIConfig is a flat
|
|
25
|
+
* tree of plain primitives/objects with no functions or class instances.
|
|
26
|
+
*/
|
|
27
|
+
function configsEqual(a, b) {
|
|
28
|
+
if (a === b)
|
|
29
|
+
return true;
|
|
30
|
+
try {
|
|
31
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Non-serializable (shouldn't happen for AIConfig) — treat as different.
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
10
38
|
/**
|
|
11
39
|
* Reactive app state manager for Svelte 5
|
|
12
40
|
*/
|
|
@@ -19,13 +47,23 @@ export class SmrtAppStateManager {
|
|
|
19
47
|
_aiConfig = null;
|
|
20
48
|
_preloadScheduled = false;
|
|
21
49
|
_idleCallbackId = null;
|
|
50
|
+
// Guards a single executePreload() pass from running concurrently. The
|
|
51
|
+
// Provider's `ai` $effect can re-fire setAIConfig on every parent render
|
|
52
|
+
// (inline `ai={{…}}` literal => new identity), and an `idle`/`eager` strategy
|
|
53
|
+
// would otherwise launch overlapping preloads that interleave aiLoading
|
|
54
|
+
// writes and double-download models (R3).
|
|
55
|
+
_preloadInFlight = false;
|
|
22
56
|
// Socket management
|
|
23
57
|
_socket = null;
|
|
24
58
|
_socketConfig = null;
|
|
25
59
|
_reconnectTimeout = null;
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
60
|
+
// Adapters this manager currently owns a subscription on, mapped to the
|
|
61
|
+
// teardown that removes its listeners. Used both for dedup (skip re-subscribe
|
|
62
|
+
// when this manager already owns the adapter) and to unsubscribe on dispose()
|
|
63
|
+
// so a destroyed Provider stops pinning its `_state` proxy via the adapter's
|
|
64
|
+
// module-surviving listener `Set`s (R1).
|
|
65
|
+
_sttSubscriptions = new Map();
|
|
66
|
+
_ttsSubscriptions = new Map();
|
|
29
67
|
constructor(options = {}) {
|
|
30
68
|
this.options = options;
|
|
31
69
|
this._aiConfig = options.ai ?? null;
|
|
@@ -98,9 +136,22 @@ export class SmrtAppStateManager {
|
|
|
98
136
|
}
|
|
99
137
|
// === AI Preloading Methods ===
|
|
100
138
|
/**
|
|
101
|
-
* Set or update AI configuration
|
|
139
|
+
* Set or update AI configuration.
|
|
140
|
+
*
|
|
141
|
+
* No-ops when the incoming config is deep-equal to the current one. The
|
|
142
|
+
* Provider's `ai` $effect depends on the prop's identity, and the documented
|
|
143
|
+
* usage passes an inline `ai={{…}}` object literal — a fresh identity on every
|
|
144
|
+
* parent render. Without this guard each render would cancel the idle
|
|
145
|
+
* callback, reset `_preloadScheduled`, and re-schedule (and, for `eager`,
|
|
146
|
+
* re-launch a full preload), thrashing the scheduler and double-downloading
|
|
147
|
+
* models (R3).
|
|
102
148
|
*/
|
|
103
149
|
setAIConfig(config) {
|
|
150
|
+
if (this._aiConfig && configsEqual(this._aiConfig, config)) {
|
|
151
|
+
// Same effective config (different object identity) — nothing to do.
|
|
152
|
+
this._aiConfig = config;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
104
155
|
this._aiConfig = config;
|
|
105
156
|
// Cancel any pending preload scheduling so we can re-schedule with new config
|
|
106
157
|
if (this._idleCallbackId !== null &&
|
|
@@ -154,9 +205,30 @@ export class SmrtAppStateManager {
|
|
|
154
205
|
this.executePreload();
|
|
155
206
|
}
|
|
156
207
|
/**
|
|
157
|
-
* Execute the preloading of configured adapters
|
|
208
|
+
* Execute the preloading of configured adapters.
|
|
209
|
+
*
|
|
210
|
+
* Re-entrancy guarded: an `idle`/`eager` strategy can be re-scheduled while a
|
|
211
|
+
* pass is still awaiting model downloads. Without the guard the overlapping
|
|
212
|
+
* passes interleave their aiLoading writes and double-download models (R3).
|
|
158
213
|
*/
|
|
159
214
|
async executePreload() {
|
|
215
|
+
if (!this._aiConfig)
|
|
216
|
+
return;
|
|
217
|
+
if (this._preloadInFlight)
|
|
218
|
+
return;
|
|
219
|
+
this._preloadInFlight = true;
|
|
220
|
+
try {
|
|
221
|
+
await this.runPreload();
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
this._preloadInFlight = false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The actual preload pass. Always invoked behind the `_preloadInFlight` guard
|
|
229
|
+
* in {@link executePreload}.
|
|
230
|
+
*/
|
|
231
|
+
async runPreload() {
|
|
160
232
|
if (!this._aiConfig)
|
|
161
233
|
return;
|
|
162
234
|
const adaptersToLoad = [];
|
|
@@ -174,7 +246,10 @@ export class SmrtAppStateManager {
|
|
|
174
246
|
adaptersToLoad.push(`llm:${modelKey}`);
|
|
175
247
|
}
|
|
176
248
|
if (adaptersToLoad.length === 0) {
|
|
177
|
-
|
|
249
|
+
// Reset loaded/failed too (R7) — the main path clears them via the
|
|
250
|
+
// 'checking' update below, so the early-return must not leave stale
|
|
251
|
+
// entries from a prior pass behind.
|
|
252
|
+
this.updateLoadingState({ phase: 'idle', loaded: [], failed: [] });
|
|
178
253
|
return;
|
|
179
254
|
}
|
|
180
255
|
this.updateLoadingState({
|
|
@@ -482,41 +557,61 @@ export class SmrtAppStateManager {
|
|
|
482
557
|
}
|
|
483
558
|
}
|
|
484
559
|
/**
|
|
485
|
-
* Subscribe to STT adapter events
|
|
486
|
-
*
|
|
560
|
+
* Subscribe to STT adapter events.
|
|
561
|
+
*
|
|
562
|
+
* Captures every unsubscribe handle the adapter returns and stores a single
|
|
563
|
+
* teardown both per-manager (called on dispose()) and at module scope keyed
|
|
564
|
+
* by adapter identity. Because warm adapters are shared singletons, any
|
|
565
|
+
* previous owner's listeners are torn down first — guaranteeing exactly one
|
|
566
|
+
* live listener set per adapter, with the latest manager owning it (R1).
|
|
487
567
|
*/
|
|
488
568
|
subscribeToSTTEvents(adapter) {
|
|
489
|
-
//
|
|
490
|
-
if (this.
|
|
569
|
+
// Dedup: this manager already owns the adapter's subscription.
|
|
570
|
+
if (this._sttSubscriptions.has(adapter)) {
|
|
491
571
|
return;
|
|
492
572
|
}
|
|
493
|
-
|
|
494
|
-
adapter
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
if (
|
|
499
|
-
|
|
573
|
+
// Evict any prior owner (e.g. a destroyed Provider that failed to dispose)
|
|
574
|
+
// so the adapter never fires more than one manager's listeners.
|
|
575
|
+
sttAdapterTeardowns.get(adapter)?.();
|
|
576
|
+
const unsubs = [
|
|
577
|
+
adapter.onResult((result) => {
|
|
578
|
+
if (result.isFinal) {
|
|
579
|
+
// Accumulate final results (continuous mode emits multiple phrases)
|
|
580
|
+
const existing = this._state.ai.stt.lastResult;
|
|
581
|
+
if (existing) {
|
|
582
|
+
this._state.ai.stt.lastResult = `${existing} ${result.text}`;
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
this._state.ai.stt.lastResult = result.text;
|
|
586
|
+
}
|
|
587
|
+
this._state.ai.stt.interimResult = '';
|
|
500
588
|
}
|
|
501
589
|
else {
|
|
502
|
-
|
|
590
|
+
// Interim result - update live
|
|
591
|
+
this._state.ai.stt.interimResult = result.text;
|
|
503
592
|
}
|
|
504
|
-
|
|
593
|
+
}),
|
|
594
|
+
adapter.onStart(() => {
|
|
595
|
+
this._state.ai.stt.isListening = true;
|
|
596
|
+
}),
|
|
597
|
+
adapter.onEnd(() => {
|
|
598
|
+
this._state.ai.stt.isListening = false;
|
|
599
|
+
}),
|
|
600
|
+
adapter.onError((error) => {
|
|
601
|
+
this._state.ai.stt.error = error;
|
|
602
|
+
}),
|
|
603
|
+
];
|
|
604
|
+
const teardown = () => {
|
|
605
|
+
for (const unsub of unsubs) {
|
|
606
|
+
unsub();
|
|
505
607
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
608
|
+
this._sttSubscriptions.delete(adapter);
|
|
609
|
+
if (sttAdapterTeardowns.get(adapter) === teardown) {
|
|
610
|
+
sttAdapterTeardowns.delete(adapter);
|
|
509
611
|
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
});
|
|
514
|
-
adapter.onEnd(() => {
|
|
515
|
-
this._state.ai.stt.isListening = false;
|
|
516
|
-
});
|
|
517
|
-
adapter.onError((error) => {
|
|
518
|
-
this._state.ai.stt.error = error;
|
|
519
|
-
});
|
|
612
|
+
};
|
|
613
|
+
this._sttSubscriptions.set(adapter, teardown);
|
|
614
|
+
sttAdapterTeardowns.set(adapter, teardown);
|
|
520
615
|
}
|
|
521
616
|
/**
|
|
522
617
|
* Start STT listening
|
|
@@ -585,27 +680,44 @@ export class SmrtAppStateManager {
|
|
|
585
680
|
}
|
|
586
681
|
}
|
|
587
682
|
/**
|
|
588
|
-
* Subscribe to TTS adapter events
|
|
589
|
-
*
|
|
683
|
+
* Subscribe to TTS adapter events.
|
|
684
|
+
*
|
|
685
|
+
* Mirrors {@link subscribeToSTTEvents}: captures unsubscribe handles, dedups
|
|
686
|
+
* per-manager, and evicts any prior owner so a shared warm adapter never
|
|
687
|
+
* pins more than one manager's `_state` proxy (R1).
|
|
590
688
|
*/
|
|
591
689
|
subscribeToTTSEvents(adapter) {
|
|
592
|
-
//
|
|
593
|
-
if (this.
|
|
690
|
+
// Dedup: this manager already owns the adapter's subscription.
|
|
691
|
+
if (this._ttsSubscriptions.has(adapter)) {
|
|
594
692
|
return;
|
|
595
693
|
}
|
|
596
|
-
this.
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
694
|
+
// Evict any prior owner so the adapter fires only this manager's listeners.
|
|
695
|
+
ttsAdapterTeardowns.get(adapter)?.();
|
|
696
|
+
const unsubs = [
|
|
697
|
+
adapter.onStart(() => {
|
|
698
|
+
this._state.ai.tts.isSpeaking = true;
|
|
699
|
+
this._state.ai.tts.isPaused = false;
|
|
700
|
+
}),
|
|
701
|
+
adapter.onEnd(() => {
|
|
702
|
+
this._state.ai.tts.isSpeaking = false;
|
|
703
|
+
this._state.ai.tts.isPaused = false;
|
|
704
|
+
}),
|
|
705
|
+
adapter.onError((error) => {
|
|
706
|
+
this._state.ai.tts.error = error;
|
|
707
|
+
this._state.ai.tts.isSpeaking = false;
|
|
708
|
+
}),
|
|
709
|
+
];
|
|
710
|
+
const teardown = () => {
|
|
711
|
+
for (const unsub of unsubs) {
|
|
712
|
+
unsub();
|
|
713
|
+
}
|
|
714
|
+
this._ttsSubscriptions.delete(adapter);
|
|
715
|
+
if (ttsAdapterTeardowns.get(adapter) === teardown) {
|
|
716
|
+
ttsAdapterTeardowns.delete(adapter);
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
this._ttsSubscriptions.set(adapter, teardown);
|
|
720
|
+
ttsAdapterTeardowns.set(adapter, teardown);
|
|
609
721
|
}
|
|
610
722
|
/**
|
|
611
723
|
* Speak text using TTS
|
|
@@ -726,12 +838,44 @@ export class SmrtAppStateManager {
|
|
|
726
838
|
* Unload LLM model to free memory
|
|
727
839
|
*/
|
|
728
840
|
async unloadLLM() {
|
|
729
|
-
|
|
841
|
+
const adapter = this._state.ai.llm.adapter;
|
|
842
|
+
// Capture the model id BEFORE unloadModel(): a real WebLLM adapter clears
|
|
843
|
+
// `currentModel` on unload, so reading it afterward would key the cache
|
|
844
|
+
// downgrade off `undefined` and leave the actual `'ready'` entry stale (R2).
|
|
845
|
+
const unloadedModel = adapter?.currentModel ?? undefined;
|
|
846
|
+
await adapter?.unloadModel();
|
|
847
|
+
// Downgrade (or remove) the warm-cache entry for the unloaded model so a
|
|
848
|
+
// later initializeLLM() re-runs ensureInitialized() — re-downloading and
|
|
849
|
+
// reporting progress — instead of cache-hitting a `'ready'` entry whose
|
|
850
|
+
// model is now gone (R2). `unloadModel()` keeps the adapter instance
|
|
851
|
+
// reusable, so downgrade to `'uninitialized'` rather than dispose it.
|
|
852
|
+
if (adapter) {
|
|
853
|
+
updateLLMCacheState(adapter.type, unloadedModel, {
|
|
854
|
+
initState: 'uninitialized',
|
|
855
|
+
downloadProgress: null,
|
|
856
|
+
error: null,
|
|
857
|
+
});
|
|
858
|
+
}
|
|
730
859
|
this._state.ai.llm.adapter = null;
|
|
731
860
|
this._state.ai.llm.initState = 'uninitialized';
|
|
732
861
|
this._state.ai.llm.currentModel = null;
|
|
733
862
|
}
|
|
734
863
|
// === Cleanup ===
|
|
864
|
+
/**
|
|
865
|
+
* Unsubscribe every adapter-event listener this manager owns (R1). Called on
|
|
866
|
+
* dispose() so a destroyed Provider stops being pinned by the shared warm
|
|
867
|
+
* adapters' module-surviving listener `Set`s.
|
|
868
|
+
*/
|
|
869
|
+
unsubscribeAllAdapterEvents() {
|
|
870
|
+
for (const teardown of [...this._sttSubscriptions.values()]) {
|
|
871
|
+
teardown();
|
|
872
|
+
}
|
|
873
|
+
for (const teardown of [...this._ttsSubscriptions.values()]) {
|
|
874
|
+
teardown();
|
|
875
|
+
}
|
|
876
|
+
this._sttSubscriptions.clear();
|
|
877
|
+
this._ttsSubscriptions.clear();
|
|
878
|
+
}
|
|
735
879
|
/**
|
|
736
880
|
* Dispose of all resources
|
|
737
881
|
*/
|
|
@@ -742,12 +886,38 @@ export class SmrtAppStateManager {
|
|
|
742
886
|
cancelIdleCallback(this._idleCallbackId);
|
|
743
887
|
this._idleCallbackId = null;
|
|
744
888
|
}
|
|
889
|
+
// Stop any in-flight preload so it can't write to a torn-down state (R3).
|
|
890
|
+
this._preloadInFlight = false;
|
|
745
891
|
// Disconnect socket
|
|
746
892
|
this.disconnectSocket();
|
|
747
|
-
//
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
893
|
+
// Remove this manager's adapter-event listeners (R1).
|
|
894
|
+
this.unsubscribeAllAdapterEvents();
|
|
895
|
+
// Adapter lifecycle is owned by the warm cache (it survives navigation by
|
|
896
|
+
// design). For adapters this manager holds that the cache no longer tracks
|
|
897
|
+
// — e.g. an instance orphaned by a mid-session type switch — dispose them
|
|
898
|
+
// directly so they don't leak. Adapters still backed by a warm-cache entry
|
|
899
|
+
// are left intact and genuinely `'ready'`; previously they were disposed
|
|
900
|
+
// here yet left cached as `'ready'`, so the next init cache-hit restored a
|
|
901
|
+
// dead engine with no download progress (R2). Full teardown remains
|
|
902
|
+
// available via `clearAllCaches()`.
|
|
903
|
+
//
|
|
904
|
+
// NOTE: state adapters are `$state` proxies, so identity (`!==`) comparison
|
|
905
|
+
// against the raw cached instance is unreliable (Svelte proxy-equality
|
|
906
|
+
// gotcha). Gate on whether the cache *has* a live entry for the adapter's
|
|
907
|
+
// type/model instead of comparing instances.
|
|
908
|
+
const sttAdapter = this._state.ai.stt.adapter;
|
|
909
|
+
if (sttAdapter && !getCachedSTT(sttAdapter.type)) {
|
|
910
|
+
await sttAdapter.dispose?.();
|
|
911
|
+
}
|
|
912
|
+
const ttsAdapter = this._state.ai.tts.adapter;
|
|
913
|
+
if (ttsAdapter && !getCachedTTS(ttsAdapter.type)) {
|
|
914
|
+
await ttsAdapter.dispose?.();
|
|
915
|
+
}
|
|
916
|
+
const llmAdapter = this._state.ai.llm.adapter;
|
|
917
|
+
if (llmAdapter &&
|
|
918
|
+
!getCachedLLM(llmAdapter.type, llmAdapter.currentModel ?? undefined)) {
|
|
919
|
+
await llmAdapter.dispose?.();
|
|
920
|
+
}
|
|
751
921
|
this._state = createInitialState();
|
|
752
922
|
}
|
|
753
923
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"description": "Svelte 5 components for SMRT user management - auth, users, tenants, roles, permissions, groups",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -81,11 +81,12 @@
|
|
|
81
81
|
"access": "public"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
+
"@happyvertical/logger": "^0.74.7",
|
|
84
85
|
"esm-env": "^1.2.2",
|
|
85
|
-
"@happyvertical/smrt-
|
|
86
|
-
"@happyvertical/smrt-types": "0.
|
|
87
|
-
"@happyvertical/smrt-
|
|
88
|
-
"@happyvertical/smrt-
|
|
86
|
+
"@happyvertical/smrt-agents": "0.31.1",
|
|
87
|
+
"@happyvertical/smrt-types": "0.31.1",
|
|
88
|
+
"@happyvertical/smrt-languages": "0.31.1",
|
|
89
|
+
"@happyvertical/smrt-ui": "0.31.1"
|
|
89
90
|
},
|
|
90
91
|
"peerDependencies": {
|
|
91
92
|
"@huggingface/transformers": ">=3.0.0",
|