arcane-os 0.64.0 → 0.65.0
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 +26 -0
- package/README.md +1 -1
- package/browser-runtime/core/client.mjs +62 -5
- package/docs/guides/native-whisper-openvino.md +334 -0
- package/docs/reference/README.md +4 -0
- package/docs/reference/arcane-ollama.md +1 -1
- package/docs/reference/codex-app-server.md +269 -0
- package/docs/reference/core-client.md +60 -2
- package/docs/reference/core-development.md +157 -0
- package/docs/reference/core-native-packaging.md +13 -0
- package/docs/reference/core-repositories.md +112 -3
- package/docs/reference/inventory/package-api.json +143 -3
- package/docs/reference/inventory/runtime-modules.json +3 -2
- package/docs/reference/local-ai.md +73 -3
- package/docs/reference/local-image-generation.md +5 -0
- package/docs/reference/local-image-sdxl.md +1 -1
- package/docs/reference/mcp-stdio.md +263 -0
- package/docs/reference/runtime-components.md +18 -1
- package/docs/reference/runtime-modules.md +10 -2
- package/docs/reference/sdk-api.md +251 -1
- package/package.json +6 -2
- package/runtime/arcane/modules/AI.js +156 -13
- package/runtime/arcane/modules/Ollama.js +1 -1
- package/runtime/arcane/modules/OllamaModelIdentifier.js +13 -0
- package/schemas/arcane-app.schema.json +8 -1
- package/schemas/arcane-package.schema.json +8 -1
- package/src/codex/app-server.mjs +845 -0
- package/src/core/development.mjs +457 -0
- package/src/core/repositories.mjs +170 -5
- package/src/core/services/local-ai.mjs +80 -10
- package/src/dev-server.mjs +3 -2
- package/src/index.mjs +1 -0
- package/src/local-ai/dev.mjs +80 -426
- package/src/local-ai/whisper/config.mjs +31 -3
- package/src/local-ai/whisper/index.mjs +62 -5
- package/src/local-ai/whisper/install.mjs +72 -14
- package/src/local-ai/whisper/native/main.cpp +33 -2
- package/src/local-ai/whisper/openvino-build.mjs +138 -0
- package/src/mcp/stdio-server.mjs +579 -0
- package/src/native/portable-layout.mjs +3 -1
- package/src/toolchain.mjs +19 -8
|
@@ -208,17 +208,54 @@ export function createLocalAIService(configuration, {appRoot, runtimes = [], sig
|
|
|
208
208
|
publish();
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
function beginOllamaObservation(engine) {
|
|
212
|
+
return {revision: ++engine.ollamaRevision, signal: engine.signal};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function ownsOllamaObservation(engine, observation) {
|
|
216
|
+
return observation.signal === engine.signal && !observation.signal.aborted
|
|
217
|
+
&& engine.server.current.available && observation.revision >= engine.ollamaAppliedRevision;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function recordOllamaFailure(engine, error, observation) {
|
|
221
|
+
if (!ownsOllamaObservation(engine, observation)) return;
|
|
222
|
+
engine.ollamaAppliedRevision = observation.revision;
|
|
223
|
+
recordFailure(engine, error);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function recordOllamaModels(engine, catalog, running, observation) {
|
|
227
|
+
if (!ownsOllamaObservation(engine, observation)) return;
|
|
228
|
+
engine.ollamaAppliedRevision = observation.revision;
|
|
229
|
+
engine.state = {...engine.state, ...engine.server.current, error: null};
|
|
230
|
+
const resident = new Map((running.models ?? []).map(function residentModel(model) {
|
|
231
|
+
return [model.model ?? model.name, model];
|
|
232
|
+
}));
|
|
233
|
+
const models = new Map((catalog.models ?? []).map(function catalogModel(model) {
|
|
234
|
+
const id = model.model ?? model.name ?? model.id;
|
|
235
|
+
return [id, {...model, id, loaded: resident.has(id)}];
|
|
236
|
+
}));
|
|
237
|
+
for (const [id, model] of resident) {
|
|
238
|
+
if (!models.has(id)) models.set(id, {...model, id, loaded: true});
|
|
239
|
+
}
|
|
240
|
+
engine.models = [...models.values()];
|
|
241
|
+
}
|
|
242
|
+
|
|
211
243
|
async function refreshModels(engine, signal) {
|
|
212
244
|
const revision = engine.revision;
|
|
213
245
|
if (engine.id === 'ollama') {
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
246
|
+
const observation = beginOllamaObservation(engine);
|
|
247
|
+
const observationSignal = signal ? AbortSignal.any([signal, observation.signal]) : observation.signal;
|
|
248
|
+
try {
|
|
249
|
+
const [catalog, running] = await Promise.all([
|
|
250
|
+
requestLocalJSON({url: engine.server.url, path: '/api/tags', signal: observationSignal}),
|
|
251
|
+
requestLocalJSON({url: engine.server.url, path: '/api/ps', signal: observationSignal})
|
|
252
|
+
]);
|
|
253
|
+
observationSignal.throwIfAborted();
|
|
254
|
+
recordOllamaModels(engine, catalog, running, observation);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
if (!observationSignal.aborted) recordOllamaFailure(engine, error, observation);
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
222
259
|
} else {
|
|
223
260
|
const properties = await requestLocalJSON({url: engine.server.url, path: '/props', signal});
|
|
224
261
|
engine.router = properties.role === 'router';
|
|
@@ -427,6 +464,34 @@ export function createLocalAIService(configuration, {appRoot, runtimes = [], sig
|
|
|
427
464
|
|
|
428
465
|
async function ollamaRequest(operation, parameters = {}, request, method = 'POST') {
|
|
429
466
|
const engine = await engineReady('ollama', request.signal);
|
|
467
|
+
const engineSignal = engine.signal;
|
|
468
|
+
const observation = operation === 'ps' ? beginOllamaObservation(engine) : null;
|
|
469
|
+
try {
|
|
470
|
+
const result = await ollamaResponse(engine, operation, parameters, request, method);
|
|
471
|
+
if (operation === 'ps') {
|
|
472
|
+
recordOllamaModels(engine, {models: engine.models}, result, observation);
|
|
473
|
+
publish();
|
|
474
|
+
}
|
|
475
|
+
return result;
|
|
476
|
+
} catch (error) {
|
|
477
|
+
if (operation === 'ps' && !request.signal.aborted) recordOllamaFailure(engine, error, observation);
|
|
478
|
+
throw error;
|
|
479
|
+
} finally {
|
|
480
|
+
// Every owned operation that can change residency/catalog leaves
|
|
481
|
+
// a real upstream observation, including cancellation or failure.
|
|
482
|
+
if (['chat', 'generate', 'embed', 'pull', 'create', 'copy', 'delete'].includes(operation)
|
|
483
|
+
&& engine.signal === engineSignal && !engineSignal.aborted) {
|
|
484
|
+
try {
|
|
485
|
+
await refreshModels(engine, engineSignal);
|
|
486
|
+
} catch {
|
|
487
|
+
// The refresh publishes only its current owned failure;
|
|
488
|
+
// retain the operation's original result or error.
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
async function ollamaResponse(engine, operation, parameters, request, method) {
|
|
430
495
|
const signal = AbortSignal.any([request.signal, engine.signal]);
|
|
431
496
|
const {streamId, ...payload} = parameters;
|
|
432
497
|
if (payload.stream !== true) {
|
|
@@ -472,6 +537,8 @@ export function createLocalAIService(configuration, {appRoot, runtimes = [], sig
|
|
|
472
537
|
function startEngine(engine) {
|
|
473
538
|
engine.controller = new AbortController();
|
|
474
539
|
engine.signal = AbortSignal.any([lifetimeSignal, engine.controller.signal]);
|
|
540
|
+
engine.ollamaRevision = 0;
|
|
541
|
+
engine.ollamaAppliedRevision = 0;
|
|
475
542
|
const signal = engine.signal;
|
|
476
543
|
engine.server = createLocalAIServer({
|
|
477
544
|
id: engine.id, appRoot, runtime: runtimes.find(function runtimeRecord(record) { return record.id === engine.id; }),
|
|
@@ -487,7 +554,10 @@ export function createLocalAIService(configuration, {appRoot, runtimes = [], sig
|
|
|
487
554
|
}
|
|
488
555
|
return engine;
|
|
489
556
|
});
|
|
490
|
-
engine.ready.catch(function startupFailed(error) {
|
|
557
|
+
engine.ready.catch(function startupFailed(error) {
|
|
558
|
+
// Ollama refreshes and the server already publish their own failures.
|
|
559
|
+
if (!signal.aborted && engine.id !== 'ollama') recordFailure(engine, error);
|
|
560
|
+
});
|
|
491
561
|
}
|
|
492
562
|
|
|
493
563
|
const service = {
|
|
@@ -557,7 +627,7 @@ export function createLocalAIService(configuration, {appRoot, runtimes = [], sig
|
|
|
557
627
|
await refreshModels(engine, request.signal);
|
|
558
628
|
} catch (error) {
|
|
559
629
|
request.signal.throwIfAborted();
|
|
560
|
-
recordFailure(engine, error);
|
|
630
|
+
if (engine.id !== 'ollama') recordFailure(engine, error);
|
|
561
631
|
}
|
|
562
632
|
}));
|
|
563
633
|
return snapshot();
|
package/src/dev-server.mjs
CHANGED
|
@@ -855,6 +855,7 @@ async function startOwnedDevServer({
|
|
|
855
855
|
certPath,
|
|
856
856
|
keyPath,
|
|
857
857
|
localAI,
|
|
858
|
+
core = localAI,
|
|
858
859
|
signal,
|
|
859
860
|
sdkRuntimeSourceRoot
|
|
860
861
|
}={},events,releaseSignal){
|
|
@@ -1261,7 +1262,7 @@ async function startOwnedDevServer({
|
|
|
1261
1262
|
response.end();
|
|
1262
1263
|
return;
|
|
1263
1264
|
}
|
|
1264
|
-
if (
|
|
1265
|
+
if (core && await core.handler(request, response)) return;
|
|
1265
1266
|
if(request.method!=='GET'&&request.method!=='HEAD'){
|
|
1266
1267
|
deny(response,405,'Method not allowed.');
|
|
1267
1268
|
return;
|
|
@@ -1558,7 +1559,7 @@ async function startOwnedDevServer({
|
|
|
1558
1559
|
}
|
|
1559
1560
|
if(!closeInitiated){
|
|
1560
1561
|
closeInitiated=true;
|
|
1561
|
-
localAIClosing=Promise.resolve().then(function
|
|
1562
|
+
localAIClosing=Promise.resolve().then(function closeCore(){return core?.close(error);});
|
|
1562
1563
|
localAIClosing.catch(function observeLocalAICloseFailure(closeError){operationalError??=closeError;});
|
|
1563
1564
|
try{
|
|
1564
1565
|
closeDevelopmentListeners(fileServer, tlsServer).then(
|
package/src/index.mjs
CHANGED
|
@@ -146,6 +146,7 @@ export {
|
|
|
146
146
|
} from './workspace.mjs';
|
|
147
147
|
export {materializeInstalledSdkRuntime} from './installed-sdk-runtime.mjs';
|
|
148
148
|
export {startDevServer} from './dev-server.mjs';
|
|
149
|
+
export {createDevelopmentCore} from './core/development.mjs';
|
|
149
150
|
export {startSourceExampleServer} from './source-server.mjs';
|
|
150
151
|
export {acceptWebSocket} from './websocket.mjs';
|
|
151
152
|
export {WS} from '../browser-runtime/websocket-client.mjs';
|