arcane-os 0.5.7 → 0.5.8
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 +9 -0
- package/README.md +14 -7
- package/package.json +1 -1
- package/runtime/arcane/modules/AI.js +70 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.8
|
|
4
|
+
|
|
5
|
+
- Added provider-neutral `reasoningEffort` to `AI.fetchRequest()` and
|
|
6
|
+
`AI.streamRequest()`, accepting `none`, `low`, `medium`, `high`, or
|
|
7
|
+
`max`. TWiN Cloud forwards an explicit value as `reasoning_effort`, omits
|
|
8
|
+
the field when unspecified, and preserves explicit
|
|
9
|
+
`openai-gpt-oss-120b` or `openai-gpt-oss-20b` model selection with the
|
|
10
|
+
existing streaming and structural-tool behavior.
|
|
11
|
+
|
|
3
12
|
## 0.5.7
|
|
4
13
|
|
|
5
14
|
- Added `PersistentAIChatSession.open()` for model-authored conversation
|
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 preserve the same app URLs, theme, packaging,
|
|
20
20
|
event, cancellation, and browser run contracts.
|
|
21
21
|
|
|
22
|
-
This checkout defines the `0.5.
|
|
22
|
+
This checkout defines the `0.5.8` 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
|
|
|
@@ -93,6 +93,13 @@ on device: Whisper (`LOCAL_SPEACH` / `whisper-small`) owns transcription and
|
|
|
93
93
|
Kokoro (`LOCAL_SPEACH` / `kokoro`) owns speech synthesis. Neither audio route
|
|
94
94
|
uses the TWiN key, and no OpenAI audio key is required.
|
|
95
95
|
|
|
96
|
+
`fetchRequest()` and `streamRequest()` accept the provider-neutral
|
|
97
|
+
`reasoningEffort` option with `none`, `low`, `medium`, `high`, or `max`. TWiN
|
|
98
|
+
Cloud maps it to DigitalOcean Serverless Inference `reasoning_effort`; omitting
|
|
99
|
+
it preserves the provider default. TWiN Cloud defaults to
|
|
100
|
+
`openai-gpt-oss-120b`, and applications may explicitly select
|
|
101
|
+
`openai-gpt-oss-20b` without changing streaming or structural-tool behavior.
|
|
102
|
+
|
|
96
103
|
## Browser-local AI
|
|
97
104
|
|
|
98
105
|
`arcane-os/ai/browser-wasm` provides the shared Wllama LLM provider. The app
|
|
@@ -192,7 +199,7 @@ uses the same controller for automatic memory extraction.
|
|
|
192
199
|
Create a new repository-shaped Arcane application with the exact stable SDK:
|
|
193
200
|
|
|
194
201
|
```bash
|
|
195
|
-
npx arcane-os@0.5.
|
|
202
|
+
npx arcane-os@0.5.8 new my-app --path ./my-app --target portable --git
|
|
196
203
|
cd my-app
|
|
197
204
|
npm install
|
|
198
205
|
npm run check
|
|
@@ -203,7 +210,7 @@ To enroll an existing repository, install the exact SDK and initialize only
|
|
|
203
210
|
missing Arcane files:
|
|
204
211
|
|
|
205
212
|
```bash
|
|
206
|
-
npm install --save-dev --save-exact arcane-os@0.5.
|
|
213
|
+
npm install --save-dev --save-exact arcane-os@0.5.8
|
|
207
214
|
npm exec -- arcane init my-app --target portable
|
|
208
215
|
```
|
|
209
216
|
|
|
@@ -219,7 +226,7 @@ npm exec -- arcane-os targets
|
|
|
219
226
|
No global SDK install or standalone Arcane CLI is required. The application
|
|
220
227
|
repository's exact npm dependency and lockfile own the CLI and toolchain version.
|
|
221
228
|
|
|
222
|
-
Use `npx arcane-os@0.5.
|
|
229
|
+
Use `npx arcane-os@0.5.8` for the initial bootstrap because it names this npm
|
|
223
230
|
package explicitly; bare `npx arcane` outside an installed project could resolve
|
|
224
231
|
a different package. Both installed commands invoke the same headless toolchain.
|
|
225
232
|
Project-local npm scripts use the SDK pinned by that app's `package-lock.json`,
|
|
@@ -240,7 +247,7 @@ node ./bin/arcane.mjs new local-app --path ../local-app --target portable --git
|
|
|
240
247
|
|
|
241
248
|
# From the generated app repository
|
|
242
249
|
cd ../local-app
|
|
243
|
-
npm install --save-dev --save-exact ../arcane-os-sdk/arcane-os-0.5.
|
|
250
|
+
npm install --save-dev --save-exact ../arcane-os-sdk/arcane-os-0.5.8.tgz
|
|
244
251
|
npm run check
|
|
245
252
|
npm ci
|
|
246
253
|
```
|
|
@@ -250,7 +257,7 @@ same location. The lockfile retains the selected package dependency while
|
|
|
250
257
|
Arcane uses the installed package name and version. Local directory `file:` dependencies are not
|
|
251
258
|
accepted because npm may install them as links; use a packed `.tgz`. A GitHub
|
|
252
259
|
runner also needs that tarball at the locked path. After publication, replace
|
|
253
|
-
the local declaration with the exact `arcane-os@0.5.
|
|
260
|
+
the local declaration with the exact `arcane-os@0.5.8` registry package and
|
|
254
261
|
commit the regenerated lock.
|
|
255
262
|
|
|
256
263
|
Generated repositories use `npm ci --ignore-scripts` in CI. Run dependency
|
|
@@ -388,7 +395,7 @@ package installation, or assertions.
|
|
|
388
395
|
|
|
389
396
|
## Current target support
|
|
390
397
|
|
|
391
|
-
Version `0.5.
|
|
398
|
+
Version `0.5.8` exposes one browser target and five explicitly paired
|
|
392
399
|
native development targets: a non-runnable portable directory, a
|
|
393
400
|
Windows x64 unsigned-local-test EXE bundle, Linux x64 and Linux ARM64
|
|
394
401
|
unsigned-local-test DEBs, and an Android development-signed APK. The
|
package/package.json
CHANGED
|
@@ -30,6 +30,7 @@ const TTS_ANY_PUNCTUATION_AT_END=/(?<!\p{P})(?:(?<![\p{L}\p{N}])\p{P}+|\p{P}+(?!
|
|
|
30
30
|
credentials='omit';
|
|
31
31
|
|
|
32
32
|
const LEGACY_AI_SERVICES=new Set(['OPENAI','OLLAMA','LOCAL_SPEACH']);
|
|
33
|
+
const AI_REASONING_EFFORTS=new Set(['none','low','medium','high','max']);
|
|
33
34
|
export const AI_READY_EVENT='ai-ready';
|
|
34
35
|
const AI_TTS_FAILURE_EVENT='ai-tts-failure';
|
|
35
36
|
export const AI_INITIALIZATION_ERROR_CODES=completeValue({
|
|
@@ -128,6 +129,20 @@ function normalizeAIRequestAbort(error){
|
|
|
128
129
|
return normalized;
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
function normalizeAIReasoningEffort(value){
|
|
133
|
+
if(value===undefined||value===null||value===''){
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
136
|
+
if(typeof value!=='string'||!AI_REASONING_EFFORTS.has(value)){
|
|
137
|
+
const error=new TypeError(
|
|
138
|
+
'AI reasoningEffort must be none, low, medium, high, or max.'
|
|
139
|
+
);
|
|
140
|
+
error.code='AI_REASONING_EFFORT_INVALID';
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
return value;
|
|
144
|
+
}
|
|
145
|
+
|
|
131
146
|
function legacyAIProviderError(message,code,cause){
|
|
132
147
|
const error=cause===undefined
|
|
133
148
|
?new Error(message)
|
|
@@ -2000,7 +2015,7 @@ class AI {
|
|
|
2000
2015
|
||model;
|
|
2001
2016
|
}
|
|
2002
2017
|
if(service==='OPENAI'){
|
|
2003
|
-
return this.#models.OPENAI;
|
|
2018
|
+
return model==='OPENAI'?this.#models.OPENAI:model;
|
|
2004
2019
|
}
|
|
2005
2020
|
return model;
|
|
2006
2021
|
}
|
|
@@ -4126,7 +4141,8 @@ class AI {
|
|
|
4126
4141
|
parallelToolCalls,
|
|
4127
4142
|
payload.id??Date.now(),
|
|
4128
4143
|
function ignoreLegacyLLMProviderRequest(){},
|
|
4129
|
-
signal
|
|
4144
|
+
signal,
|
|
4145
|
+
payload.reasoningEffort
|
|
4130
4146
|
);
|
|
4131
4147
|
}
|
|
4132
4148
|
|
|
@@ -4153,7 +4169,9 @@ class AI {
|
|
|
4153
4169
|
payload.structuredOutput??false,
|
|
4154
4170
|
false,
|
|
4155
4171
|
true,
|
|
4156
|
-
emitLegacyLLMStreamData
|
|
4172
|
+
emitLegacyLLMStreamData,
|
|
4173
|
+
function ignoreLegacyLLMStreamResult(){},
|
|
4174
|
+
payload.reasoningEffort
|
|
4157
4175
|
);
|
|
4158
4176
|
}
|
|
4159
4177
|
|
|
@@ -4323,9 +4341,13 @@ class AI {
|
|
|
4323
4341
|
minP,
|
|
4324
4342
|
seed,
|
|
4325
4343
|
stop,
|
|
4326
|
-
templateOptions
|
|
4344
|
+
templateOptions,
|
|
4345
|
+
reasoningEffort
|
|
4327
4346
|
}={}){
|
|
4328
4347
|
validateAIStructuralRequest(messages,tools,parallelToolCalls);
|
|
4348
|
+
const normalizedReasoningEffort=normalizeAIReasoningEffort(
|
|
4349
|
+
reasoningEffort===undefined?this.reasoningEffort:reasoningEffort
|
|
4350
|
+
);
|
|
4329
4351
|
if(localOnly!==true&&localOnly!==false){
|
|
4330
4352
|
throw new TypeError('AI localOnly must be a boolean.');
|
|
4331
4353
|
}
|
|
@@ -4355,7 +4377,10 @@ class AI {
|
|
|
4355
4377
|
...(minP!==undefined?{minP}:{}),
|
|
4356
4378
|
...(seed!==undefined?{seed}:{}),
|
|
4357
4379
|
...(stop!==undefined?{stop}:{}),
|
|
4358
|
-
...(templateOptions!==undefined?{templateOptions}:{})
|
|
4380
|
+
...(templateOptions!==undefined?{templateOptions}:{}),
|
|
4381
|
+
...(normalizedReasoningEffort
|
|
4382
|
+
?{reasoningEffort:normalizedReasoningEffort}
|
|
4383
|
+
:{})
|
|
4359
4384
|
};
|
|
4360
4385
|
const displayId=`M-${id}`;
|
|
4361
4386
|
let handle=null;
|
|
@@ -4457,7 +4482,8 @@ class AI {
|
|
|
4457
4482
|
false,
|
|
4458
4483
|
true,
|
|
4459
4484
|
onDataChunk,
|
|
4460
|
-
onDataResult
|
|
4485
|
+
onDataResult,
|
|
4486
|
+
normalizedReasoningEffort
|
|
4461
4487
|
);
|
|
4462
4488
|
const structuralToolCalls=normalizeAICompletionToolCalls(
|
|
4463
4489
|
completion
|
|
@@ -4563,7 +4589,8 @@ class AI {
|
|
|
4563
4589
|
finishSpeech=true,
|
|
4564
4590
|
returnCompletion=false,
|
|
4565
4591
|
dataChunkHandler=function ignoreLegacyStreamDataChunk(){},
|
|
4566
|
-
dataResultHandler=function ignoreLegacyStreamDataResult(){}
|
|
4592
|
+
dataResultHandler=function ignoreLegacyStreamDataResult(){},
|
|
4593
|
+
reasoningEffort
|
|
4567
4594
|
){
|
|
4568
4595
|
let speechTurnCompleted=false;
|
|
4569
4596
|
|
|
@@ -4583,6 +4610,9 @@ class AI {
|
|
|
4583
4610
|
structuredOutput
|
|
4584
4611
|
);
|
|
4585
4612
|
|
|
4613
|
+
const normalizedReasoningEffort=normalizeAIReasoningEffort(
|
|
4614
|
+
reasoningEffort===undefined?this.reasoningEffort:reasoningEffort
|
|
4615
|
+
);
|
|
4586
4616
|
const request={
|
|
4587
4617
|
model:this.model,
|
|
4588
4618
|
messages:messages,
|
|
@@ -4603,8 +4633,11 @@ class AI {
|
|
|
4603
4633
|
}
|
|
4604
4634
|
}
|
|
4605
4635
|
|
|
4606
|
-
if(
|
|
4607
|
-
|
|
4636
|
+
if(
|
|
4637
|
+
normalizedReasoningEffort
|
|
4638
|
+
&&(this.llmService==='OPENAI'||this.llmService==='OLLAMA')
|
|
4639
|
+
){
|
|
4640
|
+
request.reasoning_effort=normalizedReasoningEffort;
|
|
4608
4641
|
}
|
|
4609
4642
|
|
|
4610
4643
|
let isThinking=true;
|
|
@@ -4631,7 +4664,9 @@ class AI {
|
|
|
4631
4664
|
model:this.model,
|
|
4632
4665
|
messages:ollamaMessages,
|
|
4633
4666
|
stream:true,
|
|
4634
|
-
...(
|
|
4667
|
+
...(normalizedReasoningEffort
|
|
4668
|
+
?{think:normalizedReasoningEffort}
|
|
4669
|
+
:{}),
|
|
4635
4670
|
...(structuredOutputFormat?{format:structuredOutputFormat}:{}),
|
|
4636
4671
|
...(ollamaTools.length?{tools:ollamaTools}:{})
|
|
4637
4672
|
};
|
|
@@ -5272,9 +5307,13 @@ class AI {
|
|
|
5272
5307
|
minP,
|
|
5273
5308
|
seed,
|
|
5274
5309
|
stop,
|
|
5275
|
-
templateOptions
|
|
5310
|
+
templateOptions,
|
|
5311
|
+
reasoningEffort
|
|
5276
5312
|
}={}){
|
|
5277
5313
|
validateAIStructuralRequest(messages,tools,parallelToolCalls);
|
|
5314
|
+
const normalizedReasoningEffort=normalizeAIReasoningEffort(
|
|
5315
|
+
reasoningEffort===undefined?this.reasoningEffort:reasoningEffort
|
|
5316
|
+
);
|
|
5278
5317
|
if(localOnly!==true&&localOnly!==false){
|
|
5279
5318
|
throw new TypeError('AI localOnly must be a boolean.');
|
|
5280
5319
|
}
|
|
@@ -5306,7 +5345,10 @@ class AI {
|
|
|
5306
5345
|
...(minP!==undefined?{minP}:{}),
|
|
5307
5346
|
...(seed!==undefined?{seed}:{}),
|
|
5308
5347
|
...(stop!==undefined?{stop}:{}),
|
|
5309
|
-
...(templateOptions!==undefined?{templateOptions}:{})
|
|
5348
|
+
...(templateOptions!==undefined?{templateOptions}:{}),
|
|
5349
|
+
...(normalizedReasoningEffort
|
|
5350
|
+
?{reasoningEffort:normalizedReasoningEffort}
|
|
5351
|
+
:{})
|
|
5310
5352
|
};
|
|
5311
5353
|
await this.#reportRequest(onRequest,request,id);
|
|
5312
5354
|
if(signal?.aborted){
|
|
@@ -5332,7 +5374,7 @@ class AI {
|
|
|
5332
5374
|
return response;
|
|
5333
5375
|
}
|
|
5334
5376
|
|
|
5335
|
-
return this
|
|
5377
|
+
return this.#fetchLegacy(
|
|
5336
5378
|
messages,
|
|
5337
5379
|
onResponse,
|
|
5338
5380
|
structuredOutput,
|
|
@@ -5341,7 +5383,8 @@ class AI {
|
|
|
5341
5383
|
parallelToolCalls,
|
|
5342
5384
|
id,
|
|
5343
5385
|
onRequest,
|
|
5344
|
-
signal
|
|
5386
|
+
signal,
|
|
5387
|
+
normalizedReasoningEffort
|
|
5345
5388
|
);
|
|
5346
5389
|
}
|
|
5347
5390
|
|
|
@@ -5354,7 +5397,7 @@ class AI {
|
|
|
5354
5397
|
parallel_tool_calls,
|
|
5355
5398
|
id=Date.now(),
|
|
5356
5399
|
requestHandler=function ignoreFetchRequest(){},
|
|
5357
|
-
signal=null
|
|
5400
|
+
signal=null
|
|
5358
5401
|
){
|
|
5359
5402
|
if(this.#shouldUseProviderRuntime('llm',this.llmService,false)){
|
|
5360
5403
|
return this.fetchRequest({
|
|
@@ -5394,6 +5437,7 @@ class AI {
|
|
|
5394
5437
|
id=Date.now(),
|
|
5395
5438
|
requestHandler=function ignoreFetchRequest(){},
|
|
5396
5439
|
signal=null,
|
|
5440
|
+
reasoningEffort
|
|
5397
5441
|
){
|
|
5398
5442
|
validateAIStructuralRequest(messages,tools,parallel_tool_calls);
|
|
5399
5443
|
this.#assertServiceConfigured(this.llmService);
|
|
@@ -5408,6 +5452,9 @@ class AI {
|
|
|
5408
5452
|
}
|
|
5409
5453
|
const structuredOutputFormat=this.#structuredOutputFormat(structuredOutput);
|
|
5410
5454
|
|
|
5455
|
+
const normalizedReasoningEffort=normalizeAIReasoningEffort(
|
|
5456
|
+
reasoningEffort===undefined?this.reasoningEffort:reasoningEffort
|
|
5457
|
+
);
|
|
5411
5458
|
const request={
|
|
5412
5459
|
model:this.model,
|
|
5413
5460
|
messages:messages,
|
|
@@ -5428,8 +5475,11 @@ class AI {
|
|
|
5428
5475
|
}
|
|
5429
5476
|
}
|
|
5430
5477
|
|
|
5431
|
-
if(
|
|
5432
|
-
|
|
5478
|
+
if(
|
|
5479
|
+
normalizedReasoningEffort
|
|
5480
|
+
&&(this.llmService==='OPENAI'||this.llmService==='OLLAMA')
|
|
5481
|
+
){
|
|
5482
|
+
request.reasoning_effort=normalizedReasoningEffort;
|
|
5433
5483
|
}
|
|
5434
5484
|
|
|
5435
5485
|
const nativeOllama=this.#nativeOllama();
|
|
@@ -5448,7 +5498,9 @@ class AI {
|
|
|
5448
5498
|
model:this.model,
|
|
5449
5499
|
messages:ollamaMessages,
|
|
5450
5500
|
stream:false,
|
|
5451
|
-
...(
|
|
5501
|
+
...(normalizedReasoningEffort
|
|
5502
|
+
?{think:normalizedReasoningEffort}
|
|
5503
|
+
:{}),
|
|
5452
5504
|
...(structuredOutputFormat?{format:structuredOutputFormat}:{}),
|
|
5453
5505
|
...(ollamaTools.length?{tools:ollamaTools}:{})
|
|
5454
5506
|
};
|