arcane-os 0.3.3 → 0.3.5
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/CHANGELOG.md +22 -0
- package/README.md +7 -7
- package/browser-runtime/ai/browser-wasm-llm-provider.mjs +315 -119
- package/browser-runtime/ai/model-controller.mjs +439 -95
- package/package.json +1 -1
- package/runtime/arcane/components/assistant-panel.html +2 -1
- package/runtime/arcane/components/chat.html +466 -206
- package/runtime/arcane/components/speech.html +107 -30
- package/runtime/arcane/components/voice-transcription.html +27 -3
- package/runtime/arcane/entities/Chat.js +165 -97
- package/runtime/arcane/entities/IntentEnvelope.js +52 -118
- package/runtime/arcane/entities/TWiNPolicyDecision.js +33 -130
- package/runtime/arcane/entities/User.js +38 -44
- package/runtime/arcane/modules/AI.js +569 -302
- package/runtime/arcane/modules/AIProviderRuntime.js +765 -135
- package/runtime/arcane/modules/AIRuntimeState.js +22 -24
- package/runtime/arcane/modules/ApiModelDatabase.js +54 -48
- package/runtime/arcane/modules/CaseEvidenceIndexer.js +6 -10
- package/runtime/arcane/modules/CommunicationHub.js +90 -94
- package/runtime/arcane/modules/ComponentContracts.js +34 -9
- package/runtime/arcane/modules/ConfiguredAIChatSession.js +77 -77
- package/runtime/arcane/modules/ConversationTimebox.js +76 -104
- package/runtime/arcane/modules/DBLS.js +14 -12
- package/runtime/arcane/modules/DBOPFS.js +20 -15
- package/runtime/arcane/modules/Errors.js +196 -436
- package/runtime/arcane/modules/HTMLImport.js +49 -32
- package/runtime/arcane/modules/Ollama.js +16 -14
- package/runtime/arcane/modules/PersistentAIChatSession.js +174 -93
- package/runtime/arcane/modules/RecordReviewStore.js +40 -35
- package/runtime/arcane/modules/TerminalClient.js +12 -14
- package/runtime/arcane/modules/ThemeBootstrap.js +7 -7
- package/runtime/arcane/modules/ThemeManager.js +5 -5
- package/runtime/arcane/modules/TimeGuard.js +5 -65
- package/runtime/arcane/modules/WaitForComponent.js +43 -40
- package/src/cli/main.mjs +12 -11
- package/src/installed-sdk-runtime.mjs +11 -1
- package/src/mail-server.mjs +12 -5
- package/src/mail.mjs +25 -19
- package/src/workspace.mjs +32 -9
|
@@ -3,24 +3,24 @@ import CommunicationMessage from '../entities/CommunicationMessage.js';
|
|
|
3
3
|
import CommunicationThread from '../entities/CommunicationThread.js';
|
|
4
4
|
import CommunicationProviderRegistry from './CommunicationProviderRegistry.js?v=2';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const communicationHubEvents={
|
|
7
7
|
refreshCancelled:'communications-refresh-cancelled',
|
|
8
8
|
refreshCompleted:'communications-refresh-completed',
|
|
9
9
|
refreshFailed:'communications-refresh-failed',
|
|
10
10
|
refreshLegacy:'communications-refresh',
|
|
11
11
|
refreshPartiallyCompleted:'communications-refresh-partially-completed',
|
|
12
12
|
refreshStarted:'communications-refresh-started'
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const communicationHubRefreshStates={
|
|
16
16
|
cancelled:'refresh-cancelled',
|
|
17
17
|
completed:'refresh-completed',
|
|
18
18
|
failed:'refresh-failed',
|
|
19
19
|
partiallyCompleted:'refresh-partially-completed',
|
|
20
20
|
started:'refresh-started'
|
|
21
|
-
}
|
|
21
|
+
};
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
const communicationHubRefreshReasons={
|
|
24
24
|
allProviderThreadListsRejected:'all-provider-thread-lists-rejected',
|
|
25
25
|
boundaryThrew:'refresh-boundary-threw',
|
|
26
26
|
hubDisposed:'hub-disposed',
|
|
@@ -28,9 +28,9 @@ export const COMMUNICATION_HUB_REFRESH_REASONS=Object.freeze({
|
|
|
28
28
|
signalAborted:'refresh-signal-aborted',
|
|
29
29
|
startCancelled:'refresh-start-cancelled',
|
|
30
30
|
superseded:'refresh-superseded'
|
|
31
|
-
}
|
|
31
|
+
};
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
const communicationHubErrorCodes={
|
|
34
34
|
allProviderThreadListsRejected:'ARCANE_COMMUNICATION_PROVIDER_THREAD_LISTS_REJECTED',
|
|
35
35
|
disposed:'ARCANE_COMMUNICATION_HUB_DISPOSED',
|
|
36
36
|
providerThreadListRejected:'ARCANE_COMMUNICATION_PROVIDER_THREAD_LIST_REJECTED',
|
|
@@ -38,7 +38,12 @@ export const COMMUNICATION_HUB_ERROR_CODES=Object.freeze({
|
|
|
38
38
|
refreshFailed:'ARCANE_COMMUNICATION_HUB_REFRESH_FAILED',
|
|
39
39
|
refreshOptionsInvalid:'ARCANE_COMMUNICATION_HUB_REFRESH_OPTIONS_INVALID',
|
|
40
40
|
refreshSuperseded:'ARCANE_COMMUNICATION_HUB_REFRESH_SUPERSEDED'
|
|
41
|
-
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const COMMUNICATION_HUB_EVENTS={...communicationHubEvents};
|
|
44
|
+
export const COMMUNICATION_HUB_REFRESH_STATES={...communicationHubRefreshStates};
|
|
45
|
+
export const COMMUNICATION_HUB_REFRESH_REASONS={...communicationHubRefreshReasons};
|
|
46
|
+
export const COMMUNICATION_HUB_ERROR_CODES={...communicationHubErrorCodes};
|
|
42
47
|
|
|
43
48
|
function codedError(message,code,{cause,name='Error',ErrorType=Error}={}){
|
|
44
49
|
const error=new ErrorType(message);
|
|
@@ -53,16 +58,16 @@ function codedError(message,code,{cause,name='Error',ErrorType=Error}={}){
|
|
|
53
58
|
function disposedError(){
|
|
54
59
|
return codedError(
|
|
55
60
|
'The communication hub has been disposed.',
|
|
56
|
-
|
|
61
|
+
communicationHubErrorCodes.disposed
|
|
57
62
|
);
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
function refreshAbortError(reason,code=
|
|
65
|
+
function refreshAbortError(reason,code=communicationHubErrorCodes.refreshAborted){
|
|
61
66
|
if(reason instanceof Error&&reason.name==='AbortError'&&reason.code===code){
|
|
62
67
|
return reason;
|
|
63
68
|
}
|
|
64
69
|
return codedError(
|
|
65
|
-
code===
|
|
70
|
+
code===communicationHubErrorCodes.refreshSuperseded
|
|
66
71
|
?'The communication refresh was superseded by a newer refresh.'
|
|
67
72
|
:'The communication refresh was aborted.',
|
|
68
73
|
code,
|
|
@@ -74,12 +79,12 @@ function refreshAbortError(reason,code=COMMUNICATION_HUB_ERROR_CODES.refreshAbor
|
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
function refreshFailureError(error){
|
|
77
|
-
if(error instanceof Error&&error.code===
|
|
82
|
+
if(error instanceof Error&&error.code===communicationHubErrorCodes.refreshFailed){
|
|
78
83
|
return error;
|
|
79
84
|
}
|
|
80
85
|
return codedError(
|
|
81
86
|
'The communication refresh boundary failed.',
|
|
82
|
-
|
|
87
|
+
communicationHubErrorCodes.refreshFailed,
|
|
83
88
|
{cause:error}
|
|
84
89
|
);
|
|
85
90
|
}
|
|
@@ -94,41 +99,24 @@ function isAbortSignal(value){
|
|
|
94
99
|
|
|
95
100
|
function normalizeRefreshOptions(value){
|
|
96
101
|
if(value===undefined){
|
|
97
|
-
return
|
|
102
|
+
return {signal:null};
|
|
98
103
|
}
|
|
99
104
|
if(!value||typeof value!=='object'||Array.isArray(value)){
|
|
100
105
|
throw codedError(
|
|
101
106
|
'Communication refresh options must be a plain record.',
|
|
102
|
-
|
|
103
|
-
{ErrorType:TypeError}
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
const descriptors=Object.getOwnPropertyDescriptors(value);
|
|
107
|
-
const unknown=Reflect.ownKeys(descriptors).find(
|
|
108
|
-
function findUnknownRefreshOption(key){
|
|
109
|
-
return key!=='signal';
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
if(unknown!==undefined||Object.values(descriptors).some(
|
|
113
|
-
function findRefreshOptionAccessor(descriptor){
|
|
114
|
-
return !Object.hasOwn(descriptor,'value');
|
|
115
|
-
}
|
|
116
|
-
)){
|
|
117
|
-
throw codedError(
|
|
118
|
-
'Communication refresh options may contain only a data signal property.',
|
|
119
|
-
COMMUNICATION_HUB_ERROR_CODES.refreshOptionsInvalid,
|
|
107
|
+
communicationHubErrorCodes.refreshOptionsInvalid,
|
|
120
108
|
{ErrorType:TypeError}
|
|
121
109
|
);
|
|
122
110
|
}
|
|
123
|
-
const signal=
|
|
111
|
+
const signal=value.signal??null;
|
|
124
112
|
if(signal!==null&&!isAbortSignal(signal)){
|
|
125
113
|
throw codedError(
|
|
126
114
|
'Communication refresh signal must be an AbortSignal.',
|
|
127
|
-
|
|
115
|
+
communicationHubErrorCodes.refreshOptionsInvalid,
|
|
128
116
|
{ErrorType:TypeError}
|
|
129
117
|
);
|
|
130
118
|
}
|
|
131
|
-
return
|
|
119
|
+
return {signal};
|
|
132
120
|
}
|
|
133
121
|
|
|
134
122
|
function normalizeProviderThreads(provider,values){
|
|
@@ -152,11 +140,15 @@ function compareThreadsByUpdatedAt(left,right){
|
|
|
152
140
|
}
|
|
153
141
|
|
|
154
142
|
function providerFailure(provider){
|
|
155
|
-
return
|
|
156
|
-
code:
|
|
143
|
+
return {
|
|
144
|
+
code:communicationHubErrorCodes.providerThreadListRejected,
|
|
157
145
|
providerId:provider.id,
|
|
158
|
-
reason:
|
|
159
|
-
}
|
|
146
|
+
reason:communicationHubRefreshReasons.providerThreadListRejected
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function copyProviderFailure(failure){
|
|
151
|
+
return {...failure};
|
|
160
152
|
}
|
|
161
153
|
|
|
162
154
|
function settleWithAbort(operation,promise){
|
|
@@ -215,7 +207,7 @@ export default class CommunicationHub extends EventTarget{
|
|
|
215
207
|
this,
|
|
216
208
|
{
|
|
217
209
|
source:'communication-hub',
|
|
218
|
-
eventTypes:Object.
|
|
210
|
+
eventTypes:Object.values(communicationHubEvents)
|
|
219
211
|
}
|
|
220
212
|
);
|
|
221
213
|
}
|
|
@@ -264,15 +256,15 @@ export default class CommunicationHub extends EventTarget{
|
|
|
264
256
|
operation.controller.abort(error);
|
|
265
257
|
if(!this.#events.disposed){
|
|
266
258
|
this.#events.dispatch(
|
|
267
|
-
|
|
268
|
-
|
|
259
|
+
communicationHubEvents.refreshCancelled,
|
|
260
|
+
{error,reason},
|
|
269
261
|
{
|
|
270
262
|
operationId:operation.operationId,
|
|
271
|
-
publicDetail:
|
|
263
|
+
publicDetail:{
|
|
272
264
|
code:error.code,
|
|
273
265
|
reason,
|
|
274
|
-
state:
|
|
275
|
-
}
|
|
266
|
+
state:communicationHubRefreshStates.cancelled
|
|
267
|
+
}
|
|
276
268
|
}
|
|
277
269
|
);
|
|
278
270
|
}
|
|
@@ -312,9 +304,9 @@ export default class CommunicationHub extends EventTarget{
|
|
|
312
304
|
this.#cancelActiveRefresh(
|
|
313
305
|
refreshAbortError(
|
|
314
306
|
undefined,
|
|
315
|
-
|
|
307
|
+
communicationHubErrorCodes.refreshSuperseded
|
|
316
308
|
),
|
|
317
|
-
|
|
309
|
+
communicationHubRefreshReasons.superseded
|
|
318
310
|
);
|
|
319
311
|
|
|
320
312
|
const providers=this.enabledProviders();
|
|
@@ -331,7 +323,7 @@ export default class CommunicationHub extends EventTarget{
|
|
|
331
323
|
this.#publishCancellation(
|
|
332
324
|
operation,
|
|
333
325
|
refreshAbortError(settings.signal.reason),
|
|
334
|
-
|
|
326
|
+
communicationHubRefreshReasons.signalAborted
|
|
335
327
|
);
|
|
336
328
|
}.bind(this);
|
|
337
329
|
settings.signal?.addEventListener(
|
|
@@ -341,22 +333,22 @@ export default class CommunicationHub extends EventTarget{
|
|
|
341
333
|
);
|
|
342
334
|
this.#refreshOperation=operation;
|
|
343
335
|
|
|
344
|
-
const providerIds=
|
|
336
|
+
const providerIds=providers.map(
|
|
345
337
|
function communicationProviderId(provider){
|
|
346
338
|
return provider.id;
|
|
347
339
|
}
|
|
348
|
-
)
|
|
340
|
+
);
|
|
349
341
|
const startPublication=this.#events.dispatch(
|
|
350
|
-
|
|
351
|
-
|
|
342
|
+
communicationHubEvents.refreshStarted,
|
|
343
|
+
{providerIds:[...providerIds]},
|
|
352
344
|
{
|
|
353
345
|
cancelable:true,
|
|
354
346
|
operationId:operation.operationId,
|
|
355
|
-
publicDetail:
|
|
347
|
+
publicDetail:{
|
|
356
348
|
providerCount:providerIds.length,
|
|
357
|
-
providerIds,
|
|
358
|
-
state:
|
|
359
|
-
}
|
|
349
|
+
providerIds:[...providerIds],
|
|
350
|
+
state:communicationHubRefreshStates.started
|
|
351
|
+
}
|
|
360
352
|
}
|
|
361
353
|
);
|
|
362
354
|
if(operation.terminal){
|
|
@@ -367,7 +359,7 @@ export default class CommunicationHub extends EventTarget{
|
|
|
367
359
|
this.#publishCancellation(
|
|
368
360
|
operation,
|
|
369
361
|
error,
|
|
370
|
-
|
|
362
|
+
communicationHubRefreshReasons.startCancelled
|
|
371
363
|
);
|
|
372
364
|
throw error;
|
|
373
365
|
}
|
|
@@ -375,7 +367,7 @@ export default class CommunicationHub extends EventTarget{
|
|
|
375
367
|
if(this.#refreshOperation!==operation){
|
|
376
368
|
throw operation.error??refreshAbortError(
|
|
377
369
|
undefined,
|
|
378
|
-
|
|
370
|
+
communicationHubErrorCodes.refreshSuperseded
|
|
379
371
|
);
|
|
380
372
|
}
|
|
381
373
|
|
|
@@ -411,7 +403,7 @@ export default class CommunicationHub extends EventTarget{
|
|
|
411
403
|
if(this.#refreshOperation!==operation){
|
|
412
404
|
throw operation.error??refreshAbortError(
|
|
413
405
|
undefined,
|
|
414
|
-
|
|
406
|
+
communicationHubErrorCodes.refreshSuperseded
|
|
415
407
|
);
|
|
416
408
|
}
|
|
417
409
|
|
|
@@ -435,45 +427,52 @@ export default class CommunicationHub extends EventTarget{
|
|
|
435
427
|
if(this.#refreshOperation!==operation){
|
|
436
428
|
throw operation.error??refreshAbortError(
|
|
437
429
|
undefined,
|
|
438
|
-
|
|
430
|
+
communicationHubErrorCodes.refreshSuperseded
|
|
439
431
|
);
|
|
440
432
|
}
|
|
441
433
|
|
|
442
434
|
this.threads=threads;
|
|
443
435
|
const returnedThreads=[...this.threads];
|
|
444
436
|
const returnedErrors=[...errors];
|
|
445
|
-
const frozenFailures=Object.freeze([...failures]);
|
|
446
437
|
const allProvidersRejected=providers.length>0
|
|
447
438
|
&&failures.length===providers.length;
|
|
448
439
|
const state=allProvidersRejected
|
|
449
|
-
?
|
|
440
|
+
?communicationHubRefreshStates.failed
|
|
450
441
|
:failures.length
|
|
451
|
-
?
|
|
452
|
-
:
|
|
442
|
+
?communicationHubRefreshStates.partiallyCompleted
|
|
443
|
+
:communicationHubRefreshStates.completed;
|
|
453
444
|
const terminalType=allProvidersRejected
|
|
454
|
-
?
|
|
445
|
+
?communicationHubEvents.refreshFailed
|
|
455
446
|
:failures.length
|
|
456
|
-
?
|
|
457
|
-
:
|
|
458
|
-
const compatibilityDetail=
|
|
459
|
-
errors:
|
|
460
|
-
failures:
|
|
447
|
+
?communicationHubEvents.refreshPartiallyCompleted
|
|
448
|
+
:communicationHubEvents.refreshCompleted;
|
|
449
|
+
const compatibilityDetail={
|
|
450
|
+
errors:[...returnedErrors],
|
|
451
|
+
failures:failures.map(copyProviderFailure),
|
|
461
452
|
state,
|
|
462
|
-
threads:
|
|
463
|
-
}
|
|
464
|
-
const publicDetail=
|
|
453
|
+
threads:[...returnedThreads]
|
|
454
|
+
};
|
|
455
|
+
const publicDetail={
|
|
465
456
|
...(allProvidersRejected
|
|
466
457
|
?{
|
|
467
|
-
code:
|
|
468
|
-
reason:
|
|
458
|
+
code:communicationHubErrorCodes.allProviderThreadListsRejected,
|
|
459
|
+
reason:communicationHubRefreshReasons.allProviderThreadListsRejected
|
|
469
460
|
}
|
|
470
461
|
:{}),
|
|
471
462
|
failureCount:failures.length,
|
|
472
|
-
failures:
|
|
463
|
+
failures:failures.map(copyProviderFailure),
|
|
473
464
|
providerCount:providers.length,
|
|
474
465
|
state,
|
|
475
466
|
threadCount:threads.length
|
|
476
|
-
}
|
|
467
|
+
};
|
|
468
|
+
const legacyDetail={
|
|
469
|
+
errors:[...returnedErrors],
|
|
470
|
+
threads:[...returnedThreads]
|
|
471
|
+
};
|
|
472
|
+
const legacyPublicDetail={
|
|
473
|
+
...publicDetail,
|
|
474
|
+
failures:publicDetail.failures.map(copyProviderFailure)
|
|
475
|
+
};
|
|
477
476
|
operation.terminal=true;
|
|
478
477
|
this.#clearRefreshOperation(operation);
|
|
479
478
|
this.#events.dispatch(
|
|
@@ -486,14 +485,11 @@ export default class CommunicationHub extends EventTarget{
|
|
|
486
485
|
);
|
|
487
486
|
if(!this.#events.disposed){
|
|
488
487
|
this.#events.dispatch(
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
errors:compatibilityDetail.errors,
|
|
492
|
-
threads:compatibilityDetail.threads
|
|
493
|
-
}),
|
|
488
|
+
communicationHubEvents.refreshLegacy,
|
|
489
|
+
legacyDetail,
|
|
494
490
|
{
|
|
495
491
|
operationId:operation.operationId,
|
|
496
|
-
publicDetail
|
|
492
|
+
publicDetail:legacyPublicDetail
|
|
497
493
|
}
|
|
498
494
|
);
|
|
499
495
|
}
|
|
@@ -506,9 +502,9 @@ export default class CommunicationHub extends EventTarget{
|
|
|
506
502
|
this.#publishCancellation(
|
|
507
503
|
operation,
|
|
508
504
|
error,
|
|
509
|
-
error.code===
|
|
510
|
-
?
|
|
511
|
-
:
|
|
505
|
+
error.code===communicationHubErrorCodes.refreshSuperseded
|
|
506
|
+
?communicationHubRefreshReasons.superseded
|
|
507
|
+
:communicationHubRefreshReasons.signalAborted
|
|
512
508
|
);
|
|
513
509
|
throw error;
|
|
514
510
|
}
|
|
@@ -518,15 +514,15 @@ export default class CommunicationHub extends EventTarget{
|
|
|
518
514
|
this.#clearRefreshOperation(operation);
|
|
519
515
|
if(!this.#events.disposed){
|
|
520
516
|
this.#events.dispatch(
|
|
521
|
-
|
|
522
|
-
|
|
517
|
+
communicationHubEvents.refreshFailed,
|
|
518
|
+
{error:failure},
|
|
523
519
|
{
|
|
524
520
|
operationId:operation.operationId,
|
|
525
|
-
publicDetail:
|
|
521
|
+
publicDetail:{
|
|
526
522
|
code:failure.code,
|
|
527
|
-
reason:
|
|
528
|
-
state:
|
|
529
|
-
}
|
|
523
|
+
reason:communicationHubRefreshReasons.boundaryThrew,
|
|
524
|
+
state:communicationHubRefreshStates.failed
|
|
525
|
+
}
|
|
530
526
|
}
|
|
531
527
|
);
|
|
532
528
|
}
|
|
@@ -583,9 +579,9 @@ export default class CommunicationHub extends EventTarget{
|
|
|
583
579
|
this.#cancelActiveRefresh(
|
|
584
580
|
refreshAbortError(
|
|
585
581
|
disposedError(),
|
|
586
|
-
|
|
582
|
+
communicationHubErrorCodes.disposed
|
|
587
583
|
),
|
|
588
|
-
|
|
584
|
+
communicationHubRefreshReasons.hubDisposed
|
|
589
585
|
);
|
|
590
586
|
return this.#events.dispose();
|
|
591
587
|
}
|
|
@@ -403,6 +403,37 @@ function effectiveDashboardVisibility(definitions=[],visibility={}){
|
|
|
403
403
|
);
|
|
404
404
|
}
|
|
405
405
|
|
|
406
|
+
function byteProgressUnit(value){
|
|
407
|
+
const unit=String(value??'')
|
|
408
|
+
.trim()
|
|
409
|
+
.toLowerCase()
|
|
410
|
+
.replace(/[\s_-]+/g,'');
|
|
411
|
+
return unit.includes('byte')
|
|
412
|
+
||unit.includes('octet')
|
|
413
|
+
||/^(?:[kmgtpe]?i?b)(?:(?:\/|per)?(?:s|sec|second))?$/u.test(unit);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function formatAIRuntimeProgress(progress,fallback){
|
|
417
|
+
const phase=typeof progress?.phase==='string'&&progress.phase
|
|
418
|
+
?progress.phase
|
|
419
|
+
:fallback;
|
|
420
|
+
const completed=progress?.completed;
|
|
421
|
+
const total=progress?.total;
|
|
422
|
+
const unit=typeof progress?.unit==='string'
|
|
423
|
+
?progress.unit
|
|
424
|
+
:'';
|
|
425
|
+
if(!Number.isSafeInteger(completed)
|
|
426
|
+
||completed<0
|
|
427
|
+
||!Number.isSafeInteger(total)
|
|
428
|
+
||total<=0
|
|
429
|
+
||completed>total
|
|
430
|
+
||!unit
|
|
431
|
+
||byteProgressUnit(unit)){
|
|
432
|
+
return phase;
|
|
433
|
+
}
|
|
434
|
+
return `${phase} · ${completed} of ${total} ${unit}`;
|
|
435
|
+
}
|
|
436
|
+
|
|
406
437
|
function createSTTActivationController({
|
|
407
438
|
host,
|
|
408
439
|
button,
|
|
@@ -539,13 +570,6 @@ function createSTTActivationController({
|
|
|
539
570
|
return 'Start the selected transcription service.';
|
|
540
571
|
}
|
|
541
572
|
|
|
542
|
-
function formatProgress(progress,fallback){
|
|
543
|
-
if(!progress){
|
|
544
|
-
return fallback;
|
|
545
|
-
}
|
|
546
|
-
return progress.phase;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
573
|
function status(){
|
|
550
574
|
if(requestError){
|
|
551
575
|
return `Transcription activation error: ${requestError}.`;
|
|
@@ -557,10 +581,10 @@ function createSTTActivationController({
|
|
|
557
581
|
return role.busy?'Transcription busy.':'Transcription ready.';
|
|
558
582
|
}
|
|
559
583
|
if(role?.state==='loading'){
|
|
560
|
-
return `Transcription ${
|
|
584
|
+
return `Transcription ${formatAIRuntimeProgress(role.progress,'loading')}; Cancel is available.`;
|
|
561
585
|
}
|
|
562
586
|
if(role?.state==='unloading'){
|
|
563
|
-
return `Transcription ${
|
|
587
|
+
return `Transcription ${formatAIRuntimeProgress(role.progress,'releasing')}.`;
|
|
564
588
|
}
|
|
565
589
|
if(role?.state==='error'){
|
|
566
590
|
return `Transcription error: ${visibleError(role.error,'Unknown error')}.`;
|
|
@@ -1043,6 +1067,7 @@ export {
|
|
|
1043
1067
|
applyMarkdownFormat,
|
|
1044
1068
|
createSTTActivationController,
|
|
1045
1069
|
effectiveDashboardVisibility,
|
|
1070
|
+
formatAIRuntimeProgress,
|
|
1046
1071
|
normalizeChartOptions,
|
|
1047
1072
|
normalizeChartRows,
|
|
1048
1073
|
normalizeDashboardDefinitions,
|