arcane-os 0.3.0 → 0.3.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.
Files changed (153) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +86 -117
  3. package/bin/arcane-test.mjs +170 -46
  4. package/browser-runtime/ai/browser-speech-artifacts.mjs +887 -909
  5. package/browser-runtime/ai/browser-speech-providers.mjs +96 -152
  6. package/browser-runtime/ai/browser-wasm-llm-provider.mjs +627 -819
  7. package/browser-runtime/ai/browser-wasm.mjs +24 -35
  8. package/browser-runtime/ai/browser-wllama-runtime.mjs +64 -316
  9. package/browser-runtime/ai/model-controller.mjs +584 -181
  10. package/browser-runtime/ai/speech-worker-client.mjs +8 -146
  11. package/browser-runtime/ai/speech-worker-runtime.mjs +643 -363
  12. package/browser-runtime/dom-event-instrumentation.mjs +55 -147
  13. package/browser-runtime/event-manager.mjs +239 -624
  14. package/package.json +5 -6
  15. package/runtime/arcane/components/app-bar.html +3 -15
  16. package/runtime/arcane/components/assistant-panel.html +10 -10
  17. package/runtime/arcane/components/calculator.html +1 -1
  18. package/runtime/arcane/components/chat.html +1359 -135
  19. package/runtime/arcane/components/conversation-view.html +2 -2
  20. package/runtime/arcane/components/document-inspector.html +11 -17
  21. package/runtime/arcane/components/file-manager.html +13 -56
  22. package/runtime/arcane/components/markdown-document.html +82 -281
  23. package/runtime/arcane/components/markdown-editor.html +7 -10
  24. package/runtime/arcane/components/media-embed.html +6 -6
  25. package/runtime/arcane/components/screen-capture.html +4 -4
  26. package/runtime/arcane/components/source-explanation.html +2 -2
  27. package/runtime/arcane/components/speech.html +112 -68
  28. package/runtime/arcane/components/terminal-workspace.html +4 -4
  29. package/runtime/arcane/components/theme-editor.html +1 -1
  30. package/runtime/arcane/components/unified-inbox.html +2 -2
  31. package/runtime/arcane/components/voice-transcription.html +31 -21
  32. package/runtime/arcane/entities/Calculation.js +2 -3
  33. package/runtime/arcane/entities/Chat.js +228 -43
  34. package/runtime/arcane/entities/Preference.js +3 -5
  35. package/runtime/arcane/entities/Weather.js +5 -5
  36. package/runtime/arcane/modules/AI.js +1050 -427
  37. package/runtime/arcane/modules/AIProviderRuntime.js +658 -363
  38. package/runtime/arcane/modules/AIResponseLength.js +9 -19
  39. package/runtime/arcane/modules/AIRuntimeState.js +109 -72
  40. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +45 -32
  41. package/runtime/arcane/modules/BrowserTestSuite.js +78 -122
  42. package/runtime/arcane/modules/CalculatorEngine.js +9 -9
  43. package/runtime/arcane/modules/CommunicationAppController.js +3 -7
  44. package/runtime/arcane/modules/ComponentContracts.js +30 -32
  45. package/runtime/arcane/modules/ConfiguredAIChatSession.js +281 -230
  46. package/runtime/arcane/modules/ConversationActionItems.js +26 -59
  47. package/runtime/arcane/modules/ConversationClosingReport.js +34 -61
  48. package/runtime/arcane/modules/ConversationTimebox.js +27 -15
  49. package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +152 -344
  50. package/runtime/arcane/modules/DocumentLexicalSearch.js +25 -91
  51. package/runtime/arcane/modules/HTMLImport.js +54 -1
  52. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +40 -203
  53. package/runtime/arcane/modules/LocalAIReadiness.js +40 -60
  54. package/runtime/arcane/modules/LocalAIReadinessController.js +15 -13
  55. package/runtime/arcane/modules/MD.js +1 -45
  56. package/runtime/arcane/modules/Mail.js +51 -103
  57. package/runtime/arcane/modules/MailOutbox.mjs +95 -193
  58. package/runtime/arcane/modules/MailTransport.mjs +36 -57
  59. package/runtime/arcane/modules/ModelDefinition.js +22 -106
  60. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +39 -101
  61. package/runtime/arcane/modules/PersistentAIChatSession.js +281 -18
  62. package/runtime/arcane/modules/PreferenceStore.js +102 -30
  63. package/runtime/arcane/modules/RiskSignalAnalyzer.js +8 -9
  64. package/runtime/arcane/modules/ScopedOPFSCache.js +7 -42
  65. package/runtime/arcane/modules/ScreenCapture.js +175 -128
  66. package/runtime/arcane/modules/SpeechPlayback.js +46 -149
  67. package/runtime/arcane/modules/StaticDocumentCatalog.js +173 -407
  68. package/runtime/arcane/modules/ToolCallRouter.js +25 -12
  69. package/runtime/arcane/modules/YouTubeMedia.js +6 -5
  70. package/schemas/arcane-app-bundle.schema.json +13 -78
  71. package/schemas/arcane-app.schema.json +9 -25
  72. package/schemas/arcane-lock.schema.json +18 -151
  73. package/schemas/arcane-package.schema.json +2 -16
  74. package/schemas/native-build-plan.schema.json +119 -122
  75. package/src/app-descriptor.mjs +75 -132
  76. package/src/application-tests.mjs +200 -0
  77. package/src/cli/main.mjs +27 -46
  78. package/src/constants.mjs +3 -4
  79. package/src/dev-server.mjs +30 -324
  80. package/src/doctor.mjs +92 -154
  81. package/src/dom-event-instrumentation.mjs +55 -147
  82. package/src/errors.mjs +2 -3
  83. package/src/event-manager.mjs +239 -624
  84. package/src/event-queue.mjs +3 -3
  85. package/src/import-map.mjs +273 -1028
  86. package/src/index.mjs +14 -16
  87. package/src/installed-sdk-runtime.mjs +40 -62
  88. package/src/integrated-provider-loader.mjs +53 -382
  89. package/src/mail-api.mjs +0 -2
  90. package/src/mail-server.mjs +224 -580
  91. package/src/mail.mjs +4 -10
  92. package/src/native-plan.mjs +163 -598
  93. package/src/native-provider-loader.mjs +104 -1063
  94. package/src/packager/core.mjs +485 -3229
  95. package/src/process.mjs +5 -10
  96. package/src/release-bundle.mjs +292 -2405
  97. package/src/runtime.mjs +76 -396
  98. package/src/scaffold.mjs +30 -80
  99. package/src/sdk-browser-runtime.mjs +70 -626
  100. package/src/source-server.mjs +588 -0
  101. package/src/targets/index.mjs +78 -188
  102. package/src/templates/workspace-template.mjs +19 -135
  103. package/src/testing-loader.mjs +164 -0
  104. package/src/testing.mjs +1 -1
  105. package/src/toolchain.mjs +131 -544
  106. package/src/update-check.mjs +26 -64
  107. package/src/workspace-operation-lock.mjs +139 -430
  108. package/src/workspace-runtime.mjs +112 -779
  109. package/src/workspace.mjs +40 -302
  110. package/browser-runtime/ARCANE_SDK_BROWSER_RELEASE.json +0 -218
  111. package/browser-runtime/ai/ARCANE_AI_BROWSER_SPEECH_COMPONENTS.json +0 -203
  112. package/browser-runtime/ai/ARCANE_AI_BROWSER_WASM_COMPONENTS.json +0 -80
  113. package/browser-runtime/ai/internal/sha256.mjs +0 -166
  114. package/docs/architecture.md +0 -344
  115. package/docs/compatibility.md +0 -36
  116. package/docs/event-manager.md +0 -294
  117. package/docs/platform-targets.md +0 -108
  118. package/docs/publishing.md +0 -201
  119. package/docs/reference/README.md +0 -187
  120. package/docs/reference/ai/browser-speech-package-authority.json +0 -835
  121. package/docs/reference/ai/browser-speech.md +0 -1252
  122. package/docs/reference/ai/browser-wasm.md +0 -530
  123. package/docs/reference/arcane-ollama.md +0 -288
  124. package/docs/reference/availability-and-normalization.md +0 -183
  125. package/docs/reference/behavioral-testing.md +0 -133
  126. package/docs/reference/cli.md +0 -779
  127. package/docs/reference/core/README.md +0 -62
  128. package/docs/reference/core/arcane-ai-contracts.md +0 -907
  129. package/docs/reference/core/arcane-api.md +0 -601
  130. package/docs/reference/core/arcane-entities.md +0 -65
  131. package/docs/reference/core/arcane-events.md +0 -134
  132. package/docs/reference/core/ollama-module.md +0 -181
  133. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +0 -1909
  134. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +0 -1057
  135. package/docs/reference/core/reference/arcane-api/core-and-events.md +0 -320
  136. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +0 -610
  137. package/docs/reference/core/reference/arcane-api/namespaces.md +0 -1157
  138. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +0 -1423
  139. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +0 -315
  140. package/docs/reference/event-manager.md +0 -1511
  141. package/docs/reference/inventory/package-api.json +0 -3284
  142. package/docs/reference/inventory/runtime-components.json +0 -1011
  143. package/docs/reference/inventory/runtime-entities.json +0 -26
  144. package/docs/reference/inventory/runtime-modules.json +0 -1431
  145. package/docs/reference/mail.md +0 -316
  146. package/docs/reference/protocols.md +0 -677
  147. package/docs/reference/runtime-components.md +0 -1366
  148. package/docs/reference/runtime-entities.md +0 -303
  149. package/docs/reference/runtime-modules.md +0 -2960
  150. package/docs/reference/sdk-api.md +0 -6694
  151. package/docs/roadmap.md +0 -79
  152. package/docs/work-amplification.md +0 -129
  153. package/runtime/ARCANE_RUNTIME_RELEASE.json +0 -826
