arcane-os 0.83.0 → 0.84.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 +29 -0
- package/README.md +1 -1
- package/docs/reference/core-native-packaging.md +21 -0
- package/docs/reference/core-runtime.md +28 -1
- package/docs/reference/core-shared-host.md +71 -8
- package/docs/reference/inventory/package-api.json +20 -6
- package/docs/reference/local-ai.md +24 -3
- package/docs/reference/native-decisions.md +13 -0
- package/docs/reference/sdk-api.md +87 -3
- package/package.json +1 -1
- package/src/core/host.mjs +1 -1
- package/src/core/runtime-connection.mjs +165 -0
- package/src/core/runtime.mjs +10 -6
- package/src/core/shared-host.mjs +270 -70
- package/src/core/stdio.mjs +18 -3
- package/src/local-ai/onnx-worker.mjs +39 -5
- package/src/local-ai/onnx.mjs +3 -3
- package/src/native/portable-layout.mjs +30 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.84.0
|
|
4
|
+
|
|
5
|
+
- Add `startCoreListener({runtime, endpoint, onError})` through
|
|
6
|
+
`arcane-os/core/host` so local clients can use an application's existing
|
|
7
|
+
window-owned Core without creating another runtime or changing its profile,
|
|
8
|
+
service instances or saved-data location. Native packages select it with
|
|
9
|
+
`native.launchContext.coreListener: {endpoint}`.
|
|
10
|
+
- Keep response correlation, cancellation and current-state replay scoped to
|
|
11
|
+
each connection. Preserve complete application payloads, expose the original
|
|
12
|
+
handler `requestId` and actual internal `coreRequestId`, and prevent retired
|
|
13
|
+
request events from attaching to a later reuse of a client ID.
|
|
14
|
+
- Closing a client or listener leaves accepted service-owned work with its
|
|
15
|
+
runtime. Window shutdown drains Core and then closes its listener. Existing
|
|
16
|
+
explicitly selected headless shared-host behavior remains available. This
|
|
17
|
+
capability does not claim to correct or verify model inference.
|
|
18
|
+
|
|
19
|
+
## 0.83.1
|
|
20
|
+
|
|
21
|
+
- Preserve complete failure-only native ONNX diagnostics in `error.onnxRun`,
|
|
22
|
+
including session and request identity, failure stage, graph metadata,
|
|
23
|
+
provider execution, run options and encoded feed/fetch tensors. Existing
|
|
24
|
+
rejected evaluations and retained decision error state carry the record.
|
|
25
|
+
- Retain the device inventory already consumed by automatic physical selection
|
|
26
|
+
without another hardware query. Successful inference performs no diagnostic
|
|
27
|
+
tensor encoding; original errors and diagnostic-construction failures remain
|
|
28
|
+
observable without changing model inputs, device selection or cancellation.
|
|
29
|
+
- These diagnostics expose evidence for a failed operation; they do not claim
|
|
30
|
+
to correct an application inference failure. No dependency changes.
|
|
31
|
+
|
|
3
32
|
## 0.83.0
|
|
4
33
|
|
|
5
34
|
- Add optional `shadowPath` to native app-control inspection and actions. Follow
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ selected SDK projection or an explicit live SDK source mount. Both profiles
|
|
|
25
25
|
share the theme, packaging, event, cancellation,
|
|
26
26
|
and browser run contracts while retaining their selected application layout.
|
|
27
27
|
|
|
28
|
-
This checkout defines the `0.
|
|
28
|
+
This checkout defines the `0.84.0` SDK contract. Development applications declare
|
|
29
29
|
`arcane-os` as `latest` and retain their lockfile. Exact SDK pins begin when Roshi
|
|
30
30
|
designates a production build. Follow [Consumer updates](docs/consumer-updates.md)
|
|
31
31
|
to refresh and compare the installed SDK and lockfile with the published channel;
|
|
@@ -234,6 +234,27 @@ Windows and macOS launchers use the same packaged defaults for native state
|
|
|
234
234
|
selection, so an ordinary executable launch and external MCP can select the
|
|
235
235
|
same app-owned Core.
|
|
236
236
|
|
|
237
|
+
To expose the actual window-owned Core to an external local client while
|
|
238
|
+
preserving that stdio lifetime, select
|
|
239
|
+
`native.launchContext:{coreListener:{endpoint:"APPLICATION-SELECTED-LOCAL-ENDPOINT"}}`
|
|
240
|
+
instead. The generated entry calls
|
|
241
|
+
`startCoreListener({runtime:host.runtime,endpoint})` after creating its ordinary
|
|
242
|
+
stdio host. It reuses that exact service set and launch context, including the
|
|
243
|
+
existing origin, profile and state root; no headless runtime is created. The
|
|
244
|
+
listener endpoint has no default and its parent directory must already exist
|
|
245
|
+
where required by the operating system. `coreListener` and `sharedHost` are
|
|
246
|
+
alternative selections; supplying both reports `TypeError`.
|
|
247
|
+
|
|
248
|
+
Clients use `connectSharedCoreHost({endpoint})` with `start` omitted and close
|
|
249
|
+
only their own connection. This listener provides no host-shutdown RPC. Closing
|
|
250
|
+
the window still drains its Core, including accepted service-owned operations,
|
|
251
|
+
and then closes the listener. Signal-driven host shutdown remains observed while
|
|
252
|
+
the listener is binding; a bind failure drains the newly created stdio host and
|
|
253
|
+
reports the failure. The generated entry joins listener closure without changing
|
|
254
|
+
the existing shared-host/headless branches. See
|
|
255
|
+
[the existing-runtime listener contract](core-shared-host.md#attach-to-an-existing-window-owned-core)
|
|
256
|
+
for direct composition, correlation, cancellation and complete error behavior.
|
|
257
|
+
|
|
237
258
|
`resolveNativeLaunchContext({appId,context={}})` from `arcane-os/core/host` is
|
|
238
259
|
the public, synchronous location owner for native applications and external MCP.
|
|
239
260
|
It returns a new complete context and fills only omitted fields:
|
|
@@ -67,7 +67,7 @@ complete diagnostic serialization; the startup promise retains its original
|
|
|
67
67
|
rejection value.
|
|
68
68
|
|
|
69
69
|
Each lifecycle hook receives `{application, service, emit, getService}`. Each request handler
|
|
70
|
-
receives `(parameters, {application, service, emit, getService, requestId, signal})`, with
|
|
70
|
+
receives `(parameters, {application, service, emit, getService, requestId, coreRequestId, signal})`, with
|
|
71
71
|
`this` bound to its service definition. A hook or handler may publish a complete
|
|
72
72
|
service-owned event through `emit(event, data)`.
|
|
73
73
|
|
|
@@ -132,6 +132,18 @@ The shared `arcane-os/core/contracts` module owns `CORE_PROTOCOL` (`arcane/1`),
|
|
|
132
132
|
availability errors remain observable; unavailable services are not replaced
|
|
133
133
|
with browser behavior.
|
|
134
134
|
|
|
135
|
+
A transport that assigns internal dispatch IDs may call
|
|
136
|
+
`runtime.handle(frame, {contextRequestId})`. This optional nonempty string sets
|
|
137
|
+
only the service handler's `context.requestId`. `context.coreRequestId` always
|
|
138
|
+
exposes the actual `frame.id`; it distinguishes simultaneous requests whose
|
|
139
|
+
clients selected equal IDs. The supplied `frame.id` still
|
|
140
|
+
owns active-request state, cancellation lookup, response correlation and the
|
|
141
|
+
request event's top-level envelope. Parameters and event data remain unchanged.
|
|
142
|
+
Ordinary `handle(frame)` keeps its existing behavior: `context.requestId` equals
|
|
143
|
+
`frame.id`, and `coreRequestId` equals that same ID. Stdio and
|
|
144
|
+
the borrowed IPC listener use this metadata to preserve the original client ID
|
|
145
|
+
in service-facing data while their transport owner routes unique dispatch IDs.
|
|
146
|
+
|
|
135
147
|
A request with no registered handler retains code `METHOD_NOT_ALLOWED` and
|
|
136
148
|
adds the exact `method`, its first dotted `namespace`, and a `reason`.
|
|
137
149
|
`core-namespace-unavailable` means the dispatcher has neither a service with
|
|
@@ -222,6 +234,21 @@ reach `onError` and reject `closed`. The transport detaches
|
|
|
222
234
|
its listeners and pauses its input; it does not end caller-owned output streams
|
|
223
235
|
or take ownership of the host process.
|
|
224
236
|
|
|
237
|
+
Stdio routes responses and request-context events only for its own requests.
|
|
238
|
+
`request.cancel`, `requests.cancelAll` and `runtime.replay` are connection-scoped;
|
|
239
|
+
they do not cancel or replay another attached connection's work. The protocol
|
|
240
|
+
owner gives every accepted request a fresh internal ID and restores its client
|
|
241
|
+
ID on responses, event envelopes and stdio's own `core.state` entries. Handler
|
|
242
|
+
`context.requestId` and complete application payloads keep their original values.
|
|
243
|
+
Uncorrelated runtime/service events remain shared.
|
|
244
|
+
|
|
245
|
+
`startCoreListener({runtime,endpoint,onError})` from `arcane-os/core/host` can
|
|
246
|
+
attach additional local clients to this same runtime. Its explicit `close()`
|
|
247
|
+
closes only that listener; stdio EOF still closes the runtime and drains all
|
|
248
|
+
accepted service work, then the listener closes automatically. Observe the
|
|
249
|
+
listener's `closed` as well as the stdio owner's `closed` to join both transport
|
|
250
|
+
lifecycles. See [existing-runtime listeners](core-shared-host.md#attach-to-an-existing-window-owned-core).
|
|
251
|
+
|
|
225
252
|
## Platform and delivery boundary
|
|
226
253
|
|
|
227
254
|
These modules use portable Node and JavaScript facilities for Windows, Linux
|
|
@@ -13,6 +13,69 @@ event history. Application methods and policy stay in the application services.
|
|
|
13
13
|
Use the [MCP server](mcp-stdio.md) for external MCP framing; local Core continues
|
|
14
14
|
to use the existing `arcane/1` protocol and Content-Length stream framing.
|
|
15
15
|
|
|
16
|
+
## Attach to an existing window-owned Core
|
|
17
|
+
|
|
18
|
+
`startCoreListener({runtime,endpoint,onError})` adds a local IPC listener to an
|
|
19
|
+
existing Core runtime. It resolves `{endpoint,closed,close}` after binding the
|
|
20
|
+
selected endpoint. It neither constructs nor starts a runtime or service. The
|
|
21
|
+
existing host retains its application, services, origin, profile, state location
|
|
22
|
+
and shutdown ownership.
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import {startCoreListener} from 'arcane-os/core/host';
|
|
26
|
+
|
|
27
|
+
// host is the application's existing startCoreHost/startCoreStdio handle.
|
|
28
|
+
const listener = await startCoreListener({runtime: host.runtime, endpoint: selectedEndpoint});
|
|
29
|
+
try {
|
|
30
|
+
await host.closed;
|
|
31
|
+
} finally {
|
|
32
|
+
await listener.close();
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
An external client uses `connectSharedCoreHost({endpoint: selectedEndpoint})`
|
|
37
|
+
with `start` omitted, invokes the application's existing methods through
|
|
38
|
+
`connection.client.invoke(method, parameters)`, and calls `connection.close()`
|
|
39
|
+
when finished. This connection uses the existing SDK framing, correlation and
|
|
40
|
+
current-runtime replay; it does not launch another Core or replay requests.
|
|
41
|
+
The listener does not implement or intercept `core.host.shutdown`.
|
|
42
|
+
`connection.shutdown()` therefore has no listener-owned shutdown operation;
|
|
43
|
+
without an application method of that name it returns the ordinary
|
|
44
|
+
`METHOD_NOT_ALLOWED` error. The window's host remains the shutdown owner.
|
|
45
|
+
|
|
46
|
+
Disconnect and `listener.close()` cancel only the affected connections'
|
|
47
|
+
request-lifetime work. Explicit listener close drains queued output and releases
|
|
48
|
+
the endpoint without closing the runtime or waiting for accepted service-lifetime
|
|
49
|
+
work; that work remains tracked by its service/runtime owner. When the runtime
|
|
50
|
+
itself begins shutdown, the listener rejects new requests and retains its endpoint
|
|
51
|
+
through runtime drain/disposal, then closes its connections automatically.
|
|
52
|
+
Observe both the host's `closed` and the listener's `closed` for their respective
|
|
53
|
+
completion or failure. `close()` is idempotent. Transport errors reach `onError`
|
|
54
|
+
(complete console diagnostics by default); terminal listener failures reject
|
|
55
|
+
`closed`. Bind failures reject startup with their actual native error and leave
|
|
56
|
+
the supplied runtime alive. A draining/closed runtime rejects attachment with
|
|
57
|
+
`CORE_CLOSING`.
|
|
58
|
+
|
|
59
|
+
Stdio and each IPC connection have independent request correlation and
|
|
60
|
+
cancellation. Handlers reached through stdio or this listener receive the
|
|
61
|
+
original client ID in `context.requestId`; `context.coreRequestId` exposes the
|
|
62
|
+
fresh internal ID used by runtime dispatch and protocol routing. Responses and
|
|
63
|
+
top-level event correlation return to their originating connection. The new listener leaves all event data,
|
|
64
|
+
including any authored `data.requestId`, and all parameters/results unchanged.
|
|
65
|
+
Its runtime-state snapshot retains the runtime's internal active IDs. Late events
|
|
66
|
+
from a retired request never attach to a later reuse of that client's ID.
|
|
67
|
+
Uncorrelated service events remain shared. See the
|
|
68
|
+
[runtime metadata contract](core-runtime.md#state-and-frames).
|
|
69
|
+
|
|
70
|
+
For a generated native entry, select
|
|
71
|
+
`native.launchContext.coreListener:{endpoint}` and omit `sharedHost`. This adds
|
|
72
|
+
the listener to the ordinary window/stdio runtime; closing the native window
|
|
73
|
+
still drains Core. The endpoint is explicit, with no inferred headless startup
|
|
74
|
+
or new default location. Its parent directory must already exist on platforms
|
|
75
|
+
that require one. Selecting both `coreListener` and `sharedHost` reports
|
|
76
|
+
`TypeError` because they select different runtime lifetimes. See
|
|
77
|
+
[native launch locations](core-native-packaging.md#launch-time-locations).
|
|
78
|
+
|
|
16
79
|
## Host entry
|
|
17
80
|
|
|
18
81
|
```js
|
|
@@ -107,8 +170,8 @@ running. `closed` observes connection termination and rejects on a transport
|
|
|
107
170
|
error. A subsequent connection uses the still-running owner. Reconnection is
|
|
108
171
|
explicit; failed or uncertain requests are never resubmitted.
|
|
109
172
|
|
|
110
|
-
`await connection.shutdown(invokeOptions)` explicitly
|
|
111
|
-
`core.host.shutdown` operation. It drains the shared runtime, returns
|
|
173
|
+
For an owning shared host, `await connection.shutdown(invokeOptions)` explicitly
|
|
174
|
+
invokes the host-owned `core.host.shutdown` operation. It drains the shared runtime, returns
|
|
112
175
|
`{state:'closed'}` after successful service cleanup, then closes the connection.
|
|
113
176
|
A drain failure returns the full Core error. Shutdown affects **all** clients
|
|
114
177
|
of that app endpoint and belongs to the application owner's explicit lifecycle,
|
|
@@ -118,8 +181,8 @@ after shutdown acceptance does not undo the shared shutdown.
|
|
|
118
181
|
|
|
119
182
|
## Correlation, events, and state
|
|
120
183
|
|
|
121
|
-
Each connection has its own request-ID space. The
|
|
122
|
-
internal Core request ID and restores the originating ID on responses and
|
|
184
|
+
Each connection has its own request-ID space. The owning shared-host adapter
|
|
185
|
+
substitutes an internal Core request ID and restores the originating ID on responses and
|
|
123
186
|
the optional top-level event `requestId`. Existing `data.requestId` values that
|
|
124
187
|
carry that same Core correlation ID are restored too. `parameters`, returned results, schemas,
|
|
125
188
|
documents, and content remain complete and unchanged. A handler's
|
|
@@ -137,10 +200,10 @@ connection's IDs; other connections' active requests retain Core-side IDs.
|
|
|
137
200
|
requests. A disconnect performs the same scoped cancellation. The underlying
|
|
138
201
|
runtime continues to preserve service-lifetime acceptance.
|
|
139
202
|
|
|
140
|
-
`runtime.replay`
|
|
141
|
-
`core.state`, and `core.service.state` snapshot. Optional
|
|
142
|
-
`getReplayEvents()`
|
|
143
|
-
service owners. It is for current domain state, not historical chunks or
|
|
203
|
+
Both listener forms handle `runtime.replay` by sending only that connection the
|
|
204
|
+
current `core.ready`, `core.state`, and `core.service.state` snapshot. Optional
|
|
205
|
+
synchronous `getReplayEvents()` on the owning shared host returns current
|
|
206
|
+
`{event,data}` records from their actual service owners. It is for current domain state, not historical chunks or
|
|
144
207
|
retired requests. Subscribe before requesting a domain snapshot when its live
|
|
145
208
|
events may change; applications own those domain methods and state.
|
|
146
209
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"sdkVersion": "0.
|
|
3
|
+
"sdkVersion": "0.83.0",
|
|
4
4
|
"environment": {
|
|
5
5
|
"runtime": "Node.js for Node entrypoints; browser for browser-only entrypoints",
|
|
6
6
|
"minimumVersion": "22.23.2 for Node entrypoints",
|
|
7
7
|
"moduleSystem": "ESM"
|
|
8
8
|
},
|
|
9
|
-
"memberCount":
|
|
9
|
+
"memberCount": 303,
|
|
10
10
|
"runtimeSubpathPatterns": {
|
|
11
11
|
"arcane-os/modules/*": "./runtime/arcane/modules/*",
|
|
12
12
|
"arcane-os/entities/*": "./runtime/arcane/entities/*"
|
|
@@ -4374,7 +4374,7 @@
|
|
|
4374
4374
|
"summary": "Creates an app-neutral Core dispatcher with explicit services, request lifetimes, events and graceful drain.",
|
|
4375
4375
|
"availability": "Node on Windows, Linux and macOS native hosts; Android requires its host adaptation",
|
|
4376
4376
|
"protocol": "arcane/1 dispatcher and service lifecycle",
|
|
4377
|
-
"normalization": "Starts services independently; runtime.getService(name) and context.getService(name) return the same registered object after only its shared startup, without a renderer or global barrier. Lookup is readiness, not a lifetime lease; new lookups reject during shutdown. Preserves complete results/errors, cancels request-lifetime work and drains accepted service work; runtime.replay publishes current dispatcher/service state without restart and preserves reentrant lifecycle publication order. Missing dispatch retains METHOD_NOT_ALLOWED with exact method/namespace and core-namespace-unavailable or core-method-unavailable; named services, registered methods and built-in namespaces establish presence. Handler/startup/permission errors remain unchanged."
|
|
4377
|
+
"normalization": "Starts services independently; runtime.getService(name) and context.getService(name) return the same registered object after only its shared startup, without a renderer or global barrier. Lookup is readiness, not a lifetime lease; new lookups reject during shutdown. runtime.handle(frame,{contextRequestId}) optionally sets handler requestId while coreRequestId remains frame.id; omitted metadata exposes both equal. Internal IDs continue to own cancellation/state/event envelopes and payloads remain unchanged. Preserves complete results/errors, cancels request-lifetime work and drains accepted service work; runtime.replay publishes current dispatcher/service state without restart and preserves reentrant lifecycle publication order. Missing dispatch retains METHOD_NOT_ALLOWED with exact method/namespace and core-namespace-unavailable or core-method-unavailable; named services, registered methods and built-in namespaces establish presence. Handler/startup/permission errors remain unchanged."
|
|
4378
4378
|
},
|
|
4379
4379
|
{
|
|
4380
4380
|
"id": "core-stdio:encodeCoreFrame",
|
|
@@ -4416,7 +4416,7 @@
|
|
|
4416
4416
|
"summary": "Attaches an existing Core runtime to framed input and output with concurrent dispatch and graceful shutdown.",
|
|
4417
4417
|
"availability": "Node with readable input and writable output streams",
|
|
4418
4418
|
"protocol": "Content-Length framed arcane/1 stdio",
|
|
4419
|
-
"normalization": "Returns {runtime,closed,close};
|
|
4419
|
+
"normalization": "Returns {runtime,closed,close}; scopes responses/request events, cancellation and current-state replay to its connection, preserving original service-facing requestId and complete payloads while routing unique internal IDs. Preserves queued output order, reports parser and stream failures, drains accepted runtime work on EOF and never exits the host or ends caller-owned output"
|
|
4420
4420
|
},
|
|
4421
4421
|
{
|
|
4422
4422
|
"id": "native-portable-provider:createPortableNativeProvider",
|
|
@@ -4598,7 +4598,7 @@
|
|
|
4598
4598
|
"summary": "Resolves matching per-app native state, workspace and optional shared endpoint defaults for packaged UI and external MCP.",
|
|
4599
4599
|
"availability": "Node native locations on Windows/Linux/macOS; Android and other hosts supply stateRoot and native adaptation",
|
|
4600
4600
|
"protocol": "Pure native launch-context resolution and existing local IPC",
|
|
4601
|
-
"normalization": "Returns a new complete context with only omitted stateRoot/workspaceRoot and selected sharedHost endpoint/log fields filled; preserves explicit values and additional payloads. Native launchContext presence opts generated entry into resolution; omitted sharedHost retains stdio. No I/O, saved-state discovery, process startup, migration or ArcaneData/Repos change. Malformed selected appId/stateRoot/sharedHost inputs report TypeError; platform IPC errors remain operation-owned."
|
|
4601
|
+
"normalization": "Returns a new complete context with only omitted stateRoot/workspaceRoot and selected sharedHost endpoint/log fields filled; preserves explicit values and additional payloads. Native launchContext presence opts generated entry into resolution; omitted sharedHost retains stdio. Optional coreListener:{endpoint} is preserved without endpoint defaults and attaches to that same window-owned runtime in the generated entry; selecting it together with sharedHost reports TypeError there. No I/O, saved-state discovery, process startup, migration or ArcaneData/Repos change. Malformed selected appId/stateRoot/sharedHost inputs report TypeError; platform IPC errors remain operation-owned."
|
|
4602
4602
|
},
|
|
4603
4603
|
{
|
|
4604
4604
|
"id": "core-host:readCoreLaunchContext",
|
|
@@ -4628,6 +4628,20 @@
|
|
|
4628
4628
|
"protocol": "arcane/1 over Content-Length framed stdio",
|
|
4629
4629
|
"normalization": "Returns the existing {runtime,closed,close} transport owner; an optional abort signal invokes the same idempotent drain without killing the process, replacing service readiness or cancelling accepted service-lifetime work"
|
|
4630
4630
|
},
|
|
4631
|
+
{
|
|
4632
|
+
"id": "core-host:startCoreListener",
|
|
4633
|
+
"name": "startCoreListener",
|
|
4634
|
+
"displayName": "startCoreListener()",
|
|
4635
|
+
"kind": "function",
|
|
4636
|
+
"signature": "startCoreListener({runtime,endpoint,onError}={})",
|
|
4637
|
+
"entrypoints": ["arcane-os/core/host"],
|
|
4638
|
+
"primaryImport": "arcane-os/core/host",
|
|
4639
|
+
"group": "Shared Core host",
|
|
4640
|
+
"summary": "Attaches local IPC to an existing window-owned Core runtime without changing its services or lifetime.",
|
|
4641
|
+
"availability": "Node named pipes on Windows and Unix-domain sockets on Linux/macOS; Android requires its host adaptation",
|
|
4642
|
+
"protocol": "arcane/1 over local IPC with per-connection correlation, cancellation and current-state replay",
|
|
4643
|
+
"normalization": "Returns {endpoint,closed,close}; never constructs, starts or closes the supplied runtime. Explicit close flushes queued output and disconnects its clients while accepted service work remains runtime-owned. Runtime shutdown retains the endpoint through service drain then closes the listener. Preserves parameters/results/event data, original handler requestId and internal coreRequestId; no host shutdown RPC. Bind errors reject startup; transport errors reach onError and terminal errors reject closed. Native launchContext.coreListener:{endpoint} selects the existing stdio branch; no sharedHost/headless selection or inferred endpoint."
|
|
4644
|
+
},
|
|
4631
4645
|
{
|
|
4632
4646
|
"id": "core-host:startSharedCoreHost",
|
|
4633
4647
|
"name": "startSharedCoreHost",
|
|
@@ -4654,7 +4668,7 @@
|
|
|
4654
4668
|
"summary": "Connects to one selected host and optionally starts an explicit headless entry when absent.",
|
|
4655
4669
|
"availability": "Node local IPC and optional explicit child process with diagnostic file",
|
|
4656
4670
|
"protocol": "arcane/1 Core client; optional Node startup IPC handshake",
|
|
4657
|
-
"normalization": "Returns {client,endpoint,closed,close,shutdown}. Only ENOENT/ECONNREFUSED selects start {command,args,cwd,env,logFile}; no request retry. Close cancels this connection's request work while preserving the host and accepted service work. Explicit shutdown drains
|
|
4671
|
+
"normalization": "Returns {client,endpoint,closed,close,shutdown}. Only ENOENT/ECONNREFUSED selects start {command,args,cwd,env,logFile}; no request retry. Close cancels this connection's request work while preserving the host and accepted service work. Explicit shutdown drains an owning shared host for all clients; cancelling a launch wait does not kill the host. Connect to startCoreListener with start omitted; that borrowed listener implements no core.host.shutdown operation and its runtime owner retains shutdown."
|
|
4658
4672
|
},
|
|
4659
4673
|
{
|
|
4660
4674
|
"id": "core-host:runSharedCoreHost",
|
|
@@ -420,9 +420,13 @@ unchanged, including on the final CPU attempt.
|
|
|
420
420
|
Every loaded session includes an `execution` record in its ordinary state
|
|
421
421
|
events: `preference`, `requestedTarget`, `resolvedDevice`, `resolution`,
|
|
422
422
|
`reason`, `configuredTarget`, `observedTarget`, complete `supportedBackends`,
|
|
423
|
-
`selectedProviders`, ordered `attempts` with their full errors, `fallback`,
|
|
424
|
-
`discoveryError
|
|
425
|
-
|
|
423
|
+
`selectedProviders`, ordered `attempts` with their full errors, `fallback`,
|
|
424
|
+
`discoveryError`, and `deviceInventory`. The inventory retains the complete
|
|
425
|
+
`{platform,state,devices,issues}` already obtained for that load's automatic
|
|
426
|
+
physical selection. It is `null` when that load did not gather an inventory;
|
|
427
|
+
retaining it performs no additional discovery. Each attempt records provider
|
|
428
|
+
names in `executionProviders`, its requested `configuredTarget`, `status`
|
|
429
|
+
(`configured` or `failed`), and
|
|
426
430
|
`error`. The accepted top-level `configuredTarget` is
|
|
427
431
|
`{source,executionProviders}`; it retains the complete provider options,
|
|
428
432
|
including native numeric `deviceId` values. Its `source` is `cpu-default`,
|
|
@@ -531,6 +535,23 @@ String input containing U+0000 reports an incompatibility at the native tensor
|
|
|
531
535
|
boundary: the Node binding uses null-terminated strings and cannot preserve
|
|
532
536
|
that input completely. The SDK does not alter the supplied string.
|
|
533
537
|
|
|
538
|
+
A failed run preserves the original error, stack, cause and additional fields,
|
|
539
|
+
and adds the developer diagnostic `error.onnxRun`. It contains `sessionId`,
|
|
540
|
+
`requestId`, `stage`, the original `model` path and `runtimeModulePath`, the
|
|
541
|
+
session's complete `execution` record, `runOptions`, and input/output names and
|
|
542
|
+
metadata. `stage` distinguishes `feed-conversion`, `fetch-conversion`,
|
|
543
|
+
`session.run`, `output-conversion`, and `result-delivery`. `feeds` and `fetches`
|
|
544
|
+
retain complete tensor types, dimensions and data through the existing Core tensor encoding;
|
|
545
|
+
omitted options remain omitted at the JSON boundary. `feedsSource` and
|
|
546
|
+
`fetchesSource` identify `request` records when conversion did not complete,
|
|
547
|
+
or `converted` values prepared for `session.run`. No partial converted map is
|
|
548
|
+
presented as the complete input. The actual input tensors are preserved without changes
|
|
549
|
+
to inference, and successful runs create no diagnostic tensor copy. If building
|
|
550
|
+
this diagnostic fails, its complete `diagnosticError` accompanies the fields
|
|
551
|
+
obtained before that failure; the original run error remains the failure.
|
|
552
|
+
Session metadata and feeds describe graph inputs, not internal node tensors
|
|
553
|
+
that the native runtime has not reported.
|
|
554
|
+
|
|
534
555
|
`current()` returns `{sessions,closed}`. `subscribe(listener)` replays current
|
|
535
556
|
state synchronously and returns an unsubscribe function. Load, readiness,
|
|
536
557
|
unload and failures remain observable. `unload({id,signal?})` releases that
|
|
@@ -336,6 +336,19 @@ progress includes model preparation, tokenization and evaluation; downloaded
|
|
|
336
336
|
members report files, not byte progress. Complete technical errors belong in
|
|
337
337
|
developer diagnostics, while the application owns its user-facing status.
|
|
338
338
|
|
|
339
|
+
An ONNX run failure reaches the rejected evaluation and retained `error` in
|
|
340
|
+
`current()`, `decisions.status`, and `decisions.state`, including the complete
|
|
341
|
+
[`error.onnxRun` diagnostic](local-ai.md#native-onnx-sessions). This identifies
|
|
342
|
+
the actual session, request, failure stage, model path, provider execution
|
|
343
|
+
record, graph metadata and complete encoded feed tensors with their dimensions.
|
|
344
|
+
The activation's `execution.execution.deviceInventory` retains the complete
|
|
345
|
+
inventory consumed by automatic physical selection during its load, or `null`
|
|
346
|
+
when that selection path did not gather one.
|
|
347
|
+
Neither observation starts another hardware query or changes model execution.
|
|
348
|
+
Retain these complete records in the selected developer inspection surface;
|
|
349
|
+
ordinary user status remains application-owned. A retained error identifies
|
|
350
|
+
that failed request and does not by itself establish that a later request failed.
|
|
351
|
+
|
|
339
352
|
Concurrent callers selecting the same family, model, revision, dtype, source,
|
|
340
353
|
mapping and target share one explicit activation.
|
|
341
354
|
Cancelling a load or evaluation cancels that activation and its outstanding operations, because the
|
|
@@ -427,6 +427,7 @@ The remaining data-only subpaths are eight JSON Schemas and package metadata.
|
|
|
427
427
|
| `arcaneNativeBuilderProvider` | singleton | `arcane-os/native/portable-provider` | Portable native provider | Node; produces a portable payload rather than an executable host |
|
|
428
428
|
| `arcaneNativeBuilderProvider default export` | singleton | `arcane-os/native/portable-provider` | Portable native provider | Node; produces a portable payload rather than an executable host |
|
|
429
429
|
| `startCoreHost()` | function | `arcane-os/core/host` | Native Core host composition | Node with readable input and writable output streams |
|
|
430
|
+
| `startCoreListener()` | function | `arcane-os/core/host` | Shared Core host | Node local IPC attached to an existing runtime |
|
|
430
431
|
| `startSharedCoreHost()` | function | `arcane-os/core/host` | Shared Core host | Node local IPC on Windows, Linux and macOS |
|
|
431
432
|
| `connectSharedCoreHost()` | function | `arcane-os/core/host` | Shared Core host | Node local IPC and optional explicit headless startup |
|
|
432
433
|
| `connectAppControl()` | function | `arcane-os/core/app-control` | Native application control | Node local IPC; current window adapter is Windows WebView2 |
|
|
@@ -7394,6 +7395,14 @@ Import it from `arcane-os/core/runtime`. The runtime exposes `current()`,
|
|
|
7394
7395
|
`subscribe()`, `onFrame()`, `emit()`, `registerService()`, `getService()`, `start()`, `handle()`
|
|
7395
7396
|
and idempotent `close()`.
|
|
7396
7397
|
|
|
7398
|
+
`runtime.handle(frame, {contextRequestId})` optionally preserves a transport's
|
|
7399
|
+
original client ID in handler `context.requestId`, while `context.coreRequestId`
|
|
7400
|
+
always exposes the actual internal `frame.id`. Active requests, cancellation,
|
|
7401
|
+
response IDs and request-event envelopes retain that internal ID. Ordinary
|
|
7402
|
+
`handle(frame)` exposes both context IDs equal to `frame.id`. This metadata
|
|
7403
|
+
does not change parameters or event data; transports own client-facing protocol
|
|
7404
|
+
correlation. See [the runtime contract](core-runtime.md#state-and-frames).
|
|
7405
|
+
|
|
7397
7406
|
`await runtime.getService(name)` and service `context.getService(name)` return
|
|
7398
7407
|
the actual registered service after its shared startup. They wait for that
|
|
7399
7408
|
dependency alone, may start it before `runtime.start()`, and add no renderer or
|
|
@@ -7551,6 +7560,13 @@ Import it from `arcane-os/core/stdio`. The result is
|
|
|
7551
7560
|
`{runtime, closed, close}`. EOF or input close starts graceful shutdown;
|
|
7552
7561
|
`closed` settles only after accepted runtime work and queued output settle.
|
|
7553
7562
|
|
|
7563
|
+
Responses, request events, cancellation controls and current-state replay are
|
|
7564
|
+
connection-scoped even when an additional IPC listener shares the runtime.
|
|
7565
|
+
Stdio preserves original handler `requestId` values while routing fresh internal
|
|
7566
|
+
IDs; uncorrelated service events remain shared. EOF retains its existing
|
|
7567
|
+
runtime-wide shutdown ownership. Additional clients attach through
|
|
7568
|
+
[`startCoreListener()`](#startcorelistener).
|
|
7569
|
+
|
|
7554
7570
|
### Availability and normalization
|
|
7555
7571
|
|
|
7556
7572
|
**Node with readable input and writable output streams.** Parser, input, output
|
|
@@ -7995,6 +8011,14 @@ the caller's working-directory meaning. `appId` and the selected state path
|
|
|
7995
8011
|
must be nonempty strings; a selected `sharedHost` must be an object. Malformed
|
|
7996
8012
|
inputs report `TypeError`; native endpoint failures belong to the IPC operation.
|
|
7997
8013
|
|
|
8014
|
+
`native.launchContext.coreListener:{endpoint}` instead attaches local IPC to
|
|
8015
|
+
the existing window/stdio runtime. Its endpoint remains explicit and receives
|
|
8016
|
+
no default. The generated entry rejects simultaneous `coreListener` and
|
|
8017
|
+
`sharedHost` selections. Client disconnect affects that connection; window
|
|
8018
|
+
shutdown still drains Core and closes the additional listener. See
|
|
8019
|
+
[`startCoreListener()`](#startcorelistener) and
|
|
8020
|
+
[native launch locations](core-native-packaging.md#launch-time-locations).
|
|
8021
|
+
|
|
7998
8022
|
```javascript
|
|
7999
8023
|
import {resolveNativeLaunchContext} from 'arcane-os/core/host';
|
|
8000
8024
|
|
|
@@ -8793,6 +8817,59 @@ async function bundleMoonCheeseRuntime(outputRoot){
|
|
|
8793
8817
|
The ordinary provider invokes this owner only for an explicit native local-AI
|
|
8794
8818
|
selection. See [selected local-AI runtimes](core-native-packaging.md#selected-local-ai-runtimes).
|
|
8795
8819
|
|
|
8820
|
+
## startCoreListener()
|
|
8821
|
+
|
|
8822
|
+
### Overview and signature
|
|
8823
|
+
|
|
8824
|
+
Attaches a local IPC listener to an existing Core runtime, without creating,
|
|
8825
|
+
starting or taking ownership of that runtime or its services.
|
|
8826
|
+
|
|
8827
|
+
```text
|
|
8828
|
+
startCoreListener({runtime,endpoint,onError}={})
|
|
8829
|
+
```
|
|
8830
|
+
|
|
8831
|
+
Import from `arcane-os/core/host`. Resolves `{endpoint,closed,close}` after the
|
|
8832
|
+
selected endpoint binds. `close()` is idempotent, cancels the listener's
|
|
8833
|
+
request-lifetime work, flushes queued output and closes its connections. It
|
|
8834
|
+
does not call `runtime.close()` or wait for accepted service-lifetime work;
|
|
8835
|
+
that work remains tracked by the existing runtime. Runtime shutdown rejects
|
|
8836
|
+
new listener requests, retains the endpoint through service drain/disposal,
|
|
8837
|
+
and closes the listener automatically. Observe both owners' `closed` promises.
|
|
8838
|
+
Bind errors reject startup without closing the supplied runtime. Transport
|
|
8839
|
+
errors reach `onError`, with complete console diagnostics by default; terminal
|
|
8840
|
+
listener errors reject `closed`. Attaching to a draining/closed runtime reports
|
|
8841
|
+
`CORE_CLOSING`.
|
|
8842
|
+
|
|
8843
|
+
Node supports named pipes on Windows and Unix-domain sockets on Linux/macOS;
|
|
8844
|
+
Android requires its host adaptation. Supply a nonempty endpoint and an existing
|
|
8845
|
+
parent directory where required. Connect with `connectSharedCoreHost({endpoint})`
|
|
8846
|
+
and omit `start`. Its current-runtime replay does not replay requests. The
|
|
8847
|
+
borrowed listener implements no `core.host.shutdown` operation; use client
|
|
8848
|
+
`close()` for disconnection and the existing runtime's owner for host shutdown.
|
|
8849
|
+
|
|
8850
|
+
Each connection owns response/event correlation and request cancellation.
|
|
8851
|
+
Handler `requestId` preserves the client ID; `coreRequestId` is the distinct
|
|
8852
|
+
internal dispatch ID. Parameters, results and event data, including
|
|
8853
|
+
`data.requestId`, remain unchanged. Runtime-state snapshots retain internal
|
|
8854
|
+
active IDs; no service event is invented or retained for later replay.
|
|
8855
|
+
|
|
8856
|
+
```js
|
|
8857
|
+
import {startCoreListener} from 'arcane-os/core/host';
|
|
8858
|
+
|
|
8859
|
+
const listener = await startCoreListener({runtime: host.runtime, endpoint: selectedEndpoint});
|
|
8860
|
+
try {
|
|
8861
|
+
await host.closed;
|
|
8862
|
+
} finally {
|
|
8863
|
+
await listener.close();
|
|
8864
|
+
}
|
|
8865
|
+
```
|
|
8866
|
+
|
|
8867
|
+
`host` is the application's existing stdio host. Generated native entries
|
|
8868
|
+
select this attachment with `native.launchContext.coreListener:{endpoint}`,
|
|
8869
|
+
preserving their actual runtime, service set, profile, origin and state root.
|
|
8870
|
+
Omit `sharedHost`; the two options describe alternative lifetimes. Full
|
|
8871
|
+
contract: [existing-runtime listener](core-shared-host.md#attach-to-an-existing-window-owned-core).
|
|
8872
|
+
|
|
8796
8873
|
## startSharedCoreHost()
|
|
8797
8874
|
|
|
8798
8875
|
### Overview
|
|
@@ -8871,6 +8948,12 @@ not kill a host another client may use. No startup timeout is imposed; supply
|
|
|
8871
8948
|
before disconnecting. It affects every client; cancellation after acceptance
|
|
8872
8949
|
does not reverse it. A drain failure returns the full Core error.
|
|
8873
8950
|
|
|
8951
|
+
The same connector can attach to `startCoreListener()` with `start` omitted.
|
|
8952
|
+
There, `close()` still disconnects only this client, and `shutdown()` has no
|
|
8953
|
+
listener-owned operation: absent an application method of that name, the
|
|
8954
|
+
ordinary dispatcher returns `METHOD_NOT_ALLOWED`. The existing window/runtime
|
|
8955
|
+
owner remains responsible for shutdown.
|
|
8956
|
+
|
|
8874
8957
|
```js
|
|
8875
8958
|
import {connectSharedCoreHost} from 'arcane-os/core/host';
|
|
8876
8959
|
|
|
@@ -8967,9 +9050,10 @@ stdio-owned Core lifetime. See [native shared-host launch](core-shared-host.md#n
|
|
|
8967
9050
|
|
|
8968
9051
|
## startCoreHost()
|
|
8969
9052
|
|
|
8970
|
-
For
|
|
8971
|
-
[
|
|
8972
|
-
|
|
9053
|
+
For an external client of the actual window-owned runtime, attach
|
|
9054
|
+
[`startCoreListener()`](#startcorelistener) to `host.runtime`. For an explicitly
|
|
9055
|
+
independent headless lifetime, use the [shared host functions](#startsharedcorehost).
|
|
9056
|
+
Ordinary `startCoreHost()` retains its existing stdio-owned lifetime.
|
|
8973
9057
|
|
|
8974
9058
|
### Overview
|
|
8975
9059
|
|
package/package.json
CHANGED
package/src/core/host.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import Is from 'strong-type';
|
|
|
5
5
|
import {createCoreRuntime} from './runtime.mjs';
|
|
6
6
|
import {startCoreStdio} from './stdio.mjs';
|
|
7
7
|
|
|
8
|
-
export {startSharedCoreHost, connectSharedCoreHost, runSharedCoreHost, startSharedCoreBridge} from './shared-host.mjs';
|
|
8
|
+
export {startCoreListener, startSharedCoreHost, connectSharedCoreHost, runSharedCoreHost, startSharedCoreBridge} from './shared-host.mjs';
|
|
9
9
|
|
|
10
10
|
const is = new Is(false);
|
|
11
11
|
|