@independo/inderun-web 0.1.3-dev.7 → 0.2.0-dev.10
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/README.md +187 -1
- package/dist/core/browser-host.d.ts.map +1 -0
- package/dist/{engine.d.ts → core/engine.d.ts} +6 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/{engine.js → core/engine.js} +14 -1
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/host.d.ts.map +1 -0
- package/dist/{provider.d.ts → core/provider.d.ts} +9 -0
- package/dist/core/provider.d.ts.map +1 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/{route-planner.d.ts → core/route-planner.d.ts} +31 -8
- package/dist/core/route-planner.d.ts.map +1 -0
- package/dist/{route-planner.js → core/route-planner.js} +46 -17
- package/dist/{router.d.ts → core/router.d.ts} +11 -1
- package/dist/core/router.d.ts.map +1 -0
- package/dist/{router.js → core/router.js} +26 -20
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/index.d.ts +9 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -9
- package/dist/onnx.d.ts +13 -0
- package/dist/onnx.d.ts.map +1 -0
- package/dist/onnx.js +12 -0
- package/dist/openai.d.ts +1 -1
- package/dist/openai.d.ts.map +1 -1
- package/dist/openai.js +1 -1
- package/dist/providers/onnx/provider.d.ts +78 -0
- package/dist/providers/onnx/provider.d.ts.map +1 -0
- package/dist/providers/onnx/provider.js +217 -0
- package/dist/providers/onnx/runtime.d.ts +110 -0
- package/dist/providers/onnx/runtime.d.ts.map +1 -0
- package/dist/providers/onnx/runtime.js +76 -0
- package/dist/providers/onnx/transformers-runtime.d.ts +72 -0
- package/dist/providers/onnx/transformers-runtime.d.ts.map +1 -0
- package/dist/providers/onnx/transformers-runtime.js +210 -0
- package/dist/{openai-provider.d.ts → providers/openai/provider.d.ts} +21 -3
- package/dist/providers/openai/provider.d.ts.map +1 -0
- package/dist/{openai-provider.js → providers/openai/provider.js} +42 -2
- package/dist/providers/system-model/chrome-runtime.d.ts +48 -0
- package/dist/providers/system-model/chrome-runtime.d.ts.map +1 -0
- package/dist/providers/system-model/chrome-runtime.js +137 -0
- package/dist/providers/system-model/provider.d.ts +67 -0
- package/dist/providers/system-model/provider.d.ts.map +1 -0
- package/dist/providers/system-model/provider.js +190 -0
- package/dist/providers/system-model/runtime.d.ts +110 -0
- package/dist/providers/system-model/runtime.d.ts.map +1 -0
- package/dist/providers/system-model/runtime.js +73 -0
- package/dist/system-model.d.ts +13 -0
- package/dist/system-model.d.ts.map +1 -0
- package/dist/system-model.js +12 -0
- package/dist/web-sdk.d.ts +23 -6
- package/dist/web-sdk.d.ts.map +1 -1
- package/dist/web-sdk.js +29 -12
- package/package.json +21 -5
- package/dist/browser-host.d.ts.map +0 -1
- package/dist/engine.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/host.d.ts.map +0 -1
- package/dist/openai-provider.d.ts.map +0 -1
- package/dist/provider.d.ts.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/route-planner.d.ts.map +0 -1
- package/dist/router.d.ts.map +0 -1
- package/dist/telemetry.d.ts.map +0 -1
- /package/dist/{browser-host.d.ts → core/browser-host.d.ts} +0 -0
- /package/dist/{browser-host.js → core/browser-host.js} +0 -0
- /package/dist/{errors.d.ts → core/errors.d.ts} +0 -0
- /package/dist/{errors.js → core/errors.js} +0 -0
- /package/dist/{host.d.ts → core/host.d.ts} +0 -0
- /package/dist/{host.js → core/host.js} +0 -0
- /package/dist/{provider.js → core/provider.js} +0 -0
- /package/dist/{registry.d.ts → core/registry.d.ts} +0 -0
- /package/dist/{registry.js → core/registry.js} +0 -0
- /package/dist/{telemetry.d.ts → core/telemetry.d.ts} +0 -0
- /package/dist/{telemetry.js → core/telemetry.js} +0 -0
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
TypeScript/Web SDK for IndeRun.
|
|
10
10
|
|
|
11
|
-
This package provides the Web SDK entrypoint, the engine core, routing, telemetry, error normalization,
|
|
11
|
+
This package provides the Web SDK entrypoint, the engine core, routing, telemetry, error normalization, the OpenAI-compatible cloud provider, the Web ONNX Runtime provider for developer-supplied local models, and the Web system-model provider for browser-managed on-device models.
|
|
12
12
|
|
|
13
13
|
## Basic Usage
|
|
14
14
|
|
|
@@ -48,6 +48,192 @@ taxonomy (`AuthError`, `RateLimited`, `Timeout`, `Unavailable`, `Internal`). The
|
|
|
48
48
|
exact status-to-class mapping is documented on the provider in code — see
|
|
49
49
|
`OpenAIResponsesProvider` — so it stays in sync with behavior.
|
|
50
50
|
|
|
51
|
+
## On-Device Models: ONNX Runtime (Web)
|
|
52
|
+
|
|
53
|
+
`local.onnx.genai.web` runs developer-supplied ONNX models in the browser. Registering it is what
|
|
54
|
+
makes `constraints.privacy = "local_required"` routable. Pass `onnx` to the factory (`openAI` and
|
|
55
|
+
`onnx` are both optional, but at least one is required):
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { createIndeRunWeb } from "@independo/inderun-web";
|
|
59
|
+
|
|
60
|
+
const inderun = createIndeRunWeb({
|
|
61
|
+
onnx: {
|
|
62
|
+
modelPackage: {
|
|
63
|
+
id: "phi-3-mini-web",
|
|
64
|
+
format: "onnx",
|
|
65
|
+
tasks: ["text_to_text"],
|
|
66
|
+
runtime: { platforms: ["web"] },
|
|
67
|
+
source: { sourceType: "registry", ref: "onnx-community/Phi-3-mini-4k-instruct" }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`modelPackage` is the provider-neutral `ModelPackage` contract from
|
|
74
|
+
`@independo/inderun-contracts`; only `id` and `format` are required, and the package is validated
|
|
75
|
+
(including the inline-secret and URL-userinfo rules) before every attempt. Model files must never
|
|
76
|
+
carry credentials — use `authContextRef` and secure storage instead.
|
|
77
|
+
|
|
78
|
+
Options: `id` (defaults to `local.onnx.genai.web`), `modelPackage` (required), `runtime`, and
|
|
79
|
+
`timeoutMs` (a request's `constraints.timeoutMs` wins).
|
|
80
|
+
|
|
81
|
+
The default runtime loads **quantized** weights (`q4f16` on WebGPU, `q4` otherwise). Transformers.js
|
|
82
|
+
would otherwise pick `fp32`, which makes ONNX Runtime fail session creation with an allocation error
|
|
83
|
+
(`std::bad_alloc`) for anything but tiny models. Override with `dtype` when your model does not
|
|
84
|
+
publish that variant:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { OnnxRuntimeWebProvider, createTransformersJsRuntime } from "@independo/inderun-web/onnx";
|
|
88
|
+
|
|
89
|
+
const provider = new OnnxRuntimeWebProvider({
|
|
90
|
+
modelPackage,
|
|
91
|
+
runtime: createTransformersJsRuntime({ dtype: "q8", device: "wasm" })
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The default runtime targets models that load through the Transformers.js `text-generation` pipeline
|
|
96
|
+
— for example `onnx-community/gemma-3-1b-it-ONNX`. Multimodal exports split across separate
|
|
97
|
+
encoder/decoder graphs need `AutoProcessor` plus a model-specific class and should implement the
|
|
98
|
+
runtime seam instead — see [Custom runtimes](#custom-runtimes).
|
|
99
|
+
|
|
100
|
+
### Runtime dependency
|
|
101
|
+
|
|
102
|
+
The default runtime uses [Transformers.js](https://www.npmjs.com/package/@huggingface/transformers),
|
|
103
|
+
which runs ONNX models on `onnxruntime-web` and owns the generation loop (ONNX Runtime GenAI has no
|
|
104
|
+
browser build). It is an optional dependency that IndeRun does not bundle — install it yourself:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
pnpm add @huggingface/transformers
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If the package is present but fails to initialize, the provider reports itself unavailable and
|
|
111
|
+
routing produces an explainable `capability_unavailable` rejection instead of throwing. Bundlers do
|
|
112
|
+
need to resolve the specifier, so an app that imports `@independo/inderun-web/onnx` without
|
|
113
|
+
installing Transformers.js should pass its own runtime (or a `load` override) — see
|
|
114
|
+
[Custom runtimes](#custom-runtimes). WASM threads additionally require
|
|
115
|
+
cross-origin isolation (`Cross-Origin-Opener-Policy: same-origin`,
|
|
116
|
+
`Cross-Origin-Embedder-Policy: require-corp`) on whatever serves your app.
|
|
117
|
+
|
|
118
|
+
### Supported model sources
|
|
119
|
+
|
|
120
|
+
| `source.sourceType` | Web |
|
|
121
|
+
| ------------------- | ----------- |
|
|
122
|
+
| `registry` | Supported (hub model id in `source.ref`) |
|
|
123
|
+
| `bundled` | Supported (assets served by your app) |
|
|
124
|
+
| `app_managed` | Supported (assets served by your app) |
|
|
125
|
+
| `programmatic` | Supported (requires `createGenerator`) |
|
|
126
|
+
| `remote` | Deferred — download yourself, then declare the files |
|
|
127
|
+
| `filesystem` | Unsupported — browsers cannot read arbitrary local paths |
|
|
128
|
+
|
|
129
|
+
### Errors
|
|
130
|
+
|
|
131
|
+
| Condition | `errorClass` |
|
|
132
|
+
| ----------------------------------------------------------- | -------------------- |
|
|
133
|
+
| Capability gate fails pre-attempt, model missing/incompatible | `CapabilityMismatch` |
|
|
134
|
+
| Runtime initialization failure, resource exhaustion | `Unavailable` |
|
|
135
|
+
| Generation exceeded its timeout budget | `Timeout` |
|
|
136
|
+
| Malformed/empty model output, unexpected runtime failure | `Internal` |
|
|
137
|
+
|
|
138
|
+
A purely local runtime never produces `AuthError`, `RateLimited`, or `Offline`.
|
|
139
|
+
|
|
140
|
+
### Custom runtimes
|
|
141
|
+
|
|
142
|
+
Swap the execution backend without touching provider semantics by implementing
|
|
143
|
+
`OnnxTextGenerationRuntime`:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import {
|
|
147
|
+
OnnxRuntimeWebProvider,
|
|
148
|
+
OnnxRuntimeError,
|
|
149
|
+
createFixtureOnnxRuntime,
|
|
150
|
+
type OnnxTextGenerationRuntime
|
|
151
|
+
} from "@independo/inderun-web/onnx";
|
|
152
|
+
|
|
153
|
+
const runtime: OnnxTextGenerationRuntime = {
|
|
154
|
+
async prepare(modelPackage) {
|
|
155
|
+
return { available: true };
|
|
156
|
+
},
|
|
157
|
+
async generate({ messages, generation }, signal) {
|
|
158
|
+
// Throw OnnxRuntimeError("capability" | "unavailable" | "timeout" | "internal", …)
|
|
159
|
+
// to steer IndeRun error normalization.
|
|
160
|
+
return { text: "…" };
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`createFixtureOnnxRuntime()` provides a deterministic in-memory runtime for tests and offline demos.
|
|
166
|
+
|
|
167
|
+
## On-Device Models: Web System-Model Provider
|
|
168
|
+
|
|
169
|
+
`local.system-model.web` runs a browser-managed on-device model — currently
|
|
170
|
+
[Chrome's Prompt API](https://developer.chrome.com/docs/ai/prompt-api) (`LanguageModel`, Gemini
|
|
171
|
+
Nano). Unlike the ONNX provider above, this provider takes no `modelPackage`: the browser owns
|
|
172
|
+
model availability, download, and execution. Registering it also makes
|
|
173
|
+
`constraints.privacy = "local_required"` routable. Pass `systemModel` to the factory:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import { createIndeRunWeb } from "@independo/inderun-web";
|
|
177
|
+
|
|
178
|
+
const inderun = createIndeRunWeb({
|
|
179
|
+
systemModel: {}
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Options: `id` (defaults to `local.system-model.web`), `runtime` (defaults to
|
|
184
|
+
`createChromePromptApiRuntime()`), and `timeoutMs` (a request's `constraints.timeoutMs` wins).
|
|
185
|
+
|
|
186
|
+
### Browser support
|
|
187
|
+
|
|
188
|
+
Desktop Chrome 138+ only (Windows 10/11, macOS 13+, Linux, ChromeOS), and requires roughly 22 GB
|
|
189
|
+
free storage plus either a >4 GB VRAM GPU or a 16 GB RAM / 4+ core CPU. These figures come from
|
|
190
|
+
Chrome and may change — see the [Prompt API docs](https://developer.chrome.com/docs/ai/prompt-api)
|
|
191
|
+
for the current requirements. Edge exposes an analogous API, but this package has not yet verified
|
|
192
|
+
whether it shares the exact `LanguageModel` global shape. Everywhere else, the provider reports
|
|
193
|
+
itself unavailable (`api_missing`) rather than throwing.
|
|
194
|
+
|
|
195
|
+
### Errors
|
|
196
|
+
|
|
197
|
+
| Condition | `errorClass` |
|
|
198
|
+
| ------------------------------------------------------------- | --------------------- |
|
|
199
|
+
| Capability gate fails pre-attempt (any non-available state) | `CapabilityMismatch` |
|
|
200
|
+
| Hardware/browser-feature failure surfaced during generation | `CapabilityMismatch` |
|
|
201
|
+
| Storage/network constraints, transient failure | `Unavailable` |
|
|
202
|
+
| Generation aborted or exceeded its timeout budget | `Timeout` |
|
|
203
|
+
| Malformed/empty model output, unexpected runtime failure | `Internal` |
|
|
204
|
+
|
|
205
|
+
A purely local runtime never produces `AuthError`, `RateLimited`, or `Offline`. See
|
|
206
|
+
[`docs/architecture/web-system-model-provider-family.md`](https://github.com/independo-gmbh/inderun/blob/main/docs/architecture/web-system-model-provider-family.md)
|
|
207
|
+
in the monorepo for the full capability-state vocabulary.
|
|
208
|
+
|
|
209
|
+
### Custom runtimes
|
|
210
|
+
|
|
211
|
+
Swap the execution backend without touching provider semantics by implementing
|
|
212
|
+
`SystemModelRuntime`:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
import {
|
|
216
|
+
SystemModelWebProvider,
|
|
217
|
+
SystemModelRuntimeError,
|
|
218
|
+
createFixtureSystemModelRuntime,
|
|
219
|
+
type SystemModelRuntime
|
|
220
|
+
} from "@independo/inderun-web/system-model";
|
|
221
|
+
|
|
222
|
+
const runtime: SystemModelRuntime = {
|
|
223
|
+
async availability() {
|
|
224
|
+
return { kind: "available" };
|
|
225
|
+
},
|
|
226
|
+
async generate({ messages, generation }, signal) {
|
|
227
|
+
// Throw SystemModelRuntimeError("capability" | "unavailable" | "timeout" | "internal", …)
|
|
228
|
+
// to steer IndeRun error normalization.
|
|
229
|
+
return { text: "…" };
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
`createFixtureSystemModelRuntime()` provides a deterministic in-memory runtime for tests and
|
|
235
|
+
offline demos.
|
|
236
|
+
|
|
51
237
|
## Commands
|
|
52
238
|
|
|
53
239
|
```sh
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-host.d.ts","sourceRoot":"","sources":["../../src/core/browser-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,YAAY,EACb,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,0BAA2B,YAAW,mBAAmB;IACpE;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;CAOnC;AAED;;GAEG;AACH,qBAAa,kBAAmB,YAAW,YAAY;IACrD;;OAEG;IACH,GAAG,IAAI,MAAM;IAIb;;OAEG;IACH,YAAY,IAAI,MAAM;CAOvB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,iBAAiB;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC;;;;OAIG;gBACS,OAAO,GAAE,sBAA2B;IAShD;;;;OAIG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA0CxD;AAED;;GAEG;AACH,MAAM,WAAW,gCAAiC,SAAQ,OAAO,CAAC,YAAY,CAAC;IAC7E;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gCAAqC,GAC7C,YAAY,CA2Bd"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type TaskRequest, type TaskResult } from "@independo/inderun-contracts";
|
|
2
2
|
import type { HostServices } from "./host.js";
|
|
3
|
+
import type { ProviderCapabilitySnapshot } from "./provider.js";
|
|
3
4
|
import { ProviderRegistry } from "./registry.js";
|
|
4
5
|
import { type TelemetryService } from "./telemetry.js";
|
|
5
6
|
/**
|
|
@@ -38,5 +39,10 @@ export declare class IndeRun {
|
|
|
38
39
|
* @throws {IndeRunException} Standardized error indicating validation, connection, or provider failures.
|
|
39
40
|
*/
|
|
40
41
|
run(request: TaskRequest): Promise<TaskResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Reports each registered provider's static descriptor and current dynamic capability check,
|
|
44
|
+
* without executing a task. Useful for UI that shows live provider availability before a run.
|
|
45
|
+
*/
|
|
46
|
+
checkCapabilities(): Promise<ProviderCapabilitySnapshot[]>;
|
|
41
47
|
}
|
|
42
48
|
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,OAAO,EAAuB,KAAK,gBAAgB,EAAwB,MAAM,gBAAgB,CAAC;AAElG;;;;GAIG;AACH,qBAAa,OAAO;IAWhB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,YAAY;IAXtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAmB;IAE3C;;;;;OAKG;gBAEO,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,YAAY,EAClC,gBAAgB,CAAC,EAAE,gBAAgB;IAOrC;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAShB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;;;;OAOG;IACG,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAuIpD;;;OAGG;IACG,iBAAiB,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;CASjE"}
|
|
@@ -101,7 +101,9 @@ export class IndeRun {
|
|
|
101
101
|
taskKind: request.task.kind,
|
|
102
102
|
explanation: routeSelection.explanation,
|
|
103
103
|
constraints: request.constraints ?? null,
|
|
104
|
-
preferences: request.preferences ?? null
|
|
104
|
+
preferences: request.preferences ?? null,
|
|
105
|
+
plannerSource: routeSelection.plannerSource,
|
|
106
|
+
plannerUnavailableReason: routeSelection.plannerUnavailableReason ?? null
|
|
105
107
|
}
|
|
106
108
|
});
|
|
107
109
|
// 3. Execute the run task using the planned provider chain
|
|
@@ -188,4 +190,15 @@ export class IndeRun {
|
|
|
188
190
|
throw exception;
|
|
189
191
|
}
|
|
190
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Reports each registered provider's static descriptor and current dynamic capability check,
|
|
195
|
+
* without executing a task. Useful for UI that shows live provider availability before a run.
|
|
196
|
+
*/
|
|
197
|
+
async checkCapabilities() {
|
|
198
|
+
return Promise.all(this.registry.list().map(async (provider) => ({
|
|
199
|
+
providerId: provider.describe().id,
|
|
200
|
+
descriptor: provider.describe(),
|
|
201
|
+
capabilities: await provider.capabilities(this.hostServices)
|
|
202
|
+
})));
|
|
203
|
+
}
|
|
191
204
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,qDAAqD;IACrD,QAAQ,CAAC,aAAa,SAAS;IAC/B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,mCAAmC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE/B,MAAM,EAAE,sBAAsB;IAa1C;;OAEG;IACH,eAAe,IAAI,YAAY;CAahC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,SAAS,CAAC,GAC7D,gBAAgB,CAElB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,SAAS,CAAC,GAC7D,gBAAgB,CAElB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,SAAS,CAAC,GAC7D,gBAAgB,CAElB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,SAAS,CAAC,GAC7D,gBAAgB,CAElB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,SAAS,CAAC,GAC7D,gBAAgB,CAElB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,SAAS,CAAC,GAC7D,gBAAgB,CAElB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,SAAS,CAAC,GAC7D,gBAAgB,CAElB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,cAAc,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC,GAChE,gBAAgB,CAuDlB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/core/host.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAC"}
|
|
@@ -83,6 +83,15 @@ export interface ProviderDynamicCapabilities {
|
|
|
83
83
|
*/
|
|
84
84
|
reason?: string;
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Snapshot of a registered provider's static descriptor and current dynamic
|
|
88
|
+
* capability check, without executing a task.
|
|
89
|
+
*/
|
|
90
|
+
export interface ProviderCapabilitySnapshot {
|
|
91
|
+
providerId: string;
|
|
92
|
+
descriptor: ProviderDescriptor;
|
|
93
|
+
capabilities: ProviderDynamicCapabilities;
|
|
94
|
+
}
|
|
86
95
|
/**
|
|
87
96
|
* Execution context passed to provider run commands.
|
|
88
97
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC;;OAEG;IACH,SAAS,EAAE,YAAY,GAAG,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IACzE;;OAEG;IACH,cAAc,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;IAEnD;;OAEG;IACH,QAAQ,EAAE;QACR,mEAAmE;QACnE,GAAG,EAAE,OAAO,CAAC;QACb,mDAAmD;QACnD,SAAS,EAAE,OAAO,CAAC;QACnB,6DAA6D;QAC7D,QAAQ,EAAE,OAAO,CAAC;QAClB,6DAA6D;QAC7D,KAAK,EAAE,OAAO,CAAC;QACf,wEAAwE;QACxE,eAAe,EAAE,OAAO,CAAC;QACzB,kFAAkF;QAClF,gBAAgB,EAAE,OAAO,CAAC;QAC1B,6EAA6E;QAC7E,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IAEF;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAEjC;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,6DAA6D;QAC7D,gBAAgB,EAAE,OAAO,CAAC;QAC1B,2DAA2D;QAC3D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,YAAY,EAAE,2BAA2B,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,IAAI,kBAAkB,CAAC;IAC/B;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACvE;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAsC;IAEvD;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAWzC;;;OAGG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI5C;;OAEG;IACH,IAAI,IAAI,eAAe,EAAE;IAIzB;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -12,11 +12,28 @@ export interface SharedPlannerModule {
|
|
|
12
12
|
planRouteJson: (inputJson: string) => string | Promise<string>;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Coarse, privacy-safe reason the WASM planner produced no route plan. Used
|
|
16
|
+
* only for observability (telemetry/logging) — callers still fall back to
|
|
17
|
+
* local selection regardless of which reason fired.
|
|
18
|
+
*/
|
|
19
|
+
export type WasmUnavailableReason = "import_failed" | "invalid_module_shape" | "init_failed" | "plan_failed";
|
|
20
|
+
/**
|
|
21
|
+
* Result of a {@link RoutePlanner} attempt. `routePlan` is `null` when the
|
|
22
|
+
* planner could not produce a plan, in which case `source` is `"unavailable"`
|
|
23
|
+
* and `unavailableReason` narrows down why, so callers can log/emit telemetry
|
|
24
|
+
* instead of silently swapping planners.
|
|
25
|
+
*/
|
|
26
|
+
export interface PlannerOutcome {
|
|
27
|
+
routePlan: SharedPlannerRoutePlan | null;
|
|
28
|
+
source: "wasm" | "unavailable";
|
|
29
|
+
unavailableReason?: WasmUnavailableReason;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Strategy that turns planner input into a deterministic route plan, or an
|
|
33
|
+
* "unavailable" outcome (callers then fall back to local selection).
|
|
17
34
|
*/
|
|
18
35
|
export interface RoutePlanner {
|
|
19
|
-
planRoute(input: SharedPlannerInput): Promise<
|
|
36
|
+
planRoute(input: SharedPlannerInput): Promise<PlannerOutcome>;
|
|
20
37
|
}
|
|
21
38
|
/**
|
|
22
39
|
* A provider paired with the descriptor/capability projection the shared route
|
|
@@ -29,16 +46,22 @@ export interface ProviderRuntimeSnapshot {
|
|
|
29
46
|
}
|
|
30
47
|
/**
|
|
31
48
|
* {@link RoutePlanner} backed by the Rust route core compiled to WASM. The
|
|
32
|
-
* module is
|
|
33
|
-
*
|
|
49
|
+
* module specifier is a static literal (not configurable) so bundlers such as
|
|
50
|
+
* Vite/webpack/Rollup can statically resolve and chunk it — a variable
|
|
51
|
+
* specifier defeats bundler analysis and silently never loads in the browser
|
|
52
|
+
* (see issue #109). The module is imported lazily and memoized; if it cannot
|
|
53
|
+
* be loaded, `planRoute` resolves an "unavailable" outcome so the engine can
|
|
54
|
+
* fall back to local selection, and logs once via `console.warn` so the
|
|
55
|
+
* degradation is never fully silent.
|
|
34
56
|
*/
|
|
35
57
|
export declare class WasmRoutePlanner implements RoutePlanner {
|
|
36
|
-
private readonly moduleSpecifier;
|
|
37
58
|
private modulePromise?;
|
|
38
|
-
|
|
39
|
-
|
|
59
|
+
private loadFailureReason?;
|
|
60
|
+
private hasWarned;
|
|
61
|
+
planRoute(input: SharedPlannerInput): Promise<PlannerOutcome>;
|
|
40
62
|
private loadModule;
|
|
41
63
|
private importModule;
|
|
64
|
+
private warnOnce;
|
|
42
65
|
}
|
|
43
66
|
/**
|
|
44
67
|
* Describes each provider and evaluates its dynamic capabilities against the
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-planner.d.ts","sourceRoot":"","sources":["../../src/core/route-planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,IAAI,sBAAsB,EACnC,iBAAiB,IAAI,kBAAkB,EACvC,WAAW,EACZ,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAChE;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC/B,eAAe,GAAG,sBAAsB,GAAG,aAAa,GAAG,aAAa,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC;IAC/B,iBAAiB,CAAC,EAAE,qBAAqB,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC/D;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAClE,YAAY,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;CACvE;AAED;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IACnD,OAAO,CAAC,aAAa,CAAC,CAAsC;IAC5D,OAAO,CAAC,iBAAiB,CAAC,CAAwB;IAClD,OAAO,CAAC,SAAS,CAAS;IAEpB,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;YAkBrD,UAAU;YAOV,YAAY;IA6B1B,OAAO,CAAC,QAAQ;CAUjB;AAED;;;GAGG;AACH,wBAAsB,+BAA+B,CACnD,iBAAiB,EAAE,eAAe,EAAE,EACpC,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAepC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,uBAAuB,EAAE,EACpC,aAAa,EAAE,OAAO,GACrB,kBAAkB,CAsBpB"}
|
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
const DEFAULT_WASM_SPECIFIER = "@independo/inderun-route-core-wasm";
|
|
2
1
|
/**
|
|
3
2
|
* {@link RoutePlanner} backed by the Rust route core compiled to WASM. The
|
|
4
|
-
* module is
|
|
5
|
-
*
|
|
3
|
+
* module specifier is a static literal (not configurable) so bundlers such as
|
|
4
|
+
* Vite/webpack/Rollup can statically resolve and chunk it — a variable
|
|
5
|
+
* specifier defeats bundler analysis and silently never loads in the browser
|
|
6
|
+
* (see issue #109). The module is imported lazily and memoized; if it cannot
|
|
7
|
+
* be loaded, `planRoute` resolves an "unavailable" outcome so the engine can
|
|
8
|
+
* fall back to local selection, and logs once via `console.warn` so the
|
|
9
|
+
* degradation is never fully silent.
|
|
6
10
|
*/
|
|
7
11
|
export class WasmRoutePlanner {
|
|
8
|
-
moduleSpecifier;
|
|
9
12
|
modulePromise;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
+
loadFailureReason;
|
|
14
|
+
hasWarned = false;
|
|
13
15
|
async planRoute(input) {
|
|
14
16
|
const module = await this.loadModule();
|
|
15
17
|
if (!module) {
|
|
16
|
-
|
|
18
|
+
const unavailableReason = this.loadFailureReason ?? "import_failed";
|
|
19
|
+
this.warnOnce(unavailableReason);
|
|
20
|
+
return { routePlan: null, source: "unavailable", unavailableReason };
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const json = JSON.stringify(input);
|
|
24
|
+
const result = await module.planRouteJson(json);
|
|
25
|
+
return { routePlan: JSON.parse(result), source: "wasm" };
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
this.warnOnce("plan_failed", error);
|
|
29
|
+
return { routePlan: null, source: "unavailable", unavailableReason: "plan_failed" };
|
|
17
30
|
}
|
|
18
|
-
const json = JSON.stringify(input);
|
|
19
|
-
const result = await module.planRouteJson(json);
|
|
20
|
-
return JSON.parse(result);
|
|
21
31
|
}
|
|
22
32
|
async loadModule() {
|
|
23
33
|
if (!this.modulePromise) {
|
|
@@ -26,19 +36,38 @@ export class WasmRoutePlanner {
|
|
|
26
36
|
return this.modulePromise;
|
|
27
37
|
}
|
|
28
38
|
async importModule() {
|
|
39
|
+
let mod;
|
|
29
40
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
41
|
+
mod = (await import("@independo/inderun-route-core-wasm"));
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
this.loadFailureReason = "import_failed";
|
|
45
|
+
this.warnOnce("import_failed", error);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (typeof mod.planRouteJson !== "function") {
|
|
49
|
+
this.loadFailureReason = "invalid_module_shape";
|
|
50
|
+
this.warnOnce("invalid_module_shape");
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (mod.initSharedCore) {
|
|
54
|
+
try {
|
|
32
55
|
await mod.initSharedCore();
|
|
33
56
|
}
|
|
34
|
-
|
|
57
|
+
catch (error) {
|
|
58
|
+
this.loadFailureReason = "init_failed";
|
|
59
|
+
this.warnOnce("init_failed", error);
|
|
35
60
|
return null;
|
|
36
61
|
}
|
|
37
|
-
return mod;
|
|
38
62
|
}
|
|
39
|
-
|
|
40
|
-
|
|
63
|
+
return mod;
|
|
64
|
+
}
|
|
65
|
+
warnOnce(reason, error) {
|
|
66
|
+
if (this.hasWarned) {
|
|
67
|
+
return;
|
|
41
68
|
}
|
|
69
|
+
this.hasWarned = true;
|
|
70
|
+
console.warn(`[IndeRun] WASM route planner unavailable (${reason}); falling back to local route selection.`, error);
|
|
42
71
|
}
|
|
43
72
|
}
|
|
44
73
|
/**
|
|
@@ -2,7 +2,7 @@ import type { TaskRequest } from "@independo/inderun-contracts";
|
|
|
2
2
|
import type { HostServices } from "./host.js";
|
|
3
3
|
import type { ProviderAdapter } from "./provider.js";
|
|
4
4
|
import type { ProviderRegistry } from "./registry.js";
|
|
5
|
-
import { type RoutePlanner, type SharedPlannerRoutePlan } from "./route-planner.js";
|
|
5
|
+
import { type RoutePlanner, type SharedPlannerRoutePlan, type WasmUnavailableReason } from "./route-planner.js";
|
|
6
6
|
/**
|
|
7
7
|
* Output structure from the Router containing the chosen provider and a route selection description.
|
|
8
8
|
*/
|
|
@@ -23,6 +23,16 @@ export interface RouteSelection {
|
|
|
23
23
|
* Explanation detailing the selection decision. Useful for debugging and telemetry.
|
|
24
24
|
*/
|
|
25
25
|
explanation: string;
|
|
26
|
+
/**
|
|
27
|
+
* Which planner produced `routePlan`: the shared Rust/WASM core, or the
|
|
28
|
+
* local TypeScript fallback used when the WASM planner is unavailable.
|
|
29
|
+
*/
|
|
30
|
+
plannerSource: "wasm" | "fallback";
|
|
31
|
+
/**
|
|
32
|
+
* Set when `plannerSource` is `"fallback"` because the WASM planner failed;
|
|
33
|
+
* `undefined` when the fallback was not caused by a planner failure.
|
|
34
|
+
*/
|
|
35
|
+
plannerUnavailableReason?: WasmUnavailableReason;
|
|
26
36
|
}
|
|
27
37
|
/**
|
|
28
38
|
* Routing engine module. Filters registered providers against task types, request constraints,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/core/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAOtD,OAAO,EAIL,KAAK,YAAY,EAEjB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE3B,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,QAAQ,EAAE,eAAe,CAAC;IAC1B;;OAEG;IACH,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC;;OAEG;IACH,SAAS,EAAE,sBAAsB,CAAC;IAClC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,aAAa,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,qBAAqB,CAAC;CAClD;AAED;;;;GAIG;AACH,qBAAa,MAAM;IAEf,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,OAAO;gBADP,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,YAAqC;IAGxD;;;;;;;;;OASG;IACG,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAc5F,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,2BAA2B;IA2BnC,OAAO,CAAC,kBAAkB;IA0F1B,OAAO,CAAC,2BAA2B;IAiCnC,OAAO,CAAC,gBAAgB;CAYzB"}
|
|
@@ -26,26 +26,26 @@ export class Router {
|
|
|
26
26
|
const online = await hostServices.connectivity.isOnline();
|
|
27
27
|
const snapshots = await collectProviderRuntimeSnapshots(this.registry.list(), hostServices);
|
|
28
28
|
const planInput = buildSharedPlannerInput(request, snapshots, online);
|
|
29
|
-
const
|
|
30
|
-
if (routePlan) {
|
|
31
|
-
return this.selectFromSharedPlan(snapshots, routePlan);
|
|
29
|
+
const outcome = await this.planner.planRoute(planInput);
|
|
30
|
+
if (outcome.routePlan) {
|
|
31
|
+
return this.selectFromSharedPlan(snapshots, outcome.routePlan);
|
|
32
32
|
}
|
|
33
|
-
return this.selectFallbackRoute(request, snapshots, online);
|
|
33
|
+
return this.selectFallbackRoute(request, snapshots, online, outcome.unavailableReason);
|
|
34
34
|
}
|
|
35
35
|
selectFromSharedPlan(snapshots, routePlan) {
|
|
36
36
|
if (!routePlan.selectedProviderId) {
|
|
37
37
|
throw this.routePlanFailure(routePlan);
|
|
38
38
|
}
|
|
39
|
-
return this.buildSelectionFromRoutePlan(snapshots, routePlan);
|
|
39
|
+
return this.buildSelectionFromRoutePlan(snapshots, routePlan, "wasm");
|
|
40
40
|
}
|
|
41
|
-
selectFallbackRoute(request, snapshots, online) {
|
|
41
|
+
selectFallbackRoute(request, snapshots, online, plannerUnavailableReason) {
|
|
42
42
|
const plan = this.createFallbackPlan(request, snapshots, online);
|
|
43
43
|
if (!plan.selectedProviderId) {
|
|
44
44
|
throw this.routePlanFailure(plan);
|
|
45
45
|
}
|
|
46
|
-
return this.buildSelectionFromRoutePlan(snapshots, plan);
|
|
46
|
+
return this.buildSelectionFromRoutePlan(snapshots, plan, "fallback", plannerUnavailableReason);
|
|
47
47
|
}
|
|
48
|
-
buildSelectionFromRoutePlan(snapshots, routePlan) {
|
|
48
|
+
buildSelectionFromRoutePlan(snapshots, routePlan, plannerSource, plannerUnavailableReason) {
|
|
49
49
|
const orderedProviders = routePlan.candidates
|
|
50
50
|
.map((candidate) => snapshots.find((snapshot) => snapshot.descriptor.id === candidate.providerId))
|
|
51
51
|
.filter((snapshot) => snapshot !== undefined);
|
|
@@ -57,7 +57,9 @@ export class Router {
|
|
|
57
57
|
provider: selected.provider,
|
|
58
58
|
fallbackProviders: orderedProviders.slice(1).map((snapshot) => snapshot.provider),
|
|
59
59
|
routePlan,
|
|
60
|
-
explanation: routePlan.explanation.summary
|
|
60
|
+
explanation: routePlan.explanation.summary,
|
|
61
|
+
plannerSource,
|
|
62
|
+
...(plannerUnavailableReason ? { plannerUnavailableReason } : {})
|
|
61
63
|
};
|
|
62
64
|
}
|
|
63
65
|
createFallbackPlan(request, snapshots, online) {
|
|
@@ -67,17 +69,24 @@ export class Router {
|
|
|
67
69
|
.filter((candidate) => candidate.descriptor.supports.run);
|
|
68
70
|
const localCandidates = eligible.filter((candidate) => candidate.descriptor.type !== "cloud");
|
|
69
71
|
const cloudCandidates = eligible.filter((candidate) => candidate.descriptor.type === "cloud");
|
|
70
|
-
|
|
72
|
+
// Constraint filtering must apply to the whole candidate list, not just the selected provider:
|
|
73
|
+
// the remainder becomes the engine's fallback chain, and a fallback that violates the request
|
|
74
|
+
// constraints would let a `local_required` run be retried against a cloud provider.
|
|
75
|
+
const admissible = eligible.filter((candidate) => {
|
|
71
76
|
const descriptor = candidate.descriptor;
|
|
72
77
|
const constraints = planInput.constraints;
|
|
73
|
-
|
|
78
|
+
// Mirrors `is_data_private` in the shared Rust planner: a provider is private when it
|
|
79
|
+
// declares that data does not leave the device, defaulting to non-cloud providers.
|
|
80
|
+
const isDataPrivate = descriptor.privacy
|
|
81
|
+
? !descriptor.privacy.dataLeavesDevice
|
|
82
|
+
: descriptor.type !== "cloud";
|
|
74
83
|
if (constraints.cloud === "forbidden" && descriptor.type === "cloud") {
|
|
75
84
|
return false;
|
|
76
85
|
}
|
|
77
86
|
if (constraints.cloud === "required" && descriptor.type !== "cloud") {
|
|
78
87
|
return false;
|
|
79
88
|
}
|
|
80
|
-
if (constraints.privacy === "local_required" && !
|
|
89
|
+
if (constraints.privacy === "local_required" && !isDataPrivate) {
|
|
81
90
|
return false;
|
|
82
91
|
}
|
|
83
92
|
if (constraints.privacy === "cloud_required" && descriptor.type !== "cloud") {
|
|
@@ -88,10 +97,7 @@ export class Router {
|
|
|
88
97
|
}
|
|
89
98
|
return candidate.capabilities.available;
|
|
90
99
|
});
|
|
91
|
-
|
|
92
|
-
? [selected, ...eligible.filter((candidate) => candidate !== selected)]
|
|
93
|
-
: [];
|
|
94
|
-
if (ordered.length === 0) {
|
|
100
|
+
if (admissible.length === 0) {
|
|
95
101
|
const failureSummary = this.buildFallbackFailureSummary({
|
|
96
102
|
online,
|
|
97
103
|
constraints: planInput.constraints,
|
|
@@ -114,17 +120,17 @@ export class Router {
|
|
|
114
120
|
}
|
|
115
121
|
};
|
|
116
122
|
}
|
|
117
|
-
const selectedProviderId =
|
|
123
|
+
const selectedProviderId = admissible[0]?.descriptor.id;
|
|
118
124
|
return {
|
|
119
125
|
selectedProviderId,
|
|
120
|
-
fallbackProviderIds:
|
|
121
|
-
candidates:
|
|
126
|
+
fallbackProviderIds: admissible.slice(1).map((candidate) => candidate.descriptor.id),
|
|
127
|
+
candidates: admissible.map((candidate, index) => ({
|
|
122
128
|
providerId: candidate.descriptor.id,
|
|
123
129
|
order: index
|
|
124
130
|
})),
|
|
125
131
|
rejectedProviders: [],
|
|
126
132
|
explanation: {
|
|
127
|
-
summary: `Selected provider '${selectedProviderId}' deterministically from ${
|
|
133
|
+
summary: `Selected provider '${selectedProviderId}' deterministically from ${admissible.length} eligible candidate(s).`,
|
|
128
134
|
selectedProviderId
|
|
129
135
|
}
|
|
130
136
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/core/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAEtC;;GAEG;AACH,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;CAGnC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { type ConnectivityService, type DeviceConstraintsService, type SecureStorageService, type ClockService, type HttpClientService, type HttpRequest, type HttpResponse, type HostServices, type ThermalState } from "./host.js";
|
|
2
|
-
export { type ProviderDescriptor, type ProviderDynamicCapabilities, type RunContext, type ProviderAdapter } from "./provider.js";
|
|
3
|
-
export { ProviderRegistry } from "./registry.js";
|
|
4
|
-
export { type RouteSelection, Router } from "./router.js";
|
|
5
|
-
export { type RoutePlanner, type SharedPlannerInput, type SharedPlannerRoutePlan, WasmRoutePlanner } from "./route-planner.js";
|
|
6
|
-
export { type IndeRunExceptionParams, IndeRunException, createCapabilityMismatch, createOffline, createAuthError, createRateLimited, createTimeout, createUnavailable, createInternal, toIndeRunException } from "./errors.js";
|
|
7
|
-
export { IndeRun } from "./engine.js";
|
|
8
|
-
export { type TelemetryEventType, type TelemetryEvent, type TelemetryService, NoOpTelemetryService } from "./telemetry.js";
|
|
9
|
-
export { BrowserConnectivityService, FetchHttpClient, SystemClockService, createBrowserHostServices, type CreateBrowserHostServicesOptions, type FetchHttpClientOptions } from "./browser-host.js";
|
|
1
|
+
export { type ConnectivityService, type DeviceConstraintsService, type SecureStorageService, type ClockService, type HttpClientService, type HttpRequest, type HttpResponse, type HostServices, type ThermalState } from "./core/host.js";
|
|
2
|
+
export { type ProviderDescriptor, type ProviderDynamicCapabilities, type ProviderCapabilitySnapshot, type RunContext, type ProviderAdapter } from "./core/provider.js";
|
|
3
|
+
export { ProviderRegistry } from "./core/registry.js";
|
|
4
|
+
export { type RouteSelection, Router } from "./core/router.js";
|
|
5
|
+
export { type RoutePlanner, type PlannerOutcome, type WasmUnavailableReason, type SharedPlannerInput, type SharedPlannerRoutePlan, WasmRoutePlanner } from "./core/route-planner.js";
|
|
6
|
+
export { type IndeRunExceptionParams, IndeRunException, createCapabilityMismatch, createOffline, createAuthError, createRateLimited, createTimeout, createUnavailable, createInternal, toIndeRunException } from "./core/errors.js";
|
|
7
|
+
export { IndeRun } from "./core/engine.js";
|
|
8
|
+
export { type TelemetryEventType, type TelemetryEvent, type TelemetryService, NoOpTelemetryService } from "./core/telemetry.js";
|
|
9
|
+
export { BrowserConnectivityService, FetchHttpClient, SystemClockService, createBrowserHostServices, type CreateBrowserHostServicesOptions, type FetchHttpClientOptions } from "./core/browser-host.js";
|
|
10
10
|
export { createIndeRunWeb, type CreateIndeRunWebOptions } from "./web-sdk.js";
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,gBAAgB,EACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
|