@@ -1,158 +1,69 @@
1
1
  import {createArcaneEventSource} from 'arcane-os/event-manager';
2
2
 
3
- const MAX_SPEECH_INPUT=3900;
4
- const MAX_SPEECH_CHUNKS=32;
5
- const MAX_SPEECH_CHARACTERS=MAX_SPEECH_INPUT*MAX_SPEECH_CHUNKS;
6
- const PREFERRED_STREAM_SEGMENT=700;
7
- const SPEECH_VOICE_OPTIONS=Object.freeze([
8
- Object.freeze({value:'alloy',label:'Alloy'}),
9
- Object.freeze({value:'ash',label:'Ash'}),
10
- Object.freeze({value:'ballad',label:'Ballad'}),
11
- Object.freeze({value:'coral',label:'Coral'}),
12
- Object.freeze({value:'echo',label:'Echo'}),
13
- Object.freeze({value:'fable',label:'Fable'}),
14
- Object.freeze({value:'nova',label:'Nova'}),
15
- Object.freeze({value:'onyx',label:'Onyx'}),
16
- Object.freeze({value:'sage',label:'Sage'}),
17
- Object.freeze({value:'shimmer',label:'Shimmer'})
18
- ]);
19
- const SUPERSEDED=Object.freeze({superseded:true});
3
+ const SPEECH_VOICE_OPTIONS=[
4
+ {value:'alloy',label:'Alloy'},
5
+ {value:'ash',label:'Ash'},
6
+ {value:'ballad',label:'Ballad'},
7
+ {value:'coral',label:'Coral'},
8
+ {value:'echo',label:'Echo'},
9
+ {value:'fable',label:'Fable'},
10
+ {value:'nova',label:'Nova'},
11
+ {value:'onyx',label:'Onyx'},
12
+ {value:'sage',label:'Sage'},
13
+ {value:'shimmer',label:'Shimmer'}
14
+ ];
15
+ const SUPERSEDED={superseded:true};
20
16
  const SPEECH_PLAYBACK_STATE_EVENT='speech-playback-state';
