arcane-os 0.5.7 → 0.5.9
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 +25 -0
- package/README.md +39 -27
- package/browser-runtime/ai/browser-speech-artifacts.mjs +23 -1683
- package/browser-runtime/ai/browser-speech-providers.mjs +353 -143
- package/browser-runtime/ai/browser-wasm-llm-provider.mjs +32 -324
- package/browser-runtime/ai/speech-worker-client.mjs +51 -14
- package/browser-runtime/ai/speech-worker-runtime.mjs +45 -1072
- package/browser-runtime/dependencies/strong-type/package.json +22 -23
- package/browser-runtime/event-manager.mjs +27 -41
- package/package.json +2 -3
- package/runtime/arcane/components/chat.html +1 -1
- package/runtime/arcane/components/speech.html +8 -38
- package/runtime/arcane/components/voice-transcription.html +1 -1
- package/runtime/arcane/css/theme.css +1 -1
- package/runtime/arcane/entities/Chat.js +12 -7
- package/runtime/arcane/modules/AI.js +569 -402
- package/runtime/arcane/modules/AIPreferenceTuple.js +1 -1
- package/runtime/arcane/modules/AIProviderRuntime.js +129 -68
- package/runtime/arcane/modules/AIRuntimeState.js +2 -18
- package/runtime/arcane/modules/BrowserTestSuite.js +2 -5
- package/runtime/arcane/modules/CalculatorEngine.js +0 -4
- package/runtime/arcane/modules/ChatRecords.js +169 -1
- package/runtime/arcane/modules/CommunicationHub.js +0 -19
- package/runtime/arcane/modules/ConfiguredAIChatSession.js +28 -25
- package/runtime/arcane/modules/DBOPFSDocumentLibrary.js +4 -5
- package/runtime/arcane/modules/DocumentLexicalSearch.js +1 -1
- package/runtime/arcane/modules/Errors.js +6 -19
- package/runtime/arcane/modules/Mail.js +1 -2
- package/runtime/arcane/modules/MailTransport.mjs +1 -3
- package/runtime/arcane/modules/OllamaModelIdentifier.js +1 -1
- package/runtime/arcane/modules/PersistentAIChatSession.js +5 -5
- package/runtime/arcane/modules/ScreenCapture.js +2 -4
- package/runtime/arcane/modules/SpeechPlayback.js +0 -27
- package/runtime/arcane/modules/WaitForComponent.js +0 -1
- package/src/app-descriptor.mjs +1 -1
- package/src/doctor.mjs +1 -3
- package/src/event-manager.mjs +27 -41
- package/src/import-map.mjs +1 -1
- package/src/index.mjs +2 -9
- package/src/installed-sdk-runtime.mjs +1 -11
- package/src/mail-api.mjs +0 -1
- package/src/native-provider-loader.mjs +0 -9
- package/src/scaffold.mjs +9 -21
- package/src/toolchain.mjs +5 -28
- package/src/workspace-runtime.mjs +0 -4
- package/src/workspace.mjs +2 -23
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "strong-type",
|
|
1
|
+
{
|
|
2
|
+
"name": "strong-type",
|
|
3
3
|
"version": "2.0.0",
|
|
4
|
-
"type": "module",
|
|
4
|
+
"type": "module",
|
|
5
5
|
"description": "Dependency-free native ESM type enforcement for JavaScript values, objects, classes, browsers, and Node.",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"exports": {
|
|
@@ -19,30 +19,29 @@
|
|
|
19
19
|
"licence"
|
|
20
20
|
],
|
|
21
21
|
"sideEffects": false,
|
|
22
|
-
"directories": {
|
|
23
|
-
"example": "example"
|
|
24
|
-
},
|
|
25
|
-
"engines": {
|
|
26
|
-
"node": ">=12.21.0"
|
|
27
|
-
},
|
|
22
|
+
"directories": {
|
|
23
|
+
"example": "example"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=12.21.0"
|
|
27
|
+
},
|
|
28
28
|
"scripts": {
|
|
29
29
|
"test": "node scripts/test.js",
|
|
30
30
|
"test:core": "node scripts/test.js core",
|
|
31
31
|
"test:node": "node scripts/test.js node",
|
|
32
32
|
"test:docs": "node scripts/test.js docs",
|
|
33
|
-
"test:legacy": "node scripts/test.js legacy",
|
|
34
33
|
"coverage": "node --test --experimental-test-coverage --test-coverage-include=index.js --test-coverage-include=node.js --test-coverage-lines=95 --test-coverage-branches=90 --test-coverage-functions=95 test/CI.js test/node.js test/docs.js",
|
|
35
34
|
"start": "node scripts/serve.js",
|
|
36
35
|
"nodeExample": "node ./example/node/typecheck.js",
|
|
37
36
|
"check": "npm test"
|
|
38
|
-
},
|
|
39
|
-
"repository": {
|
|
40
|
-
"type": "git",
|
|
41
|
-
"url": "git+https://github.com/RIAEvangelist/strong-type.git"
|
|
42
|
-
},
|
|
43
|
-
"keywords": [
|
|
44
|
-
"strong",
|
|
45
|
-
"type",
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/RIAEvangelist/strong-type.git"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"strong",
|
|
44
|
+
"type",
|
|
46
45
|
"validation",
|
|
47
46
|
"validate",
|
|
48
47
|
"check",
|
|
@@ -51,11 +50,11 @@
|
|
|
51
50
|
"isomorphic",
|
|
52
51
|
"browser",
|
|
53
52
|
"node"
|
|
54
|
-
],
|
|
53
|
+
],
|
|
55
54
|
"author": "Roshi _ _",
|
|
56
|
-
"license": "MIT",
|
|
57
|
-
"bugs": {
|
|
58
|
-
"url": "https://github.com/RIAEvangelist/strong-type/issues"
|
|
59
|
-
},
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/RIAEvangelist/strong-type/issues"
|
|
58
|
+
},
|
|
60
59
|
"homepage": "https://riaevangelist.github.io/strong-type/"
|
|
61
60
|
}
|
|
@@ -28,7 +28,6 @@ export const ARCANE_EVENT_AUTHORITY_KIND='arcane-event-authority';
|
|
|
28
28
|
export const ARCANE_EVENT_SOURCE_KIND='arcane-event-source';
|
|
29
29
|
export const ARCANE_EVENT_LISTENER_ERROR_EVENT='arcane.event.listener.error';
|
|
30
30
|
export const ARCANE_EVENT_SOURCE_DISPOSED_EVENT='arcane.event.source.disposed';
|
|
31
|
-
const ARCANE_EVENT_TARGET_COMPATIBILITY_SOURCE='event-target-compatibility';
|
|
32
31
|
const ARCANE_EVENT_NAME_PATTERN=/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/u;
|
|
33
32
|
const ARCANE_EVENT_CHANNEL_PREFIX='arcane.event.authority.internal:';
|
|
34
33
|
const ARCANE_EVENT_PROJECTION_KEYS=[
|
|
@@ -36,23 +35,13 @@ const ARCANE_EVENT_PROJECTION_KEYS=[
|
|
|
36
35
|
];
|
|
37
36
|
const ARCANE_EVENT_REQUIRED_AUTHORITY_API=[
|
|
38
37
|
'on','once','off','reset','emit','instrument','forward','subscribe','createSource',
|
|
39
|
-
'projectDOMEvent','isOccurrence','addEventListener','removeEventListener'
|
|
38
|
+
'projectDOMEvent','isOccurrence','addEventListener','removeEventListener'
|
|
40
39
|
];
|
|
41
40
|
const EVENT_MANAGER_BUS_ON=Symbol('EventManager.busOn');
|
|
42
41
|
const EVENT_MANAGER_BUS_OFF=Symbol('EventManager.busOff');
|
|
43
42
|
const EVENT_MANAGER_DISPATCH=Symbol('EventManager.dispatch');
|
|
44
43
|
|
|
45
44
|
const ARCANE_EVENT_ERRORS={
|
|
46
|
-
ARCANE_EVENT_AUTHORITY_ACCESSOR_COLLISION:
|
|
47
|
-
'globalThis.arcaneEvents must be an own data property.',
|
|
48
|
-
ARCANE_EVENT_AUTHORITY_VALUE_COLLISION:
|
|
49
|
-
'globalThis.arcaneEvents is occupied by an unbranded value.',
|
|
50
|
-
ARCANE_EVENT_AUTHORITY_DESCRIPTOR_MISMATCH:
|
|
51
|
-
'The globalThis.arcaneEvents property, authority brand, or protocol descriptor is incompatible.',
|
|
52
|
-
ARCANE_EVENT_AUTHORITY_PROTOCOL_MISMATCH:
|
|
53
|
-
'globalThis.arcaneEvents uses an incompatible authority protocol.',
|
|
54
|
-
ARCANE_EVENT_AUTHORITY_API_MISMATCH:
|
|
55
|
-
'globalThis.arcaneEvents does not expose the required authority API.',
|
|
56
45
|
ARCANE_EVENT_AUTHORITY_INSTALL_FAILED:
|
|
57
46
|
'The Arcane event authority could not be installed on globalThis.',
|
|
58
47
|
ARCANE_EVENT_SOURCE_INVALID:
|
|
@@ -63,8 +52,6 @@ const ARCANE_EVENT_ERRORS={
|
|
|
63
52
|
'The Arcane event source is disposed.',
|
|
64
53
|
ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED:
|
|
65
54
|
'The Arcane event source cannot publish an undeclared event type.',
|
|
66
|
-
ARCANE_EVENT_COMPATIBILITY_DETAIL_INVALID:
|
|
67
|
-
'Arcane event compatibility detail must be safely shallow-copyable.',
|
|
68
55
|
ARCANE_EVENT_OCCURRENCE_INVALID:
|
|
69
56
|
'The Arcane event occurrence value or creation options are invalid.',
|
|
70
57
|
ARCANE_EVENT_OCCURRENCE_SEQUENCE_EXHAUSTED:
|
|
@@ -74,7 +61,7 @@ const ARCANE_EVENT_ERRORS={
|
|
|
74
61
|
ARCANE_EVENT_LISTENER_CALLBACK_FAILED:
|
|
75
62
|
'An Arcane event listener threw during observational delivery.',
|
|
76
63
|
ARCANE_EVENT_DOM_DETAIL_COLLISION:
|
|
77
|
-
'Arcane DOM projection metadata conflicts with
|
|
64
|
+
'Arcane DOM projection metadata conflicts with source detail.',
|
|
78
65
|
ARCANE_EVENT_DOM_TARGET_INVALID:
|
|
79
66
|
'Arcane DOM projection requires a target with dispatchEvent and CustomEvent support.',
|
|
80
67
|
ARCANE_EVENT_DOM_OPTIONS_INVALID:
|
|
@@ -88,7 +75,7 @@ const ARCANE_EVENT_ERRORS={
|
|
|
88
75
|
ARCANE_EVENT_SUBSCRIPTION_SIGNAL_INVALID:
|
|
89
76
|
'Arcane event subscription signal must be an AbortSignal.',
|
|
90
77
|
ARCANE_EVENT_DISPATCH_EVENT_INVALID:
|
|
91
|
-
'
|
|
78
|
+
'dispatchEvent requires an Event-like object with a valid type and data detail.'
|
|
92
79
|
};
|
|
93
80
|
export const ARCANE_EVENT_ERROR_CODES=Object.fromEntries(
|
|
94
81
|
Object.keys(ARCANE_EVENT_ERRORS).map(code=>[code,code])
|
|
@@ -1345,7 +1332,7 @@ function createArcaneEventAuthority(){
|
|
|
1345
1332
|
const compatibilityByOccurrence=new WeakMap();
|
|
1346
1333
|
const sourceRecordByOccurrence=new WeakMap();
|
|
1347
1334
|
const authorityTargetListeners=[];
|
|
1348
|
-
const
|
|
1335
|
+
const directListeners=[];
|
|
1349
1336
|
let occurrenceSequence=0;
|
|
1350
1337
|
let sourceSequence=0;
|
|
1351
1338
|
let reportingListenerError=false;
|
|
@@ -1664,9 +1651,9 @@ function createArcaneEventAuthority(){
|
|
|
1664
1651
|
record.unsubscribe();
|
|
1665
1652
|
}
|
|
1666
1653
|
|
|
1667
|
-
function dispatchEventLike(value,sourceRecord
|
|
1654
|
+
function dispatchEventLike(value,sourceRecord){
|
|
1668
1655
|
const admitted=eventLikeRecord(value);
|
|
1669
|
-
if(sourceRecord
|
|
1656
|
+
if(!sourceRecord.eventTypes.has(admitted.type)){
|
|
1670
1657
|
throw eventAuthorityError('ARCANE_EVENT_SOURCE_EVENT_TYPE_UNDECLARED');
|
|
1671
1658
|
}
|
|
1672
1659
|
const detail=compatibilityDetail(admitted.detail);
|
|
@@ -1679,8 +1666,8 @@ function createArcaneEventAuthority(){
|
|
|
1679
1666
|
const publication=dispatchOccurrence({
|
|
1680
1667
|
type:admitted.type,
|
|
1681
1668
|
sourceRecord,
|
|
1682
|
-
source:sourceRecord
|
|
1683
|
-
instanceId:sourceRecord
|
|
1669
|
+
source:sourceRecord.source,
|
|
1670
|
+
instanceId:sourceRecord.instanceId,
|
|
1684
1671
|
compatibility:detail,
|
|
1685
1672
|
publicDetail:detail,
|
|
1686
1673
|
operationId,
|
|
@@ -1943,43 +1930,43 @@ function createArcaneEventAuthority(){
|
|
|
1943
1930
|
return accepted&&!occurrence.defaultPrevented;
|
|
1944
1931
|
}
|
|
1945
1932
|
|
|
1946
|
-
function
|
|
1933
|
+
function safeDirectOn(type,handler,once=false){
|
|
1947
1934
|
const admittedType=type==='*'?'*':eventName(type);
|
|
1948
1935
|
const admitted=eventListener(handler);
|
|
1949
1936
|
if(typeof once!=='boolean'){
|
|
1950
1937
|
throw eventAuthorityError('ARCANE_EVENT_SUBSCRIPTION_OPTIONS_INVALID',undefined,TypeError);
|
|
1951
1938
|
}
|
|
1952
1939
|
const record={type:admittedType,identity:admitted.identity,wrapper:null};
|
|
1953
|
-
function
|
|
1954
|
-
if(once)
|
|
1940
|
+
function safeDirectListener(value,...rest){
|
|
1941
|
+
if(once)removeDirectRecord(record);
|
|
1955
1942
|
try{admitted.invoke(value,manager,...rest);}
|
|
1956
1943
|
catch(error){reportListenerFailure(error,null,null);}
|
|
1957
1944
|
}
|
|
1958
|
-
record.wrapper=
|
|
1959
|
-
|
|
1960
|
-
manager[EVENT_MANAGER_BUS_ON](admittedType,
|
|
1945
|
+
record.wrapper=safeDirectListener;
|
|
1946
|
+
directListeners.push(record);
|
|
1947
|
+
manager[EVENT_MANAGER_BUS_ON](admittedType,safeDirectListener);
|
|
1961
1948
|
return manager;
|
|
1962
1949
|
}
|
|
1963
1950
|
|
|
1964
|
-
function
|
|
1965
|
-
const index=
|
|
1951
|
+
function removeDirectRecord(record){
|
|
1952
|
+
const index=directListeners.indexOf(record);
|
|
1966
1953
|
if(index<0)return false;
|
|
1967
|
-
|
|
1954
|
+
directListeners.splice(index,1);
|
|
1968
1955
|
manager[EVENT_MANAGER_BUS_OFF](record.type,record.wrapper);
|
|
1969
1956
|
return true;
|
|
1970
1957
|
}
|
|
1971
1958
|
|
|
1972
|
-
function
|
|
1959
|
+
function safeDirectOff(type='*',handler='*'){
|
|
1973
1960
|
const admittedType=type==='*'?'*':eventName(type);
|
|
1974
|
-
const selected=
|
|
1961
|
+
const selected=directListeners.filter(record=>(admittedType==='*'||record.type===admittedType)
|
|
1975
1962
|
&&(handler==='*'||record.identity===handler));
|
|
1976
1963
|
if(handler!=='*')eventListener(handler);
|
|
1977
|
-
for(const record of selected)
|
|
1964
|
+
for(const record of selected)removeDirectRecord(record);
|
|
1978
1965
|
return manager;
|
|
1979
1966
|
}
|
|
1980
1967
|
|
|
1981
|
-
function
|
|
1982
|
-
for(const record of [...
|
|
1968
|
+
function safeDirectReset(){
|
|
1969
|
+
for(const record of [...directListeners])removeDirectRecord(record);
|
|
1983
1970
|
return manager;
|
|
1984
1971
|
}
|
|
1985
1972
|
|
|
@@ -1987,10 +1974,10 @@ function createArcaneEventAuthority(){
|
|
|
1987
1974
|
[ARCANE_EVENT_AUTHORITY_BRAND]:ARCANE_EVENT_AUTHORITY_PROTOCOL,
|
|
1988
1975
|
protocol:ARCANE_EVENT_AUTHORITY_PROTOCOL,
|
|
1989
1976
|
descriptor,
|
|
1990
|
-
on:
|
|
1991
|
-
once:(type,handler)=>
|
|
1992
|
-
off:
|
|
1993
|
-
reset:
|
|
1977
|
+
on:safeDirectOn,
|
|
1978
|
+
once:(type,handler)=>safeDirectOn(type,handler,true),
|
|
1979
|
+
off:safeDirectOff,
|
|
1980
|
+
reset:safeDirectReset,
|
|
1994
1981
|
subscribe,
|
|
1995
1982
|
createSource,
|
|
1996
1983
|
projectDOMEvent,
|
|
@@ -2007,8 +1994,7 @@ function createArcaneEventAuthority(){
|
|
|
2007
1994
|
},
|
|
2008
1995
|
removeEventListener(type,handler,options){
|
|
2009
1996
|
removeEventTargetListener(authorityTargetListeners,type,handler,options);
|
|
2010
|
-
}
|
|
2011
|
-
dispatchEvent:value=>dispatchEventLike(value)
|
|
1997
|
+
}
|
|
2012
1998
|
});
|
|
2013
1999
|
return manager;
|
|
2014
2000
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.mjs",
|
|
@@ -54,12 +54,11 @@
|
|
|
54
54
|
"test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
|
|
55
55
|
"test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
|
|
56
56
|
"test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/contracts.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
|
|
57
|
-
"test:functional": "node ./bin/arcane-test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-download-resume.test.mjs test/cli.test.mjs test/dbopfs-document-library.test.mjs test/dev-server.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/packaging.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/runtime-api-behavior.test.mjs test/runtime
|
|
57
|
+
"test:functional": "node ./bin/arcane-test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-download-resume.test.mjs test/cli.test.mjs test/dbopfs-document-library.test.mjs test/dev-server.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/packaging.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/site.test.mjs test/update-check.test.mjs",
|
|
58
58
|
"test:integration": "node ./bin/arcane-test.mjs test/integrated-shared.test.mjs test/integrated-workspace.test.mjs test/mail-browser.test.mjs test/native-plan.test.mjs test/native-provider-loader.test.mjs test/npm-release.test.mjs test/release-bundle.test.mjs test/release-capability-smoke.test.mjs test/shared-payload-batch.test.mjs test/tarball.test.mjs test/wllama-webgpu-runtime.test.mjs",
|
|
59
59
|
"test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/native-provider-generation.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
|
|
60
60
|
"check": "node tools/check-source.mjs && npm test",
|
|
61
61
|
"check:release": "node tools/check-source.mjs --package-only && npm run test:release",
|
|
62
|
-
"runtime:sync": "node tools/sync-runtime.mjs",
|
|
63
62
|
"pack:local": "npm pack --ignore-scripts",
|
|
64
63
|
"pack:inspect": "npm pack --dry-run --json",
|
|
65
64
|
"release:pack": "node tools/build-npm-release.mjs",
|
|
@@ -3406,7 +3406,7 @@
|
|
|
3406
3406
|
&&result.disposition!==undefined
|
|
3407
3407
|
&&result.status!==result.disposition
|
|
3408
3408
|
){
|
|
3409
|
-
throw new TypeError('Tool-result status and
|
|
3409
|
+
throw new TypeError('Tool-result status and disposition must match.');
|
|
3410
3410
|
}
|
|
3411
3411
|
const status=result.status??result.disposition;
|
|
3412
3412
|
if(!statuses.has(status)){
|
|
@@ -301,7 +301,6 @@
|
|
|
301
301
|
|| function requestSTTActivation(intent) {
|
|
302
302
|
return requestAIRuntimeIntent(intent);
|
|
303
303
|
};
|
|
304
|
-
host.setAvailability = setAvailability;
|
|
305
304
|
host.setMuted = setMuted;
|
|
306
305
|
host.availability = {
|
|
307
306
|
microphone: Boolean(
|
|
@@ -417,40 +416,15 @@
|
|
|
417
416
|
applyConfiguredMutedState(configuredMuted);
|
|
418
417
|
}
|
|
419
418
|
|
|
420
|
-
if (
|
|
421
|
-
Object.prototype.hasOwnProperty.call(options, 'stt')
|
|
422
|
-
|| Object.prototype.hasOwnProperty.call(options, 'tts')
|
|
423
|
-
|| Object.prototype.hasOwnProperty.call(options, 'microphone')
|
|
424
|
-
) {
|
|
425
|
-
setAvailability(options);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
419
|
return host;
|
|
429
420
|
}
|
|
430
421
|
|
|
431
|
-
function
|
|
422
|
+
function updateMicrophoneAvailability(available) {
|
|
432
423
|
if (destroyed) {
|
|
433
|
-
return
|
|
424
|
+
return;
|
|
434
425
|
}
|
|
435
|
-
// Compatibility-only explicit adapter report. Canonical consumers use
|
|
436
|
-
// the sticky AIRuntimeState role records instead of this wrapper.
|
|
437
|
-
const previousSTTRole = sttRole;
|
|
438
|
-
const previousTTSRole = ttsRole;
|
|
439
426
|
const microphoneWasAvailable = host.availability.microphone;
|
|
440
|
-
|
|
441
|
-
if (Object.prototype.hasOwnProperty.call(input, 'microphone')) {
|
|
442
|
-
host.availability.microphone = Boolean(input.microphone);
|
|
443
|
-
}
|
|
444
|
-
if (Object.prototype.hasOwnProperty.call(input, 'stt')
|
|
445
|
-
&& !Boolean(input.stt)
|
|
446
|
-
&& !selectedRole(sttRole)) {
|
|
447
|
-
sttRole = unavailableRole('stt');
|
|
448
|
-
}
|
|
449
|
-
if (Object.prototype.hasOwnProperty.call(input, 'tts')
|
|
450
|
-
&& !Boolean(input.tts)
|
|
451
|
-
&& !selectedRole(ttsRole)) {
|
|
452
|
-
ttsRole = unavailableRole('tts');
|
|
453
|
-
}
|
|
427
|
+
host.availability.microphone = Boolean(available);
|
|
454
428
|
|
|
455
429
|
if (microphoneWasAvailable && !host.availability.microphone) {
|
|
456
430
|
cancelSTTOperation('microphone-unavailable');
|
|
@@ -462,8 +436,7 @@
|
|
|
462
436
|
) {
|
|
463
437
|
localStatus = null;
|
|
464
438
|
}
|
|
465
|
-
applyRoleTransitions(
|
|
466
|
-
return { ...host.availability };
|
|
439
|
+
applyRoleTransitions(sttRole, ttsRole);
|
|
467
440
|
}
|
|
468
441
|
|
|
469
442
|
function setMuted(muted) {
|
|
@@ -796,10 +769,8 @@
|
|
|
796
769
|
if (destroyed) {
|
|
797
770
|
return;
|
|
798
771
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
microphone: microphonePermissionStatus?.state !== 'denied'
|
|
802
|
-
}
|
|
772
|
+
updateMicrophoneAvailability(
|
|
773
|
+
microphonePermissionStatus?.state !== 'denied'
|
|
803
774
|
);
|
|
804
775
|
}
|
|
805
776
|
|
|
@@ -1265,7 +1236,7 @@
|
|
|
1265
1236
|
owner: 'microphone'
|
|
1266
1237
|
};
|
|
1267
1238
|
if (microphonePermissionStatus?.state === 'denied') {
|
|
1268
|
-
|
|
1239
|
+
updateMicrophoneAvailability(false);
|
|
1269
1240
|
}
|
|
1270
1241
|
dispatchSpeechEvent(
|
|
1271
1242
|
'speech-microphone-unavailable',
|
|
@@ -1323,7 +1294,7 @@
|
|
|
1323
1294
|
const audioContext = new AudioContext();
|
|
1324
1295
|
const source = audioContext.createMediaStreamSource(stream);
|
|
1325
1296
|
|
|
1326
|
-
// ScriptProcessor remains the
|
|
1297
|
+
// ScriptProcessor remains the active silence-detection capture path
|
|
1327
1298
|
// in this increment. AudioWorklet needs its own reviewed protocol.
|
|
1328
1299
|
const processor = audioContext.createScriptProcessor(4096, 1, 1);
|
|
1329
1300
|
session = {
|
|
@@ -1508,7 +1479,6 @@
|
|
|
1508
1479
|
|
|
1509
1480
|
const transcription = await aiRuntime.fetchSTT(
|
|
1510
1481
|
audioFile,
|
|
1511
|
-
undefined,
|
|
1512
1482
|
controller.signal
|
|
1513
1483
|
);
|
|
1514
1484
|
if (
|
|
@@ -605,7 +605,7 @@
|
|
|
605
605
|
error.code='ARCANE_VOICE_TRANSCRIPTION_STT_RUNTIME_METHOD_UNAVAILABLE';
|
|
606
606
|
throw error;
|
|
607
607
|
}
|
|
608
|
-
return globalThis.ai.fetchSTT(file,
|
|
608
|
+
return globalThis.ai.fetchSTT(file,signal);
|
|
609
609
|
}
|
|
610
610
|
|
|
611
611
|
function isTranscriptionCancellation(error,controller){
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Arcane OS shared appearance layer.
|
|
2
|
-
* Load after
|
|
2
|
+
* Load after the shared layout.css (when used) and before primitives or app CSS.
|
|
3
3
|
* Explicit user preferences use data-color-scheme; otherwise the device
|
|
4
4
|
* preference selects the light or dark base.
|
|
5
5
|
*/
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import Is from '../../node_modules/strong-type/index.js';
|
|
2
2
|
import '../modules/DBOPFS.js';
|
|
3
3
|
import '../modules/AI.js';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
hasConversationEntry,
|
|
6
|
+
hasUserEntry,
|
|
7
|
+
recurringChatMessages
|
|
8
|
+
} from '../modules/ChatRecords.js';
|
|
5
9
|
import {normalizeMemoryContent} from '../modules/MemoryRecords.js';
|
|
6
10
|
|
|
7
11
|
const is = new Is(false);
|
|
@@ -454,15 +458,16 @@ class ChatEntity{
|
|
|
454
458
|
/**
|
|
455
459
|
* Returns the current chat message array.
|
|
456
460
|
*
|
|
457
|
-
* This is intended to be passed directly into
|
|
458
|
-
*
|
|
461
|
+
* This is intended to be passed directly into the AI request pipeline.
|
|
462
|
+
* Unresolved structural protocol remains available for its one matching
|
|
463
|
+
* continuation; settled exchanges recur only as ordinary visible content.
|
|
459
464
|
*
|
|
460
465
|
* @returns {Array<*>}
|
|
461
466
|
*/
|
|
462
467
|
get messages(){
|
|
463
468
|
const retainedMessages=retainedChatMessages(this.#messages);
|
|
464
469
|
pendingToolCalls(retainedMessages);
|
|
465
|
-
return retainedMessages
|
|
470
|
+
return recurringChatMessages(retainedMessages)
|
|
466
471
|
.map(function publicChatMessage(message){
|
|
467
472
|
const copy={...message};
|
|
468
473
|
if(copy.tool_calls){
|
|
@@ -548,7 +553,7 @@ class ChatEntity{
|
|
|
548
553
|
* @param {string} text
|
|
549
554
|
* Message content from the user.
|
|
550
555
|
* @param {{hidden?:boolean,persist?:boolean}} options
|
|
551
|
-
* The
|
|
556
|
+
* The hidden option excludes the message from memory extraction without
|
|
552
557
|
* removing it from the complete saved or UI transcript.
|
|
553
558
|
*/
|
|
554
559
|
addUserMessage(text='',{hidden=false,persist=true}={}){
|
|
@@ -633,8 +638,8 @@ class ChatEntity{
|
|
|
633
638
|
|
|
634
639
|
/**
|
|
635
640
|
* Adds an assistant tool call and its result as one hidden, atomic log exchange.
|
|
636
|
-
* The
|
|
637
|
-
*
|
|
641
|
+
* The immediate provider continuation receives the complete exchange. Recurring
|
|
642
|
+
* context and new durable history retain only ordinary user-facing content.
|
|
638
643
|
*/
|
|
639
644
|
addToolExchange({id='',name='',arguments:argumentValue='',result='',persist=true}={}){
|
|
640
645
|
const toolCallId=id;
|