arcane-os 0.66.0 → 0.67.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 +23 -0
- package/README.md +1 -1
- package/browser-runtime/ai/core-image.mjs +84 -34
- package/browser-runtime/ai/core-local.mjs +195 -43
- package/browser-runtime/ai/core-onnx.mjs +71 -12
- package/docs/reference/README.md +1 -0
- package/docs/reference/core-native-packaging.md +11 -4
- package/docs/reference/core-repositories.md +93 -9
- package/docs/reference/core-runtime.md +32 -5
- package/docs/reference/inventory/package-api.json +9 -9
- package/docs/reference/local-ai.md +112 -2
- package/docs/reference/local-image-generation.md +15 -4
- package/docs/reference/model-assets.md +50 -3
- package/docs/reference/native-decisions.md +181 -0
- package/docs/reference/sdk-api.md +55 -12
- package/package.json +5 -2
- package/src/core/repositories.mjs +27 -8
- package/src/core/runtime.mjs +11 -0
- package/src/core/services/decisions.mjs +144 -0
- package/src/core/services/local-ai.mjs +31 -9
- package/src/core/services/model-assets.mjs +98 -13
- package/src/git-identity.mjs +22 -58
- package/src/local-ai/decision-tokenizer-worker.mjs +31 -0
- package/src/local-ai/decision-tokenizer.mjs +109 -0
- package/src/local-ai/decisions.mjs +273 -0
- package/src/local-ai/dev.mjs +8 -2
- package/src/local-ai/onnx-worker.mjs +67 -7
- package/src/local-ai/onnx.mjs +23 -12
- package/src/native/portable-layout.mjs +8 -3
- package/src/repository.mjs +144 -4
|
@@ -199,14 +199,16 @@ ordered `Blob` or `File` members after its resumable download. Range support
|
|
|
199
199
|
allows concurrent transfer within a member; those transfer parts remain the
|
|
200
200
|
store's concern. Use `offline: true` to require an already complete stored model.
|
|
201
201
|
The store does not select or run the image engine. In source development,
|
|
202
|
-
|
|
203
|
-
in [Local AI through Core](local-ai.md#development)
|
|
204
|
-
|
|
202
|
+
use the development Core bootstrap described
|
|
203
|
+
in [Local AI through Core](local-ai.md#development). The accessor can be
|
|
204
|
+
constructed before that client is installed; perform model operations once
|
|
205
|
+
the service is available. Native hosts install their Core client through the
|
|
206
|
+
existing host path.
|
|
205
207
|
An ordinary browser without Core reports local image generation as unavailable.
|
|
206
208
|
|
|
207
209
|
| Member | Contract |
|
|
208
210
|
|---|---|
|
|
209
|
-
| `createCoreImageRuntime({client?, signal?, onEvent?})` |
|
|
211
|
+
| `createCoreImageRuntime({client?, signal?, onEvent?})` | Follows Core installation and lifecycle events by default, asynchronously reading status for each client. An explicit `client`, including `null`, remains caller-owned. It returns immediately. |
|
|
210
212
|
| `load({model, context?, assetProjectionId?, resourcePaths?, signal?})` | Loads the selected model and returns authoritative service state after native completion. `context` supplies native context options. |
|
|
211
213
|
| `generate({model, prompt, parameters?, assetProjectionId?, resourcePaths?, signal?, onProgress?})` | Returns the complete result with `images: [{blob, mediaType, width, height}]`. Additional runtime result metadata remains present. |
|
|
212
214
|
| `unload({signal?})` | Explicitly unloads the shared selected native context and returns its resulting state. |
|
|
@@ -229,6 +231,15 @@ model definitions, including their resource metadata before engine preparation
|
|
|
229
231
|
finishes. Installed files do not imply a loaded model. A late status
|
|
230
232
|
response never overwrites a newer lifecycle event.
|
|
231
233
|
|
|
234
|
+
With `client` omitted, the accessor consumes the shared
|
|
235
|
+
[`subscribeCoreClient`](core-client.md) installation stream. A late installation
|
|
236
|
+
attaches the service listener and reads current status; it never installs an
|
|
237
|
+
engine or loads a model. Retirement or replacement synchronously clears
|
|
238
|
+
readiness and transient `Thinking`, cancels owned requests and detaches the
|
|
239
|
+
retired service listener. Old state, progress and results cannot update the
|
|
240
|
+
replacement connection. `close()` also removes the installation subscription;
|
|
241
|
+
it does not claim that the shared native model was unloaded.
|
|
242
|
+
|
|
232
243
|
Prompts and parameters pass unchanged to the native runtime. Native option
|
|
233
244
|
names, supported model operations and defaults belong to that runtime and the
|
|
234
245
|
selected model definition. A prompt containing U+0000 or an unpaired UTF-16
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Native working files from
|
|
1
|
+
# Native working files from model assets
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Browser preparation and native retain/release ownership were first published in `arcane-os@0.61.0`. Browser
|
|
4
4
|
preparation is exported by `arcane-os/ai/core-model-assets`, and the native
|
|
5
5
|
service by `arcane-os/core/model-assets`. The image example below uses
|
|
6
6
|
`arcane-os/ai/core-image`, published in the same release.
|
|
@@ -87,6 +87,53 @@ cleanup failures remain observable.
|
|
|
87
87
|
|
|
88
88
|
## Native ownership
|
|
89
89
|
|
|
90
|
+
Native services can prepare explicitly selected upstream members without a
|
|
91
|
+
renderer or browser store. Obtain the registered shared service through
|
|
92
|
+
`await context.getService('model-assets')`, then use its native preparation API:
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
const modelAssets = await context.getService('model-assets');
|
|
96
|
+
const projection = await modelAssets.prepare({
|
|
97
|
+
id: selectedOperationId,
|
|
98
|
+
workingDirectory: selectedWorkingDirectory,
|
|
99
|
+
members: selectedMembers, // [{path: 'onnx/model.onnx', url: selectedURL}, ...]
|
|
100
|
+
signal,
|
|
101
|
+
onProgress: renderPreparationProgress
|
|
102
|
+
});
|
|
103
|
+
const use = modelAssets.retain(projection.id);
|
|
104
|
+
await modelAssets.release(projection.id);
|
|
105
|
+
try {
|
|
106
|
+
await ownNativeModelLifetime(use.members);
|
|
107
|
+
} finally {
|
|
108
|
+
// Join actual native unload/worker exit before releasing these files.
|
|
109
|
+
await use.release();
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`prepare({id,workingDirectory,members,signal,onProgress})` performs standard
|
|
114
|
+
fetches only when explicitly called. Every member has its original relative
|
|
115
|
+
`path` and selected `url`; the caller supplies the complete companion-file set.
|
|
116
|
+
Independent members download concurrently. Each complete response stream is
|
|
117
|
+
written directly through the existing ordered native file owner, without a
|
|
118
|
+
whole-model buffer or base64 conversion. No model or runtime is selected or
|
|
119
|
+
downloaded by service startup. The result is the ready projection snapshot with
|
|
120
|
+
ordered `members: [{path,nativePath}]`.
|
|
121
|
+
|
|
122
|
+
Progress uses `open`, `download`, `complete` and `ready` phases, with
|
|
123
|
+
`completed`, `total` and `unit:'files'`; member progress additionally includes
|
|
124
|
+
`memberIndex` and `path`. Progress callbacks may return a promise, which the
|
|
125
|
+
preparation observes. They must not await cleanup of the preparation currently
|
|
126
|
+
calling them. Callback failures remain preparation failures. HTTP failures
|
|
127
|
+
retain `url`, `status` and the complete response text in `response`.
|
|
128
|
+
|
|
129
|
+
`release(id)` relinquishes preparation ownership without a request signal.
|
|
130
|
+
For active native downloads, release or disposal aborts their fetches and joins
|
|
131
|
+
the transfer tasks and native writes before deleting only their owned child
|
|
132
|
+
directory. Preparation cancellation and failure follow that same cleanup path;
|
|
133
|
+
the original failures and cleanup failures remain observable. A native retain
|
|
134
|
+
handle continues to protect completed files through actual engine release.
|
|
135
|
+
Native preparation leaves browser DBOPFS originals and unrelated files alone.
|
|
136
|
+
|
|
90
137
|
```javascript
|
|
91
138
|
import {createModelAssetService} from 'arcane-os/core/model-assets';
|
|
92
139
|
|
|
@@ -103,7 +150,7 @@ try {
|
|
|
103
150
|
```
|
|
104
151
|
|
|
105
152
|
`createModelAssetService({appRoot})` returns a Core service with `current()`,
|
|
106
|
-
`retain(id)` and `dispose()`. `retain()` accepts only a completed projection
|
|
153
|
+
`prepare(options)`, `retain(id)`, `release(id)` and `dispose()`. `retain()` accepts only a completed projection
|
|
107
154
|
and returns `{id,directory,members,release}`. A native engine takes this handle
|
|
108
155
|
before loading and releases it after actual unload, failed-load cleanup or
|
|
109
156
|
worker exit. A rejected inference/load promise alone does not establish native
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Native Laya typed decisions
|
|
2
|
+
|
|
3
|
+
`arcane-os/local-ai/decisions` and `arcane-os/core/decisions` run the selected
|
|
4
|
+
Laya FP32 graph through the SDK's existing native ONNX owner. Tokenization runs
|
|
5
|
+
in its own Node Worker. A Core service can load and evaluate decisions without
|
|
6
|
+
a renderer, browser session, WebGPU browser context or chat provider.
|
|
7
|
+
|
|
8
|
+
The application owns the model selection, original state text, questions,
|
|
9
|
+
options and interpretation. The SDK owns model preparation, token framing,
|
|
10
|
+
inference and cleanup. This is option scoring, not a conversational LLM, a
|
|
11
|
+
replacement for a configured chat model or the cloud System One API.
|
|
12
|
+
|
|
13
|
+
## Compose with existing Core services
|
|
14
|
+
|
|
15
|
+
Register a decision service alongside the selected local-AI and model-assets
|
|
16
|
+
services in the application's existing Core runtime:
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import {createNativeDecisionService} from 'arcane-os/core/decisions';
|
|
20
|
+
|
|
21
|
+
const decisions = createNativeDecisionService({
|
|
22
|
+
model: 'onnx-community/laya-typed-decisions-ONNX',
|
|
23
|
+
dtype: 'fp32',
|
|
24
|
+
workingDirectory: '.models/laya'
|
|
25
|
+
}, {appRoot});
|
|
26
|
+
|
|
27
|
+
// Include decisions in the existing createCoreRuntime({services}) selection.
|
|
28
|
+
// That runtime already owns local-ai with ONNX selected and model-assets.
|
|
29
|
+
await runtime.getService('decisions');
|
|
30
|
+
await decisions.load(); // Explicit activation; no model download at registration.
|
|
31
|
+
try {
|
|
32
|
+
const result = await decisions.evaluate([{
|
|
33
|
+
state: 'The moon chef has one kettle and seventeen impatient dragons.',
|
|
34
|
+
question: 'What should the chef prepare?',
|
|
35
|
+
options: ['Tea', 'An inflatable castle']
|
|
36
|
+
}]);
|
|
37
|
+
console.log(result.decisions[0].value);
|
|
38
|
+
} finally {
|
|
39
|
+
await decisions.unload();
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Here `runtime` and `appRoot` are the application's existing Core runtime and
|
|
44
|
+
root. Add the service before starting that runtime; the example does not create
|
|
45
|
+
a second Core host or engine. Development and packaged native compositions
|
|
46
|
+
already register one model-assets service when ONNX is selected. The decision
|
|
47
|
+
service obtains those exact owners with `context.getService('local-ai')`,
|
|
48
|
+
`localAI.getONNXRuntime()` and `context.getService('model-assets')` on explicit
|
|
49
|
+
load. It reacquires the current ONNX owner after a later runtime recovery.
|
|
50
|
+
See [Core composition](core-runtime.md#native-service-composition) and
|
|
51
|
+
[native service owners](local-ai.md#native-service-owners).
|
|
52
|
+
|
|
53
|
+
`createNativeDecisionService(configuration, {appRoot})` defaults its service
|
|
54
|
+
name to `decisions`. It exposes `load`, `evaluate`, `classify` (an alias for
|
|
55
|
+
`evaluate`), `current`, `subscribe`, `unload` and `dispose`, plus Core lifecycle
|
|
56
|
+
`start(context)`. Its RPC methods are:
|
|
57
|
+
|
|
58
|
+
| Method | Parameters and result |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `decisions.status` | Current lifecycle snapshot; does not load anything. |
|
|
61
|
+
| `decisions.load` | Explicit activation; returns the ready lifecycle snapshot. The request signal cancels activation. |
|
|
62
|
+
| `decisions.evaluate` | `{rows, runOptions?}`; returns `{decisions, outputs}`. The request signal cancels the active model operation. |
|
|
63
|
+
| `decisions.unload` | Releases the activation. Service-lifetime cleanup continues after the caller disconnects. |
|
|
64
|
+
|
|
65
|
+
RPC evaluation uses the SDK's existing complete JSON tensor encoding for
|
|
66
|
+
`outputs` at the transport boundary. Direct native evaluation returns native
|
|
67
|
+
typed tensor records. Service notifications use `decisions.state`; direct
|
|
68
|
+
`subscribe(listener, {emitCurrent:true, signal})` replays current state by
|
|
69
|
+
default and returns an unsubscribe function. Startup stores the service
|
|
70
|
+
context only: importing or registering this service starts no tokenizer,
|
|
71
|
+
model download or inference.
|
|
72
|
+
|
|
73
|
+
## Direct native model
|
|
74
|
+
|
|
75
|
+
`createNativeDecisionModel(options)` from `arcane-os/local-ai/decisions` returns
|
|
76
|
+
`{load, evaluate, classify, current, status, subscribe, unload, dispose}`.
|
|
77
|
+
`status` aliases `current`; `classify` aliases `evaluate`. Supply the existing
|
|
78
|
+
native `onnx` owner, plus either the existing `modelAssets` owner and selected
|
|
79
|
+
`workingDirectory`, or caller-owned native files:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
import {createNativeDecisionModel} from 'arcane-os/local-ai/decisions';
|
|
83
|
+
|
|
84
|
+
const decisions = createNativeDecisionModel({
|
|
85
|
+
onnx: localAI.getONNXRuntime(),
|
|
86
|
+
paths: {
|
|
87
|
+
model: selectedGraphPath,
|
|
88
|
+
tokenizer: selectedTokenizerPath,
|
|
89
|
+
tokenizerConfig: selectedTokenizerConfigPath
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
These direct paths are native filesystem paths. Keep the graph's external data
|
|
95
|
+
beside it under the exact filename required by the graph. The Core service
|
|
96
|
+
resolves configured `paths` relative to `appRoot`; it does not copy or remove
|
|
97
|
+
caller-owned files. For SDK-prepared files, the default selected upstream is
|
|
98
|
+
`onnx-community/laya-typed-decisions-ONNX`, revision `main`, with exactly:
|
|
99
|
+
|
|
100
|
+
- `onnx/model.onnx` and `onnx/model.onnx_data`;
|
|
101
|
+
- `tokenizer.json` and `tokenizer_config.json`.
|
|
102
|
+
|
|
103
|
+
`model` selects the upstream Hugging Face repository and `revision` its
|
|
104
|
+
revision. Native preparation performs normal upstream fetches only during
|
|
105
|
+
explicit `load()`. It streams complete members through the existing working
|
|
106
|
+
file owner; it neither vendors the weights nor creates a second persistent
|
|
107
|
+
model store. The approved `@huggingface/tokenizers@0.2.0` dependency reads the
|
|
108
|
+
selected tokenizer files in its Worker. No Transformers or second ONNX runtime
|
|
109
|
+
is loaded by this API.
|
|
110
|
+
|
|
111
|
+
This graph selection requires `dtype:'fp32'`, which is also the default; another
|
|
112
|
+
dtype reports the incompatible selection rather than substituting a graph.
|
|
113
|
+
`sessionOptions` and `runOptions` pass to the existing native ONNX API unchanged.
|
|
114
|
+
`executionPreference` defaults to `gpu` here: actual advertised native GPU
|
|
115
|
+
provider creation is attempted, followed by an honest CPU fallback. Explicit
|
|
116
|
+
`sessionOptions.executionProviders` takes precedence. The underlying generic
|
|
117
|
+
ONNX factory continues to default to CPU. Accepted provider configuration is
|
|
118
|
+
not evidence that GPU nodes executed. Full provider-attempt diagnostics remain
|
|
119
|
+
in `execution`; see [native ONNX sessions](local-ai.md#native-onnx-sessions).
|
|
120
|
+
|
|
121
|
+
## Complete inputs and outputs
|
|
122
|
+
|
|
123
|
+
`evaluate(rows, {signal, runOptions})` requires an explicitly loaded or loading
|
|
124
|
+
activation; it does not silently load an inactive model. Rows retain their
|
|
125
|
+
caller order, complete `state`, `question` and string-array `options`, plus
|
|
126
|
+
optional `type` (`choice`, `score` or `noul`). Additional row fields remain in
|
|
127
|
+
the returned row. Strings are not trimmed, rewritten or clipped. The shared
|
|
128
|
+
browser/native encoding owner constructs only the model's necessary token
|
|
129
|
+
framing; repeated identical state is tokenized once per batch. Tokenization
|
|
130
|
+
and ONNX execution run outside Core's foreground thread.
|
|
131
|
+
|
|
132
|
+
The result is `{decisions, outputs}`. Each decision contains its original
|
|
133
|
+
`row`, complete option `logits`, unrounded raw-softmax `probabilities`,
|
|
134
|
+
`answerIndex` and `value`. `choice` returns the selected complete option;
|
|
135
|
+
`score` returns the probability-weighted zero-based option index; `noul`
|
|
136
|
+
requires `[falseOption, trueOption]` and returns the probability of option 1.
|
|
137
|
+
When the graph actually supplies `act_logits`, action logits, probabilities
|
|
138
|
+
and `actProbability` are also returned. Every named graph output is retained
|
|
139
|
+
as `{type, dims, data}`, including extra tensors and padding. Raw model scores
|
|
140
|
+
are not claimed calibrated confidence. Results do not enter chat history,
|
|
141
|
+
memory extraction or DBOPFS automatically.
|
|
142
|
+
|
|
143
|
+
The model's real graph/context limits still apply. There is no SDK token cap,
|
|
144
|
+
silent chunking or fabricated result aggregation. Native/browser token-ID or
|
|
145
|
+
numerical parity requires execution evidence for the selected tokenizer and
|
|
146
|
+
runtime; sharing the encoding implementation alone does not establish it.
|
|
147
|
+
|
|
148
|
+
## Lifetime and cancellation
|
|
149
|
+
|
|
150
|
+
`current()` returns `{family, model, revision, dtype, state, loaded, busy,
|
|
151
|
+
activeRequests, progress, error, execution}`. States include `unloaded`,
|
|
152
|
+
`loading`, `ready`, `unloading`, `disposing`, `disposed` and `error`. Semantic
|
|
153
|
+
progress includes model preparation, tokenization and evaluation; downloaded
|
|
154
|
+
members report files, not byte progress. Complete technical errors belong in
|
|
155
|
+
developer diagnostics, while the application owns its user-facing status.
|
|
156
|
+
|
|
157
|
+
Concurrent callers share one explicit activation. Cancelling a load or
|
|
158
|
+
evaluation cancels that activation and its outstanding operations, because the
|
|
159
|
+
native session and tokenizer have one owner. Use separately owned models when
|
|
160
|
+
independent cancellation is required. The construction `signal` governs the
|
|
161
|
+
whole model lifetime. `unload()` permits another explicit load after successful
|
|
162
|
+
cleanup; `dispose()` is terminal. Readiness is revoked as disposal begins.
|
|
163
|
+
|
|
164
|
+
Retained model files remain owned until the ONNX and tokenizer Workers really
|
|
165
|
+
exit. A rejected load, inference or termination request alone does not permit
|
|
166
|
+
file deletion. Cleanup joins active operations and native output delivery,
|
|
167
|
+
preserves cleanup errors, then releases only its working projection. It never
|
|
168
|
+
deletes supplied `paths`. A failed ordinary row does not destroy a healthy
|
|
169
|
+
loaded session or cancel sibling evaluations. The ONNX owner's `stopping:true`
|
|
170
|
+
retires decision readiness immediately on terminal Worker failure or shutdown,
|
|
171
|
+
even while its physical `loaded` state remains true pending actual exit. Cancelled or
|
|
172
|
+
retired operations cannot return a successful late result.
|
|
173
|
+
|
|
174
|
+
Shared Node/Worker/filesystem code is portable across Windows, Linux and macOS;
|
|
175
|
+
the selected ONNX Runtime build and provider determine actual platform/device
|
|
176
|
+
availability. Android requires the host's supported native adaptation. Static
|
|
177
|
+
source review and synthetic authored fixtures are not model execution or a
|
|
178
|
+
claim of tested platform, precision or accelerator behavior.
|
|
179
|
+
|
|
180
|
+
Upstream selection: [Laya FP32 model files](https://huggingface.co/onnx-community/laya-typed-decisions-ONNX/tree/main),
|
|
181
|
+
[Tokenizer package](https://www.npmjs.com/package/@huggingface/tokenizers).
|
|
@@ -108,7 +108,7 @@ runtime layouts.
|
|
|
108
108
|
| `arcane-os/pwa` | Nonblocking PWA registration, worker updates, native installation state and a dismissible installation component. |
|
|
109
109
|
| `arcane-os/ai/browser-wasm` | Caller-selected browser-local Wllama inference, complete DBOPFS model storage, streaming, cancellation, and structural tool-call results. |
|
|
110
110
|
| `arcane-os/ai/core-local` | Browser llama.cpp provider through an available Core connection; browser-local Wllama and ONNX remain independently available. |
|
|
111
|
-
| `arcane-os/ai/browser-decisions` | Explicit-load Laya
|
|
111
|
+
| `arcane-os/ai/browser-decisions` | Explicit-load Laya and Julia-1 typed decisions with caller-selected precision through the shared Transformers.js Worker owner. |
|
|
112
112
|
| `arcane-os/ai/tool-text-stream` | Shared selected tool-argument text observer for provider integration. |
|
|
113
113
|
| `arcane-os/ai/twin-cloud` | Stateless chat, System One state/questions and image generation with explicit key/model, complete results and operation-specific retry/cancellation. |
|
|
114
114
|
| `arcane-os/ai/browser-speech` | Caller-selected Whisper/Kokoro, native browser recognition/synthesis, cloud TTS, upstream assets, role lifecycle and cancellation. |
|
|
@@ -3742,11 +3742,19 @@ Runs one fast-forward-only pull after proving the selected repository worktree i
|
|
|
3742
3742
|
### Signature and result
|
|
3743
3743
|
|
|
3744
3744
|
```text
|
|
3745
|
-
async repositoryPull({ workspaceRoot=process.cwd(), signal, onEvent, run=runProcess }={})
|
|
3745
|
+
async repositoryPull({ workspaceRoot=process.cwd(), target, signal, onEvent, run=runProcess }={})
|
|
3746
3746
|
```
|
|
3747
3747
|
|
|
3748
3748
|
Import it from `arcane-os`. The signature above states whether settlement is synchronous or promise-based. The overview and owning group define result authority, side effects, callbacks, events, cancellation, and lifecycle.
|
|
3749
3749
|
|
|
3750
|
+
Optional `target:{remote,ref}` captures exact nonempty native-representable
|
|
3751
|
+
strings before any wait and selects `git pull --ff-only -- <remote> <ref>:`.
|
|
3752
|
+
The current clean branch receives a fast-forward-only integration; the SDK
|
|
3753
|
+
never switches branches, resets or changes configuration. Without a target,
|
|
3754
|
+
the existing configured pull and result remain unchanged. Targeted results
|
|
3755
|
+
add `target`, complete `stdout` and `stderr` to the existing pull result.
|
|
3756
|
+
See [checkout configuration and selected targets](core-repositories.md#existing-checkout-configuration-and-selected-targets).
|
|
3757
|
+
|
|
3750
3758
|
### Availability and normalization
|
|
3751
3759
|
|
|
3752
3760
|
**Node; network-assisted Git.** SDK-normalized inputs, errors, events, and documented result. Deep protocol: [Node ESM](protocols.md).
|
|
@@ -3770,7 +3778,7 @@ Pushes the selected attached branch through the repository's configured remote a
|
|
|
3770
3778
|
### Signature, parameters, and result
|
|
3771
3779
|
|
|
3772
3780
|
```text
|
|
3773
|
-
async repositoryPush({ workspaceRoot=process.cwd(), signal, onEvent, run=runProcess }={})
|
|
3781
|
+
async repositoryPush({ workspaceRoot=process.cwd(), target, signal, onEvent, run=runProcess }={})
|
|
3774
3782
|
```
|
|
3775
3783
|
|
|
3776
3784
|
Import it from `arcane-os`. `workspaceRoot` selects the Git worktree. `signal`
|
|
@@ -3781,10 +3789,16 @@ should keep the default.
|
|
|
3781
3789
|
|
|
3782
3790
|
Before pushing, the SDK runs `git rev-parse --show-toplevel`,
|
|
3783
3791
|
`git branch --show-current`, and `git status --short --branch` in order. It rejects a
|
|
3784
|
-
detached HEAD, then runs plain `git push`; the repository's current branch,
|
|
3792
|
+
detached HEAD, then, without `target`, runs plain `git push`; the repository's current branch,
|
|
3785
3793
|
configured upstream/remote, Git credentials, hooks, and server policy remain
|
|
3786
3794
|
authoritative. Unlike `repositoryPull()`, this function does **not** require a
|
|
3787
|
-
clean worktree. It does not create a commit or
|
|
3795
|
+
clean worktree. It does not create a commit or choose an application destination.
|
|
3796
|
+
Optional `target:{remote,ref}` captures the original nonempty
|
|
3797
|
+
native-representable strings before any wait and runs
|
|
3798
|
+
`git push --no-follow-tags -- <remote> HEAD:<ref>`. This publishes current HEAD
|
|
3799
|
+
to the caller-selected ref without force or implicit configured tag following.
|
|
3800
|
+
It changes no branch or Git configuration; credentials, URL interpretation,
|
|
3801
|
+
hooks and remote rejection remain Git-owned.
|
|
3788
3802
|
|
|
3789
3803
|
The promise resolves to
|
|
3790
3804
|
`{action:'push', repositoryRoot, branch, output}`. `output` is trimmed stdout,
|
|
@@ -3792,6 +3806,9 @@ or trimmed stderr when stdout is empty. A missing Git executable, failed status
|
|
|
3792
3806
|
probe, rejected/nonzero push, cancellation, or event-callback failure rejects
|
|
3793
3807
|
with the normalized process error. Cancellation stops the local process tree;
|
|
3794
3808
|
it cannot prove that a remote accepted no objects before the interruption.
|
|
3809
|
+
Targeted results also contain the captured `target` and complete
|
|
3810
|
+
`stdout`/`stderr`; omitting the target preserves the existing result shape.
|
|
3811
|
+
See [checkout configuration and selected targets](core-repositories.md#existing-checkout-configuration-and-selected-targets).
|
|
3795
3812
|
|
|
3796
3813
|
### Availability and normalization
|
|
3797
3814
|
|
|
@@ -7894,8 +7911,8 @@ explicit existing path. The application owns the remote, branch and Core API.
|
|
|
7894
7911
|
createRepositoryWorkspace({name,directory,dataRoot,remote,branch,gitIdentity,onEvent,run=runProcess}={})
|
|
7895
7912
|
```
|
|
7896
7913
|
|
|
7897
|
-
Returns `{directory,open,status,pull,push,write,close,drain,dispose}`. Construction does
|
|
7898
|
-
no I/O.
|
|
7914
|
+
Returns `{directory,open,status,configuration,pull,push,write,close,drain,dispose}`. Construction does
|
|
7915
|
+
no I/O. Preparing operations accept `{signal}`; a missing or empty destination clones once,
|
|
7899
7916
|
while existing checkout files, branches, remotes and local changes remain intact.
|
|
7900
7917
|
Same-directory calls are ordered within the process. Shutdown drains accepted
|
|
7901
7918
|
work and preserves the checkout. No CLI cwd, launch state, preference, snapshot
|
|
@@ -7908,7 +7925,25 @@ Selected author fields override inherited child author/committer fields;
|
|
|
7908
7925
|
omitted fields remain inherited. Username remains a credential hint, with
|
|
7909
7926
|
authentication owned by ordinary Git and its configured helper.
|
|
7910
7927
|
|
|
7911
|
-
`
|
|
7928
|
+
`configuration({signal})` observes an existing working root without clone,
|
|
7929
|
+
initialization or fetch. It returns `{repositoryRoot,headRef,origin,upstream}`:
|
|
7930
|
+
full symbolic HEAD (including unborn, null when detached), origin URL/pushURL
|
|
7931
|
+
arrays and current branch remote/merge/URL/pushURL arrays. Unset, empty and
|
|
7932
|
+
repeated configuration values remain distinct. These are ordinary configured
|
|
7933
|
+
values, not authentication or endpoint proof, and are not atomic with later
|
|
7934
|
+
operations. Raw stdout is decoded without replacement; unrepresentable text
|
|
7935
|
+
reports `ARCANE_GIT_CONFIGURATION_NOT_TEXT` with full diagnostics.
|
|
7936
|
+
|
|
7937
|
+
`pull({target,signal})`, `push({target,signal})` and
|
|
7938
|
+
`write({files:[{path,content}],message,target,signal})` accept optional
|
|
7939
|
+
`target:{remote,ref}`, captured as original strings at acceptance. The target
|
|
7940
|
+
selects a fast-forward-only pull into the current branch or a non-force push
|
|
7941
|
+
of current HEAD to the selected ref, without switching branches or changing
|
|
7942
|
+
configuration. It is independent of initial-clone `remote`/`branch`; omission
|
|
7943
|
+
preserves ordinary configured behavior. See the [complete configuration and
|
|
7944
|
+
target contract](core-repositories.md#existing-checkout-configuration-and-selected-targets).
|
|
7945
|
+
|
|
7946
|
+
`write` snapshots the exact selected
|
|
7912
7947
|
strings, writes those repository-relative files, commits only their literal
|
|
7913
7948
|
paths and performs an ordinary non-force push. It retains unrelated staged
|
|
7914
7949
|
paths and existing Git filters/hooks. Results and causal failures distinguish
|
|
@@ -9075,14 +9110,19 @@ native installation eligibility and URL-bar promotion.
|
|
|
9075
9110
|
|
|
9076
9111
|
### Overview
|
|
9077
9112
|
|
|
9078
|
-
Creates an explicitly loaded browser model for Laya typed decisions
|
|
9079
|
-
Julia-1
|
|
9113
|
+
Creates an explicitly loaded browser model for Laya typed decisions or
|
|
9114
|
+
Julia-1. Laya defaults to FP16 and Julia to FP32; callers may select `dtype`
|
|
9115
|
+
explicitly. The shared Worker owns Transformers.js loading, full-input
|
|
9080
9116
|
encoding, batched inference, complete results, cancellation and resource lifetime.
|
|
9081
9117
|
Applications own model selection, questions, option meanings and decision policy.
|
|
9082
9118
|
Existing chat and speech providers are unchanged.
|
|
9083
9119
|
|
|
9084
9120
|
### Signature and result
|
|
9085
9121
|
|
|
9122
|
+
```text
|
|
9123
|
+
createBrowserDecisionModel({family,model,revision,device,dtype,runtime}={})
|
|
9124
|
+
```
|
|
9125
|
+
|
|
9086
9126
|
```js
|
|
9087
9127
|
import {createBrowserDecisionModel} from 'arcane-os/ai/browser-decisions';
|
|
9088
9128
|
|
|
@@ -9107,8 +9147,11 @@ precision, tokenization, output meanings, lifecycle and model limitations.
|
|
|
9107
9147
|
### Availability and normalization
|
|
9108
9148
|
|
|
9109
9149
|
Browser module Workers plus the selected Transformers.js backend are required
|
|
9110
|
-
on explicit use. Import and construction do not activate a model.
|
|
9111
|
-
`dtype
|
|
9150
|
+
on explicit use. Import and construction do not activate a model. The optional
|
|
9151
|
+
nonempty `dtype` string defaults to `fp16` for Laya and `fp32` for Julia. An
|
|
9152
|
+
explicit value is forwarded unchanged to the upstream loader; unsupported
|
|
9153
|
+
selections report its failure without precision fallback. For Laya FP32, pass
|
|
9154
|
+
`dtype: 'fp32'`.
|
|
9112
9155
|
Cancellation terminates that client's Worker and rejects its in-flight work.
|
|
9113
9156
|
No decisions are inserted into chat history or durable storage.
|
|
9114
9157
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.67.0",
|
|
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",
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"./core/preferences": "./src/core/services/preferences.mjs",
|
|
70
70
|
"./core/diarization": "./src/diarization/service.mjs",
|
|
71
71
|
"./core/local-ai": "./src/core/services/local-ai.mjs",
|
|
72
|
+
"./core/decisions": "./src/core/services/decisions.mjs",
|
|
72
73
|
"./core/image": "./src/core/services/image.mjs",
|
|
73
74
|
"./core/speech": "./src/core/services/speech.mjs",
|
|
74
75
|
"./core/model-assets": "./src/core/services/model-assets.mjs",
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
"./diarization/build": "./src/diarization/build.mjs",
|
|
77
78
|
"./local-ai": "./src/local-ai/install.mjs",
|
|
78
79
|
"./local-ai/onnx": "./src/local-ai/onnx.mjs",
|
|
80
|
+
"./local-ai/decisions": "./src/local-ai/decisions.mjs",
|
|
79
81
|
"./local-ai/image": "./src/local-ai/image-runtime.mjs",
|
|
80
82
|
"./local-ai/whisper": "./src/local-ai/whisper/index.mjs",
|
|
81
83
|
"./local-ai/whisper/build": "./src/local-ai/whisper/build.mjs",
|
|
@@ -121,7 +123,7 @@
|
|
|
121
123
|
"test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
|
|
122
124
|
"test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
|
|
123
125
|
"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/conversation-closing-report.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/native-windows-icon.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
|
|
124
|
-
"test:functional": "node ./bin/arcane-test.mjs test/ai-ollama-readiness.test.mjs test/core-ollama-lifecycle.test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-decisions.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.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/continuous-voice-capture.test.mjs test/codex-app-server.test.mjs test/mcp-stdio-server.test.mjs test/core-classic-source.test.mjs test/core-client.test.mjs test/core-client-installation.test.mjs test/core-development.test.mjs test/core-host.test.mjs test/core-packaged-web.test.mjs test/core-runtime.test.mjs test/core-stdio.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.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/file-preview.test.mjs test/import-map.test.mjs test/local-image-editing.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/native-module-packaging.test.mjs test/native-module-resource-references.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/rendered-print.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/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/websocket-client-import-map.test.mjs test/websocket.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
126
|
+
"test:functional": "node ./bin/arcane-test.mjs test/ai-ollama-readiness.test.mjs test/core-ollama-lifecycle.test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-decisions.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.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/continuous-voice-capture.test.mjs test/codex-app-server.test.mjs test/mcp-stdio-server.test.mjs test/core-classic-source.test.mjs test/core-client.test.mjs test/core-client-installation.test.mjs test/core-ai-installation.test.mjs test/core-llama-lifecycle.test.mjs test/core-development.test.mjs test/core-host.test.mjs test/core-model-assets.test.mjs test/core-native-services.test.mjs test/core-packaged-web.test.mjs test/core-runtime.test.mjs test/core-stdio.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.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/file-preview.test.mjs test/import-map.test.mjs test/local-image-editing.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/native-decisions.test.mjs test/native-onnx.test.mjs test/native-module-packaging.test.mjs test/native-module-resource-references.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/rendered-print.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/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/websocket-client-import-map.test.mjs test/websocket.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
125
127
|
"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-macos-provider.test.mjs test/native-plan.test.mjs test/native-portable-provider.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",
|
|
126
128
|
"test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/html-import-packaged-script.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",
|
|
127
129
|
"check": "node tools/check-source.mjs && npm test",
|
|
@@ -158,6 +160,7 @@
|
|
|
158
160
|
"tag": "latest"
|
|
159
161
|
},
|
|
160
162
|
"dependencies": {
|
|
163
|
+
"@huggingface/tokenizers": "0.2.0",
|
|
161
164
|
"event-pubsub": "6.1.1",
|
|
162
165
|
"js-queue": "3.1.1",
|
|
163
166
|
"node-http-server": "10.0.0",
|
|
@@ -4,7 +4,8 @@ import path from 'node:path';
|
|
|
4
4
|
import Is from 'strong-type';
|
|
5
5
|
import {ArcaneError, throwIfAborted} from '../errors.mjs';
|
|
6
6
|
import {runProcess} from '../process.mjs';
|
|
7
|
-
import {repositoryPull, repositoryPush,
|
|
7
|
+
import {captureRepositoryTarget, repositoryConfiguration, repositoryPull, repositoryPush,
|
|
8
|
+
repositoryPushArguments, repositoryStatus} from '../repository.mjs';
|
|
8
9
|
import {createGitIdentityRunner} from '../git-identity.mjs';
|
|
9
10
|
|
|
10
11
|
export {readGitIdentity} from '../git-identity.mjs';
|
|
@@ -152,29 +153,46 @@ export function createRepositoryWorkspace(
|
|
|
152
153
|
);
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
function
|
|
156
|
+
function configuration({signal} = {}) {
|
|
157
|
+
return accept(
|
|
158
|
+
function readRepositoryConfiguration() {
|
|
159
|
+
return repositoryConfiguration({workspaceRoot: repositoryDirectory, signal, onEvent, run: execute});
|
|
160
|
+
},
|
|
161
|
+
signal
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function pull({target, signal} = {}) {
|
|
166
|
+
let selectedTarget;
|
|
167
|
+
try { selectedTarget = captureRepositoryTarget(target); }
|
|
168
|
+
catch (error) { return Promise.reject(error); }
|
|
156
169
|
return accept(
|
|
157
170
|
async function pullRepository() {
|
|
158
171
|
await prepare(signal);
|
|
159
|
-
return repositoryPull({workspaceRoot: repositoryDirectory, signal, onEvent, run: execute});
|
|
172
|
+
return repositoryPull({workspaceRoot: repositoryDirectory, target: selectedTarget, signal, onEvent, run: execute});
|
|
160
173
|
},
|
|
161
174
|
signal
|
|
162
175
|
);
|
|
163
176
|
}
|
|
164
177
|
|
|
165
|
-
function push({signal} = {}) {
|
|
178
|
+
function push({target, signal} = {}) {
|
|
179
|
+
let selectedTarget;
|
|
180
|
+
try { selectedTarget = captureRepositoryTarget(target); }
|
|
181
|
+
catch (error) { return Promise.reject(error); }
|
|
166
182
|
return accept(
|
|
167
183
|
async function pushRepository() {
|
|
168
184
|
await prepare(signal);
|
|
169
|
-
return repositoryPush({workspaceRoot: repositoryDirectory, signal, onEvent, run: execute});
|
|
185
|
+
return repositoryPush({workspaceRoot: repositoryDirectory, target: selectedTarget, signal, onEvent, run: execute});
|
|
170
186
|
},
|
|
171
187
|
signal
|
|
172
188
|
);
|
|
173
189
|
}
|
|
174
190
|
|
|
175
|
-
function write({files, message, signal} = {}) {
|
|
191
|
+
function write({files, message, target, signal} = {}) {
|
|
176
192
|
let selectedFiles;
|
|
193
|
+
let selectedTarget;
|
|
177
194
|
try {
|
|
195
|
+
selectedTarget = captureRepositoryTarget(target);
|
|
178
196
|
requireString(message, 'message');
|
|
179
197
|
if (!message.isWellFormed()) throw new TypeError('message cannot be represented completely as UTF-8 text.');
|
|
180
198
|
if (!is.array(files) || files.length === 0) {
|
|
@@ -210,6 +228,7 @@ export function createRepositoryWorkspace(
|
|
|
210
228
|
async function writeRepositoryFiles() {
|
|
211
229
|
const outcome = {
|
|
212
230
|
directory: repositoryDirectory,
|
|
231
|
+
...(selectedTarget === undefined ? {} : {target: {...selectedTarget}}),
|
|
213
232
|
state: 'local',
|
|
214
233
|
stage: 'prepare',
|
|
215
234
|
paths: selectedFiles.map(function selectedPath(file) { return file.path; }),
|
|
@@ -321,7 +340,7 @@ export function createRepositoryWorkspace(
|
|
|
321
340
|
['--literal-pathspecs', 'commit', '--only', '--cleanup=verbatim', '--file', '-', '--', ...outcome.paths],
|
|
322
341
|
commitMessage()
|
|
323
342
|
);
|
|
324
|
-
await executeGit('push',
|
|
343
|
+
await executeGit('push', repositoryPushArguments(selectedTarget));
|
|
325
344
|
outcome.stage = 'complete';
|
|
326
345
|
return outcome;
|
|
327
346
|
} catch (cause) {
|
|
@@ -357,7 +376,7 @@ export function createRepositoryWorkspace(
|
|
|
357
376
|
return closing;
|
|
358
377
|
}
|
|
359
378
|
|
|
360
|
-
return {directory: repositoryDirectory, open, status, pull, push, write, close, drain: close, dispose: close};
|
|
379
|
+
return {directory: repositoryDirectory, open, status, configuration, pull, push, write, close, drain: close, dispose: close};
|
|
361
380
|
}
|
|
362
381
|
|
|
363
382
|
function requireString(value, name) {
|
package/src/core/runtime.mjs
CHANGED
|
@@ -150,11 +150,22 @@ class CoreRuntime {
|
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
async getService(name) {
|
|
154
|
+
if (this.#closing) throw failure('CORE_CLOSING', 'Core is closing.');
|
|
155
|
+
const service = this.#services.get(name);
|
|
156
|
+
if (!service) throw failure('CORE_SERVICE_UNAVAILABLE', `Core service ${String(name)} is not registered.`);
|
|
157
|
+
await this.#startService(service);
|
|
158
|
+
return service.definition;
|
|
159
|
+
}
|
|
160
|
+
|
|
153
161
|
#serviceContext(service) {
|
|
154
162
|
const runtime = this;
|
|
155
163
|
return {
|
|
156
164
|
application: this.#application,
|
|
157
165
|
service: service.name,
|
|
166
|
+
getService(name) {
|
|
167
|
+
return runtime.getService(name);
|
|
168
|
+
},
|
|
158
169
|
emit(event, data) {
|
|
159
170
|
return runtime.emit(event, data);
|
|
160
171
|
}
|