21
- const SPEECH_PLAYBACK_FAILURE_REASONS=Object.freeze({
17
+ const SPEECH_PLAYBACK_FAILURE_REASONS={
22
18
  ARCANE_AI_OPERATION_SUPERSEDED:'speech-synthesis-superseded',
23
19
  ARCANE_AI_REQUEST_ABORTED:'speech-synthesis-cancelled',
24
20
  ARCANE_SPEECH_PLAYBACK_AUDIO_PLAYBACK_REJECTED:'audio-playback-rejected',
25
21
  ARCANE_SPEECH_PLAYBACK_SYNTHESIZED_AUDIO_CONTRACT_MISMATCH:'synthesized-audio-contract-mismatch',
26
22
  ARCANE_SPEECH_PLAYBACK_SYNTHESIZER_UNAVAILABLE:'speech-synthesizer-unavailable'
27
- });
28
- const WAV_AUDIO_CONTENT_TYPES=Object.freeze(new Set([
23
+ };
24
+ const WAV_AUDIO_CONTENT_TYPES=new Set([
29
25
  'audio/vnd.wave',
30
26
  'audio/wav',
31
27
  'audio/wave',
32
28
  'audio/x-wav'
33
- ]));
29
+ ]);
34
30
  const queuesBySpeechClient=new WeakMap();
