arcane-os 0.34.1 → 0.34.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.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/docs/reference/runtime-components.md +9 -0
- package/package.json +2 -2
- package/runtime/arcane/components/chat.html +29 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.34.2
|
|
4
|
+
|
|
5
|
+
- Remove temporary `persist:false` Chat cards on completion, failure,
|
|
6
|
+
cancellation, destruction and session replacement. Temporary input is not
|
|
7
|
+
restored into the composer after a rejected request.
|
|
8
|
+
- Track each submission's exact created cards, preserving earlier persistent
|
|
9
|
+
cards and newer submissions even when operation identifiers are reused.
|
|
10
|
+
Persistent transcript and draft behavior remain unchanged; existing saved
|
|
11
|
+
history is not migrated or rewritten.
|
|
12
|
+
|
|
3
13
|
## 0.34.1
|
|
4
14
|
|
|
5
15
|
- Honor an optional request-local `model` in `AI.fetchRequest()` and
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
|
|
|
19
19
|
`arcane/` runtime. Both profiles share the theme, packaging, event, cancellation,
|
|
20
20
|
and browser run contracts while retaining their selected application layout.
|
|
21
21
|
|
|
22
|
-
This checkout defines the `0.34.
|
|
22
|
+
This checkout defines the `0.34.2` SDK contract. Applications pin one exact npm
|
|
23
23
|
version and lockfile; registry state is deliberately not baked into application
|
|
24
24
|
artifacts.
|
|
25
25
|
|
|
@@ -413,6 +413,15 @@ the public result term; `disposition` remains an accepted input spelling.
|
|
|
413
413
|
When a submitted turn uses `persist:false`, Chat may show its cards while that
|
|
414
414
|
one operation is active, then removes them when the operation settles; neither
|
|
415
415
|
the input nor response remains in the retained transcript or model context.
|
|
416
|
+
This cleanup also applies to failed, cancelled, detached, or replaced-session
|
|
417
|
+
requests. Temporary input is not restored into the composer, and a temporary
|
|
418
|
+
failure does not become an assistant history card. The request still rejects
|
|
419
|
+
normally and keeps its diagnostic/status reporting. Cleanup owns the exact
|
|
420
|
+
operation's nodes so a completion listener can start another turn safely.
|
|
421
|
+
Submission code passes those card references directly when it creates them;
|
|
422
|
+
reusing an operation identifier never selects earlier conversation cards for
|
|
423
|
+
cleanup or timestamp updates.
|
|
424
|
+
Persistent-turn recovery and existing saved history remain unchanged.
|
|
416
425
|
|
|
417
426
|
For streaming sessions, every provisional structural card and the terminal
|
|
418
427
|
result must preserve the same choice, ordered call position, exact ID, type,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.2",
|
|
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",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
|
|
87
87
|
"test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
|
|
88
88
|
"test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.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",
|
|
89
|
-
"test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/cli.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.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/modal.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.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/speech-playback.test.mjs test/site.test.mjs test/twin-cloud.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
89
|
+
"test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.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/modal.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.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/speech-playback.test.mjs test/site.test.mjs test/twin-cloud.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
90
90
|
"test:integration": "node ./bin/arcane-test.mjs test/installed-package-runtime.test.mjs test/root-app-layout.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/browser-wasm-cpu.test.mjs test/wllama-webgpu-runtime.test.mjs",
|
|
91
91
|
"test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/logging-regression.test.mjs test/markdown-speech.test.mjs test/prepared-speech.test.mjs test/native-provider-generation.test.mjs test/speech-queue-regression.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
|
|
92
92
|
"check": "node tools/check-source.mjs && npm test",
|
|
@@ -3188,15 +3188,12 @@
|
|
|
3188
3188
|
].includes(error?.code);
|
|
3189
3189
|
}
|
|
3190
3190
|
|
|
3191
|
-
function restoreRejectedStructuralDraft(messageId,
|
|
3191
|
+
function restoreRejectedStructuralDraft(messageId,requestMessages,text){
|
|
3192
3192
|
const response=[...chatOutput.children].find(
|
|
3193
3193
|
candidate=>candidate.id===`message-${messageId}`
|
|
3194
3194
|
)||null;
|
|
3195
|
-
const request=[...chatOutput.children].find(
|
|
3196
|
-
candidate=>candidate.dataset.operationId===operationId
|
|
3197
|
-
)||null;
|
|
3198
3195
|
response?.remove();
|
|
3199
|
-
request
|
|
3196
|
+
for(const request of requestMessages) request.remove();
|
|
3200
3197
|
const existing=textArea.value;
|
|
3201
3198
|
if(existing!==text){
|
|
3202
3199
|
textArea.value=existing
|
|
@@ -3206,14 +3203,15 @@
|
|
|
3206
3203
|
textArea.style.height='auto';
|
|
3207
3204
|
textArea.style.height=`${textArea.scrollHeight}px`;
|
|
3208
3205
|
scrollTranscriptToBottom();
|
|
3209
|
-
return Boolean(response||
|
|
3206
|
+
return Boolean(response||requestMessages.length);
|
|
3210
3207
|
}
|
|
3211
3208
|
|
|
3212
3209
|
async function sendMessageThroughBoundSession(
|
|
3213
3210
|
text,
|
|
3214
3211
|
context,
|
|
3215
3212
|
sessionRequest={content:text,role:'user'},
|
|
3216
|
-
perTurnRequest=null
|
|
3213
|
+
perTurnRequest=null,
|
|
3214
|
+
requestMessages=[]
|
|
3217
3215
|
){
|
|
3218
3216
|
const session=boundChatSession;
|
|
3219
3217
|
const bindingGeneration=sessionBindingGeneration;
|
|
@@ -3248,12 +3246,21 @@
|
|
|
3248
3246
|
const streamedStructuralToolCalls=[];
|
|
3249
3247
|
const messageId=`session-${++sessionMessageSequence}`;
|
|
3250
3248
|
const sessionMessageToken=Symbol(messageId);
|
|
3249
|
+
const transientCards=retainTurn?[]:[...requestMessages];
|
|
3250
|
+
function removeTransientSessionCards(){
|
|
3251
|
+
if(!transientCards.length) return;
|
|
3252
|
+
// The submitter supplies only nodes created for this submission.
|
|
3253
|
+
for(const card of transientCards) card.remove();
|
|
3254
|
+
transientCards.length=0;
|
|
3255
|
+
scrollTranscriptToBottom();
|
|
3256
|
+
}
|
|
3251
3257
|
activeSessionMessageToken=sessionMessageToken;
|
|
3252
3258
|
sessionMessagePending=true;
|
|
3253
3259
|
applyAIAvailability(host.aiAvailability);
|
|
3254
3260
|
setSessionStatus('sending','AI is responding…');
|
|
3255
3261
|
try{
|
|
3256
|
-
receivedMessage(host.aiName, '', messageId);
|
|
3262
|
+
const responseCard=receivedMessage(host.aiName, '', messageId);
|
|
3263
|
+
if(!retainTurn) transientCards.push(responseCard);
|
|
3257
3264
|
await streamMessage('',messageId,true);
|
|
3258
3265
|
setMessageProgress(
|
|
3259
3266
|
messageId,
|
|
@@ -3337,9 +3344,6 @@
|
|
|
3337
3344
|
result.message.content,
|
|
3338
3345
|
committedTurn?.response?.timestamp??result.message.timestamp
|
|
3339
3346
|
);
|
|
3340
|
-
const requestMessages=[...chatOutput.children].filter(
|
|
3341
|
-
candidate=>candidate.dataset.operationId===context.operationId
|
|
3342
|
-
);
|
|
3343
3347
|
for(const [index,requestMessage] of requestMessages.entries()){
|
|
3344
3348
|
setTranscriptMessageTimestamp(
|
|
3345
3349
|
requestMessage,
|
|
@@ -3365,10 +3369,8 @@
|
|
|
3365
3369
|
}
|
|
3366
3370
|
setPendingStructuralToolCalls(terminalToolCalls);
|
|
3367
3371
|
}else{
|
|
3368
|
-
|
|
3369
|
-
message.remove();
|
|
3372
|
+
removeTransientSessionCards();
|
|
3370
3373
|
setPendingStructuralToolCalls(previousPendingToolCalls);
|
|
3371
|
-
scrollTranscriptToBottom();
|
|
3372
3374
|
}
|
|
3373
3375
|
setSessionStatus(
|
|
3374
3376
|
pendingStructuralToolMessage?'tool':'ready',
|
|
@@ -3417,16 +3419,13 @@
|
|
|
3417
3419
|
const response=[...chatOutput.children].find(
|
|
3418
3420
|
candidate=>candidate.id===`message-${messageId}`
|
|
3419
3421
|
)||null;
|
|
3420
|
-
const requestMessages=[...chatOutput.children].filter(
|
|
3421
|
-
candidate=>candidate.dataset.operationId===context.operationId
|
|
3422
|
-
);
|
|
3423
3422
|
response?.remove();
|
|
3424
3423
|
for(const requestMessage of requestMessages){
|
|
3425
3424
|
requestMessage.remove();
|
|
3426
3425
|
}
|
|
3427
3426
|
scrollTranscriptToBottom();
|
|
3428
|
-
}else{
|
|
3429
|
-
restoreRejectedStructuralDraft(messageId,
|
|
3427
|
+
}else if(retainTurn){
|
|
3428
|
+
restoreRejectedStructuralDraft(messageId,requestMessages,text);
|
|
3430
3429
|
}
|
|
3431
3430
|
arcaneLogging.error('Arcane structural tool protocol failure.',error);
|
|
3432
3431
|
setSessionStatus(
|
|
@@ -3436,14 +3435,11 @@
|
|
|
3436
3435
|
}else if(!destroyed&&bindingGeneration===sessionBindingGeneration){
|
|
3437
3436
|
arcaneLogging.error('Arcane chat request failed.',error);
|
|
3438
3437
|
if(sessionRequestMessages.every(message=>message.role==='tool')){
|
|
3439
|
-
const requestMessages=[...chatOutput.children].filter(
|
|
3440
|
-
candidate=>candidate.dataset.operationId===context.operationId
|
|
3441
|
-
);
|
|
3442
3438
|
for(const requestMessage of requestMessages){
|
|
3443
3439
|
requestMessage.remove();
|
|
3444
3440
|
}
|
|
3445
3441
|
}
|
|
3446
|
-
renderSessionMessageFailure(messageId,error);
|
|
3442
|
+
if(retainTurn) renderSessionMessageFailure(messageId,error);
|
|
3447
3443
|
setSessionStatus(
|
|
3448
3444
|
'error',
|
|
3449
3445
|
visibleErrorMessage(error,'The AI request failed.')
|
|
@@ -3471,6 +3467,7 @@
|
|
|
3471
3467
|
}
|
|
3472
3468
|
throw error;
|
|
3473
3469
|
}finally{
|
|
3470
|
+
removeTransientSessionCards();
|
|
3474
3471
|
if(activeSessionMessageToken===sessionMessageToken){
|
|
3475
3472
|
activeSessionMessageToken=null;
|
|
3476
3473
|
sessionMessagePending=false;
|
|
@@ -3625,6 +3622,7 @@
|
|
|
3625
3622
|
return false;
|
|
3626
3623
|
}
|
|
3627
3624
|
try{
|
|
3625
|
+
const requestMessages=[];
|
|
3628
3626
|
for(const result of orderedResults){
|
|
3629
3627
|
const visibleMessage=appendTranscriptMessage(
|
|
3630
3628
|
'tool',
|
|
@@ -3633,12 +3631,14 @@
|
|
|
3633
3631
|
);
|
|
3634
3632
|
visibleMessage.dataset.operationId=operationId;
|
|
3635
3633
|
visibleMessage.dataset.toolCallId=result.tool_call_id;
|
|
3634
|
+
requestMessages.push(visibleMessage);
|
|
3636
3635
|
}
|
|
3637
3636
|
const result=sendMessageThroughBoundSession(
|
|
3638
3637
|
orderedResults.map(message=>message.content).join('\n'),
|
|
3639
3638
|
eventContext,
|
|
3640
3639
|
orderedResults,
|
|
3641
|
-
perTurnRequest
|
|
3640
|
+
perTurnRequest,
|
|
3641
|
+
requestMessages
|
|
3642
3642
|
);
|
|
3643
3643
|
return observeHostSubmission(result,eventContext,ownership);
|
|
3644
3644
|
}catch(error){
|
|
@@ -3824,6 +3824,7 @@
|
|
|
3824
3824
|
return false;
|
|
3825
3825
|
}
|
|
3826
3826
|
try{
|
|
3827
|
+
const requestMessages=[];
|
|
3827
3828
|
if(!eventContext.preserveDraft){
|
|
3828
3829
|
textArea.value='';
|
|
3829
3830
|
}
|
|
@@ -3834,6 +3835,7 @@
|
|
|
3834
3835
|
hostSubmissionGeneration++;
|
|
3835
3836
|
const visibleMessage=appendTranscriptMessage('user',text,host.name);
|
|
3836
3837
|
visibleMessage.dataset.operationId=operationId;
|
|
3838
|
+
requestMessages.push(visibleMessage);
|
|
3837
3839
|
}
|
|
3838
3840
|
scrollTranscriptToBottom(!eventContext.synthetic);
|
|
3839
3841
|
|
|
@@ -3854,7 +3856,9 @@
|
|
|
3854
3856
|
let result;
|
|
3855
3857
|
try{
|
|
3856
3858
|
result=boundChatSession
|
|
3857
|
-
?sendMessageThroughBoundSession(
|
|
3859
|
+
?sendMessageThroughBoundSession(
|
|
3860
|
+
text,eventContext,undefined,null,requestMessages
|
|
3861
|
+
)
|
|
3858
3862
|
:host.sendMessage(text,eventContext);
|
|
3859
3863
|
}catch(error){
|
|
3860
3864
|
result=Promise.reject(error);
|