35
31
 
36
- class ReadonlyAliasSet{
37
- #values;
38
-
39
- constructor(values){
40
- this.#values=new Set(values);
41
- Object.freeze(this);
42
- }
43
-
44
- get size(){return this.#values.size;}
45
- get [Symbol.toStringTag](){return 'Set';}
46
- has(value){return this.#values.has(value);}
47
- entries(){return this.#values.entries();}
48
- keys(){return this.#values.keys();}
49
- values(){return this.#values.values();}
50
- [Symbol.iterator](){return this.values();}
51
-
52
- forEach(callback,thisArgument){
53
- for(const value of this.#values)callback.call(thisArgument,value,value,this);
54
- }
55
- }
56
-
57
- const SPEECH_VOICE_ALIASES=new ReadonlyAliasSet(
32
+ const SPEECH_VOICE_ALIASES=new Set(
58
33
  SPEECH_VOICE_OPTIONS.map(function voiceAlias(option){return option.value;})
59
34
  );
60
35
 
61
- function speechLimitError(message='Speech text is too long for bounded playback. The full visual content remains available.'){
62
- return new RangeError(message);
63
- }
64
-
65
- function speechBoundary(value,limit,minimum){
66
- const candidates=[
67
- value.lastIndexOf('\n\n',limit),
68
- value.lastIndexOf('. ',limit),
69
- value.lastIndexOf('? ',limit),
70
- value.lastIndexOf('! ',limit),
71
- value.lastIndexOf('; ',limit),
72
- value.lastIndexOf(', ',limit),
73
- value.lastIndexOf(' ',limit)
74
- ];
75
- const boundary=Math.max(...candidates);
76
- return boundary>=minimum
77
- ?Math.min(limit,boundary+(/^[.!?;,]$/.test(value[boundary]||'')?1:0))
78
- :limit;
79
- }
80
-
81
- function splitSpeechText(
82
- value='',
83
- maximum=MAX_SPEECH_INPUT,
84
- maximumChunks=MAX_SPEECH_CHUNKS,
85
- {
86
- tooLongMessage='Speech text is too long for bounded playback. The full visual content remains available.',
87
- queueLimitMessage='Speech text exceeds the bounded playback queue. The full visual content remains available.'
88
- }={}
89
- ){
90
- const text=String(value??'').trim();
91
- if(!text)return [];
92
- if(!Number.isInteger(maximum)||maximum<100||maximum>4000){
93
- throw new RangeError('Speech chunk size must be between 100 and 4,000 characters.');
94
- }
95
- if(!Number.isInteger(maximumChunks)||maximumChunks<1||maximumChunks>MAX_SPEECH_CHUNKS){
96
- throw new RangeError(`Speech chunk count must be between 1 and ${MAX_SPEECH_CHUNKS}.`);
97
- }
98
- if(text.length>maximum*maximumChunks)throw speechLimitError(tooLongMessage);
99
- const chunks=[];
100
- let remaining=text;
101
- while(remaining.length){
102
- const slots=maximumChunks-chunks.length;
103
- if(slots<1)throw speechLimitError(queueLimitMessage);
104
- if(remaining.length<=maximum&&remaining.length<=PREFERRED_STREAM_SEGMENT){
105
- chunks.push(remaining);
106
- break;
107
- }
108
- const minimum=Math.ceil(remaining.length/slots);
109
- const preferred=chunks.length===0?PREFERRED_STREAM_SEGMENT:maximum;
110
- const target=Math.min(maximum,Math.max(preferred,minimum));
111
- if(remaining.length<=target){
112
- chunks.push(remaining);
113
- break;
114
- }
115
- const boundary=speechBoundary(remaining,target,Math.max(minimum,Math.floor(target*0.55)));
116
- chunks.push(remaining.slice(0,boundary).trim());
117
- remaining=remaining.slice(boundary).trimStart();
118
- }
119
- return chunks;
36
+ function splitSpeechText(value=''){
37
+ const text=String(value??'');
38
+ return text.trim()?[text]:[];
120
39
  }
121
40
 
122
41
  function normalizeParts(parts,defaultVoice=null,defaultSpeed=1){
123
42
  if(!Array.isArray(parts)||!parts.length){
124
43
  throw new TypeError('Narration text cannot be blank. The full visual content remains available.');
125
44
  }
126
- if(parts.length>MAX_SPEECH_CHUNKS){
127
- throw speechLimitError('Speech text exceeds the bounded playback queue. The full visual content remains available.');
128
- }
129
45
  return parts.map(function normalizePart(part){
130
46
  const candidate=typeof part==='string'?{input:part}:part;
131
- const input=String(candidate?.input??'').trim();
132
- if(!input)throw new TypeError('Speech segments cannot be blank. The full visual content remains available.');
133
- if(input.length>MAX_SPEECH_INPUT){
134
- throw speechLimitError('A speech segment exceeds the local service limit. The full visual content remains available.');
135
- }
47
+ const input=String(candidate?.input??'');
48
+ if(!input.trim())throw new TypeError('Speech segments cannot be blank. The full visual content remains available.');
136
49
  const pauseAfterMs=Number(candidate?.pauseAfterMs??0);
137
- if(!Number.isFinite(pauseAfterMs)||pauseAfterMs<0||pauseAfterMs>60_000){
138
- throw new RangeError('Speech segment pauses must be between 0 and 60,000 milliseconds.');
50
+ if(!Number.isFinite(pauseAfterMs)||pauseAfterMs<0){
51
+ throw new RangeError('Speech segment pauses must be a nonnegative number of milliseconds.');
139
52
  }
140
53
  const voiceValue=candidate?.voice??defaultVoice;
141
- const voice=voiceValue===null||voiceValue===undefined
142
- ?null
143
- :String(voiceValue).trim();
54
+ const voice=voiceValue===null||voiceValue===undefined?null:String(voiceValue);
144
55
  const speed=Number(candidate?.speed??defaultSpeed);
145
- if(voiceValue!==null&&voiceValue!==undefined&&!voice){
56
+ if(voiceValue!==null&&voiceValue!==undefined&&!voice.trim()){
146
57
  throw new TypeError('Speech segment voice cannot be blank.');
147
58
  }
148
59
  if(!Number.isFinite(speed)||speed<=0)throw new RangeError('Every speech segment requires a positive speech speed.');
149
- return Object.freeze({
60
+ return {
150
61
  input,
151
62
  pauseAfterMs,
152
63
  role:String(candidate?.role||'narration'),
153
64
  speed,
154
65
  voice
155
- });
66
+ };
156
67
  });
157
68
  }
158
69
 
@@ -394,7 +305,7 @@ function queueFor(speech){
394
305
  return queue;
395
306
  }
396
307
 
397
- const DEFAULT_MESSAGES=Object.freeze({
308
+ const DEFAULT_MESSAGES={
398
309
  idle:'Speech is ready when visual content is available.',
399
310
  queued:'Waiting for the current local speech request. The latest narration will begin next.',
400
311
  preparing:function preparing({count}){return `Preparing ${count===1?'the narration':`${count} speech segments`}.`;},
@@ -412,7 +323,7 @@ const DEFAULT_MESSAGES=Object.freeze({
412
323
  invalidAudio:'Arcane returned invalid synthesized audio.',
413
324
  playbackError:'The synthesized narration could not be played. The visual content remains available.',
414
325
  fallbackError:'Speech is unavailable. The visual content remains available.'
415
- });
326
+ };
416
327
 
417
328
  class SpeechPlayback{
418
329
  constructor({
@@ -441,7 +352,7 @@ class SpeechPlayback{
441
352
  this,
442
353
  {
443
354
  source:'speech-playback',
444
- eventTypes:Object.freeze([SPEECH_PLAYBACK_STATE_EVENT])
355
+ eventTypes:[SPEECH_PLAYBACK_STATE_EVENT]
445
356
  }
446
357
  );
447
358
  this.onState=onState;
@@ -463,7 +374,7 @@ class SpeechPlayback{
463
374
  timer=globalThis.setTimeout(finish,duration);
464
375
  });
465
376
  };
466
- this.messages=Object.freeze({...DEFAULT_MESSAGES,...messages});
377
+ this.messages={...DEFAULT_MESSAGES,...messages};
467
378
  this.urls=[];
468
379
  this.parts=[];
469
380
  this.index=0;
@@ -471,11 +382,11 @@ class SpeechPlayback{
471
382
  this.pendingGenerations=new Set();
472
383
  this.lookahead=null;
473
384
  this.lookaheadError=null;
474
- this.model=model===null||model===undefined?null:String(model).trim()||null;
475
- this.voice=voice===null||voice===undefined?null:String(voice).trim()||null;
385
+ this.model=model===null||model===undefined?null:String(model);
386
+ this.voice=voice===null||voice===undefined?null:String(voice);
476
387
  this.responseFormat=responseFormat===null||responseFormat===undefined
477
388
  ?null
478
- :String(responseFormat).trim()||null;
389
+ :String(responseFormat);
479
390
  this.speed=normalizedSpeed;
480
391
  this.key='';
481
392
  this.state='idle';
@@ -512,7 +423,7 @@ class SpeechPlayback{
512
423
 
513
424
  emit(state,message,key=this.key,{code=null,reason=null}={}){
514
425
  this.state=state;
515
- const detail=Object.freeze({
426
+ const detail={
516
427
  state,
517
428
  message,
518
429
  key,
@@ -524,24 +435,14 @@ class SpeechPlayback{
524
435
  operationId:this.operationId,
525
436
  code,
526
437
  reason
527
- });
438
+ };
528
439
  if(!this.destroyed){
529
440
  this.events.dispatch(
530
441
  SPEECH_PLAYBACK_STATE_EVENT,
531
442
  detail,
532
443
  {
533
444
  operationId:this.operationId,
534
- publicDetail:{
535
- state,
536
- key,
537
- index:detail.index,
538
- total:detail.total,
539
- producing:detail.producing,
540
- buffered:detail.buffered,
541
- hasAudio:detail.hasAudio,
542
- code,
543
- reason
544
- }
445
+ publicDetail:detail
545
446
  }
546
447
  );
547
448
  }
@@ -622,7 +523,7 @@ class SpeechPlayback{
622
523
  async synthesizeSegment(index,generation,announce=false){
623
524
  const playback=this;
624
525
  const controller=new AbortController();
625
- const token=Object.freeze({generation,index,controller});
526
+ const token={generation,index,controller};
626
527
  const queue=queueFor(this.speech);
627
528
  this.pendingGenerations.add(token);
628
529
  this.abortControllers.add(controller);
@@ -758,20 +659,20 @@ class SpeechPlayback{
758
659
  if(!Number.isFinite(numericSpeed)||numericSpeed<=0)throw new RangeError('Speech speed must be a positive number.');
759
660
  const selectedModel=model===null||model===undefined
760
661
  ?null
761
- :String(model).trim();
662
+ :String(model);
762
663
  const selectedVoice=voice===null||voice===undefined
763
664
  ?null
764
- :String(voice).trim();
665
+ :String(voice);
765
666
  const selectedResponseFormat=responseFormat===null||responseFormat===undefined
766
667
  ?null
767
- :String(responseFormat).trim();
768
- if(model!==null&&model!==undefined&&!selectedModel){
668
+ :String(responseFormat);
669
+ if(model!==null&&model!==undefined&&!selectedModel.trim()){
769
670
  throw new TypeError('Speech model cannot be blank.');
770
671
  }
771
- if(voice!==null&&voice!==undefined&&!selectedVoice){
672
+ if(voice!==null&&voice!==undefined&&!selectedVoice.trim()){
772
673
  throw new TypeError('Speech voice cannot be blank.');
773
674
  }
774
- if(responseFormat!==null&&responseFormat!==undefined&&!selectedResponseFormat){
675
+ if(responseFormat!==null&&responseFormat!==undefined&&!selectedResponseFormat.trim()){
775
676
  throw new TypeError('Speech response format cannot be blank.');
776
677
  }
777
678
  this.speed=numericSpeed;
@@ -965,10 +866,6 @@ class SpeechPlayback{
965
866
  }
966
867
 
967
868
  export {
968
- MAX_SPEECH_CHARACTERS,
969
- MAX_SPEECH_CHUNKS,
970
- MAX_SPEECH_INPUT,
971
- PREFERRED_STREAM_SEGMENT,
972
869
  SPEECH_VOICE_ALIASES,
973
870
  SPEECH_VOICE_OPTIONS,
974
871
  SPEECH_PLAYBACK_STATE_EVENT,