@independo/inderun-web 0.3.0-dev.8 → 0.3.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.
Files changed (47) hide show
  1. package/README.md +12 -10
  2. package/dist/core/engine.d.ts +11 -0
  3. package/dist/core/engine.d.ts.map +1 -1
  4. package/dist/core/engine.js +38 -42
  5. package/dist/core/route-planner.d.ts +16 -13
  6. package/dist/core/route-planner.d.ts.map +1 -1
  7. package/dist/core/route-planner.js +22 -19
  8. package/dist/core/router.d.ts +1 -39
  9. package/dist/core/router.d.ts.map +1 -1
  10. package/dist/core/router.js +12 -206
  11. package/dist/index.d.ts +63 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +47 -2
  14. package/dist/onnx.d.ts +21 -0
  15. package/dist/onnx.d.ts.map +1 -1
  16. package/dist/onnx.js +15 -0
  17. package/dist/openai.d.ts +7 -0
  18. package/dist/openai.d.ts.map +1 -1
  19. package/dist/openai.js +7 -0
  20. package/dist/system-model.d.ts +13 -0
  21. package/dist/system-model.d.ts.map +1 -1
  22. package/dist/system-model.js +13 -0
  23. package/package.json +22 -8
  24. package/src/core/browser-host.ts +339 -0
  25. package/src/core/engine.ts +540 -0
  26. package/src/core/errors.ts +220 -0
  27. package/src/core/event-gate.ts +71 -0
  28. package/src/core/generated/inderun-api.ts +19 -0
  29. package/src/core/host.ts +15 -0
  30. package/src/core/provider.ts +231 -0
  31. package/src/core/registry.ts +48 -0
  32. package/src/core/route-planner.ts +261 -0
  33. package/src/core/router.ts +149 -0
  34. package/src/core/sse.ts +134 -0
  35. package/src/core/telemetry.ts +20 -0
  36. package/src/index.ts +147 -0
  37. package/src/onnx.ts +57 -0
  38. package/src/openai.ts +21 -0
  39. package/src/providers/onnx/provider.ts +300 -0
  40. package/src/providers/onnx/runtime.ts +188 -0
  41. package/src/providers/onnx/transformers-runtime.ts +345 -0
  42. package/src/providers/openai/provider.ts +765 -0
  43. package/src/providers/system-model/chrome-runtime.ts +221 -0
  44. package/src/providers/system-model/provider.ts +260 -0
  45. package/src/providers/system-model/runtime.ts +202 -0
  46. package/src/system-model.ts +49 -0
  47. package/src/web-sdk.ts +114 -0
@@ -31,25 +31,24 @@ export class Router {
31
31
  const snapshots = await collectProviderRuntimeSnapshots(this.registry.list(), hostServices);
32
32
  const planInput = buildSharedPlannerInput(request, snapshots, online, interactionMode);
33
33
  const outcome = await this.planner.planRoute(planInput);
34
- if (outcome.routePlan) {
35
- return this.selectFromSharedPlan(snapshots, outcome.routePlan);
34
+ if (!outcome.routePlan) {
35
+ // There is no second planner to degrade to: routing is the shared Rust
36
+ // core's semantics or nothing. Failing here keeps provider selection
37
+ // identical everywhere rather than forking it on a module load failure.
38
+ const reason = outcome.unavailableReason ?? "import_failed";
39
+ throw createInternal(`Route planner unavailable (${reason}).`, {
40
+ details: { plannerUnavailableReason: reason }
41
+ });
36
42
  }
37
- return this.selectFallbackRoute(request, snapshots, online, interactionMode, outcome.unavailableReason);
43
+ return this.selectFromSharedPlan(snapshots, outcome.routePlan);
38
44
  }
39
45
  selectFromSharedPlan(snapshots, routePlan) {
40
46
  if (!routePlan.selectedProviderId) {
41
47
  throw this.routePlanFailure(routePlan);
42
48
  }
43
- return this.buildSelectionFromRoutePlan(snapshots, routePlan, "wasm");
44
- }
45
- selectFallbackRoute(request, snapshots, online, interactionMode, plannerUnavailableReason) {
46
- const plan = this.createFallbackPlan(request, snapshots, online, interactionMode);
47
- if (!plan.selectedProviderId) {
48
- throw this.routePlanFailure(plan);
49
- }
50
- return this.buildSelectionFromRoutePlan(snapshots, plan, "fallback", plannerUnavailableReason);
49
+ return this.buildSelectionFromRoutePlan(snapshots, routePlan);
51
50
  }
52
- buildSelectionFromRoutePlan(snapshots, routePlan, plannerSource, plannerUnavailableReason) {
51
+ buildSelectionFromRoutePlan(snapshots, routePlan) {
53
52
  const orderedProviders = routePlan.candidates
54
53
  .map((candidate) => snapshots.find((snapshot) => snapshot.descriptor.id === candidate.providerId))
55
54
  .filter((snapshot) => snapshot !== undefined);
@@ -61,202 +60,9 @@ export class Router {
61
60
  provider: selected.provider,
62
61
  fallbackProviders: orderedProviders.slice(1).map((snapshot) => snapshot.provider),
63
62
  routePlan,
64
- explanation: routePlan.explanation.summary,
65
- plannerSource,
66
- ...(plannerUnavailableReason ? { plannerUnavailableReason } : {})
63
+ explanation: routePlan.explanation.summary
67
64
  };
68
65
  }
69
- /**
70
- * Hand-written mirror of the shared Rust planner (`rust/inderun-route-core/src/planner.rs`),
71
- * used when the WASM core cannot be loaded. It reproduces the same rejection
72
- * codes and messages so route explanations stay comparable across both paths.
73
- *
74
- * Known, deliberate divergence: this mirror keeps the id-sorted snapshot order
75
- * instead of reproducing the Rust placement/preference ranks, so `optimizeFor`
76
- * does not influence ordering here.
77
- */
78
- createFallbackPlan(request, snapshots, online, interactionMode) {
79
- const planInput = buildSharedPlannerInput(request, snapshots, online, interactionMode);
80
- const eligible = snapshots.filter((candidate) => candidate.descriptor.tasks.includes(planInput.task.kind));
81
- const localCandidates = eligible.filter((candidate) => candidate.descriptor.type !== "cloud");
82
- const cloudCandidates = eligible.filter((candidate) => candidate.descriptor.type === "cloud");
83
- // Constraint filtering must apply to the whole candidate list, not just the selected provider:
84
- // the remainder becomes the engine's fallback chain, and a fallback that violates the request
85
- // constraints would let a `local_required` run be retried against a cloud provider.
86
- const admissible = [];
87
- const rejectedProviders = [];
88
- for (const candidate of snapshots) {
89
- const reasons = this.evaluateFallbackCandidate(candidate, planInput, interactionMode);
90
- if (reasons.length === 0) {
91
- admissible.push(candidate);
92
- }
93
- else {
94
- rejectedProviders.push({ providerId: candidate.descriptor.id, reasons });
95
- }
96
- }
97
- if (admissible.length === 0) {
98
- const failureSummary = this.buildFallbackFailureSummary({
99
- online,
100
- interactionMode,
101
- taskKind: planInput.task.kind,
102
- constraints: planInput.constraints,
103
- localCandidates,
104
- cloudCandidates
105
- });
106
- const failureCode = this.inferFallbackFailureCode(planInput, rejectedProviders);
107
- return {
108
- fallbackProviderIds: [],
109
- candidates: [],
110
- rejectedProviders,
111
- failureCode,
112
- explanation: {
113
- summary: failureSummary
114
- }
115
- };
116
- }
117
- const selectedProviderId = admissible[0]?.descriptor.id;
118
- const summary = interactionMode === "stream"
119
- ? `Selected streaming provider '${selectedProviderId}' deterministically from ${admissible.length} eligible candidate(s).`
120
- : `Selected provider '${selectedProviderId}' deterministically from ${admissible.length} eligible candidate(s).`;
121
- return {
122
- selectedProviderId,
123
- fallbackProviderIds: admissible.slice(1).map((candidate) => candidate.descriptor.id),
124
- candidates: admissible.map((candidate, index) => ({
125
- providerId: candidate.descriptor.id,
126
- order: index
127
- })),
128
- rejectedProviders,
129
- explanation: {
130
- summary,
131
- selectedProviderId
132
- }
133
- };
134
- }
135
- /**
136
- * Mirrors `infer_failure_code` in the shared Rust planner. The offline class is
137
- * derived from the rejection reasons rather than from the connectivity flag
138
- * alone: an offline host whose only provider is local and non-streaming failed
139
- * on capability, not on connectivity, and reporting `Offline` there would
140
- * contradict the explanation shipped alongside it.
141
- */
142
- inferFallbackFailureCode(planInput, rejectedProviders) {
143
- if (rejectedProviders.some((rejected) => rejected.reasons.some((reason) => reason.code === "offline"))) {
144
- return "offline";
145
- }
146
- if (planInput.constraints.cloud === "required" ||
147
- planInput.constraints.privacy === "cloud_required") {
148
- return "unavailable";
149
- }
150
- return "capability_mismatch";
151
- }
152
- /**
153
- * Mirrors `evaluate_provider` in the shared Rust planner: it accumulates every
154
- * violated rule rather than short-circuiting, so a rejected provider carries a
155
- * complete explanation. The streaming checks are ordered static-before-dynamic
156
- * for the same reason as in Rust — a provider that never declared streaming
157
- * must not also be reported as dynamically unavailable.
158
- */
159
- evaluateFallbackCandidate(candidate, planInput, interactionMode) {
160
- const descriptor = candidate.descriptor;
161
- const capabilities = candidate.capabilities;
162
- const constraints = planInput.constraints;
163
- const wantsStream = interactionMode === "stream";
164
- const reasons = [];
165
- // Mirrors `is_data_private` in the shared Rust planner: a provider is private when it
166
- // declares that data does not leave the device, defaulting to non-cloud providers.
167
- const isDataPrivate = descriptor.privacy
168
- ? !descriptor.privacy.dataLeavesDevice
169
- : descriptor.type !== "cloud";
170
- if (!descriptor.tasks.includes(planInput.task.kind)) {
171
- reasons.push({
172
- code: "task_not_supported",
173
- message: `Provider '${descriptor.id}' does not support task '${planInput.task.kind}'.`
174
- });
175
- }
176
- if (!wantsStream && !descriptor.supports.run) {
177
- reasons.push({
178
- code: "run_not_supported",
179
- message: `Provider '${descriptor.id}' does not support run().`
180
- });
181
- }
182
- if (wantsStream) {
183
- if (!descriptor.supports.streaming) {
184
- reasons.push({
185
- code: "streaming_not_supported",
186
- message: `Provider '${descriptor.id}' does not support streaming (Mode 2).`
187
- });
188
- }
189
- else if (capabilities.streamingAvailable === false) {
190
- reasons.push({
191
- code: "streaming_unavailable",
192
- message: capabilities.streamingUnavailableReason ??
193
- `Provider '${descriptor.id}' cannot stream in the current host environment.`
194
- });
195
- }
196
- }
197
- if (constraints.privacy === "local_required" && !isDataPrivate) {
198
- reasons.push({
199
- code: "privacy_constraint",
200
- message: `Provider '${descriptor.id}' does not satisfy local-required privacy.`
201
- });
202
- }
203
- if (constraints.privacy === "cloud_required" && descriptor.type !== "cloud") {
204
- reasons.push({
205
- code: "privacy_constraint",
206
- message: `Provider '${descriptor.id}' does not satisfy cloud-required privacy.`
207
- });
208
- }
209
- if (constraints.cloud === "forbidden" && descriptor.type === "cloud") {
210
- reasons.push({
211
- code: "cloud_constraint",
212
- message: `Provider '${descriptor.id}' is cloud-based but cloud execution is forbidden.`
213
- });
214
- }
215
- if (constraints.cloud === "required" && descriptor.type !== "cloud") {
216
- reasons.push({
217
- code: "cloud_constraint",
218
- message: `Provider '${descriptor.id}' is not cloud-based but cloud execution is required.`
219
- });
220
- }
221
- if (constraints.networkOnline === false && descriptor.type === "cloud") {
222
- reasons.push({
223
- code: "offline",
224
- message: `Provider '${descriptor.id}' requires cloud connectivity, but the host is offline.`
225
- });
226
- }
227
- if (!capabilities.available) {
228
- reasons.push({
229
- code: "capability_unavailable",
230
- message: capabilities.reason ?? `Provider '${descriptor.id}' is currently unavailable.`
231
- });
232
- }
233
- return reasons;
234
- }
235
- buildFallbackFailureSummary(input) {
236
- const wantsCloud = input.constraints.cloud === "required" || input.constraints.privacy === "cloud_required";
237
- const wantsLocal = input.constraints.privacy === "local_required";
238
- if (!input.online && (wantsCloud || input.cloudCandidates.length > 0)) {
239
- return "No network connection is available.";
240
- }
241
- if (wantsCloud) {
242
- if (input.cloudCandidates.length === 0) {
243
- return "No cloud provider found.";
244
- }
245
- return "No cloud provider is currently available.";
246
- }
247
- if (wantsLocal) {
248
- if (input.localCandidates.length === 0) {
249
- return "No on-device provider found.";
250
- }
251
- return "No on-device provider is currently available.";
252
- }
253
- if (input.interactionMode === "stream") {
254
- // Kept verbatim in sync with the shared Rust planner's stream-mode failure
255
- // summary so the message a caller sees does not depend on which planner ran.
256
- return `No provider capable of streaming was found for task '${input.taskKind}'.`;
257
- }
258
- return "No eligible provider found for the current routing constraints.";
259
- }
260
66
  /**
261
67
  * Routing failure throws before any `route_decided` telemetry is emitted, so the
262
68
  * plan's diagnostics are attached to the exception — that is the only channel
package/dist/index.d.ts CHANGED
@@ -1,13 +1,76 @@
1
+ /**
2
+ * Unified entry point for the IndeRun Web SDK (`@independo/inderun-web`).
3
+ *
4
+ * Everything a browser app needs to run and stream tasks is exported from here:
5
+ * the engine, the routing and provider seams, host services, error and telemetry
6
+ * types, and the contract types the SDK's own signatures use. Provider adapters
7
+ * are the deliberate exception — each ships from its own subpath
8
+ * (`/openai`, `/onnx`, `/system-model`) so this surface stays provider-agnostic.
9
+ */
10
+ /**
11
+ * Host services: the platform capabilities the engine reads and calls through,
12
+ * and the seams an embedder overrides to supply its own (custom transport,
13
+ * credential storage, clock).
14
+ */
1
15
  export { type AbortSignalLike, type ConnectivityService, type DeviceConstraintsService, type SecureStorageService, type ClockService, type HttpClientService, type HttpRequest, type HttpResponse, type HttpStreamResponse, type HttpStreamingClientService, type HostServices, type ThermalState } from "./core/host.js";
16
+ /**
17
+ * The provider contract. Implement `ProviderAdapter` for a Mode 1 backend and add
18
+ * a `stream` for Mode 2; the descriptor and dynamic capability check are what the
19
+ * router plans against.
20
+ */
2
21
  export { type ProviderDescriptor, type ProviderDynamicCapabilities, type ProviderCapabilitySnapshot, type RunContext, type ProviderAdapter, type ProviderStreamContext, type ProviderStreamEvent, type StreamRun } from "./core/provider.js";
22
+ /**
23
+ * Per-run gatekeeper for a Mode 2 stream: assigns the sequence numbers callers
24
+ * order by, and enforces that exactly one terminal outcome is produced with
25
+ * nothing admitted after it. Exported for embedders driving a stream themselves.
26
+ */
3
27
  export { EventGate } from "./core/event-gate.js";
28
+ /** Holds the provider adapters a given engine instance can route to. */
4
29
  export { ProviderRegistry } from "./core/registry.js";
30
+ /**
31
+ * Route selection. `Router` turns a request plus a host capability snapshot into
32
+ * a provider chain; `WasmRoutePlanner` is the shared Rust planner behind it, and
33
+ * the only planner the Web SDK has — there is no JavaScript fallback.
34
+ */
5
35
  export { type RouteSelection, Router } from "./core/router.js";
6
36
  export { type RoutePlanner, type PlannerOutcome, type WasmUnavailableReason, type SharedPlannerInput, type SharedPlannerRoutePlan, WasmRoutePlanner } from "./core/route-planner.js";
37
+ /**
38
+ * The normalized error taxonomy. Every failure the SDK surfaces is an
39
+ * `IndeRunException` in one of these classes, whatever the provider raised.
40
+ */
7
41
  export { type IndeRunExceptionParams, IndeRunException, createCapabilityMismatch, createOffline, createAuthError, createRateLimited, createTimeout, createUnavailable, createInternal, toIndeRunException } from "./core/errors.js";
42
+ /** The engine itself, and the app-facing API surface it implements. */
8
43
  export { IndeRun, type StreamHandleResult } from "./core/engine.js";
9
44
  export type { IndeRunApi } from "./core/generated/inderun-api.js";
45
+ /**
46
+ * The contract types this SDK's own signatures take and return.
47
+ *
48
+ * Re-exported so a typed app needs only the one dependency the README tells it to
49
+ * install. `@independo/inderun-contracts` is ours transitively, and under pnpm's
50
+ * isolated `node_modules` an undeclared import of it does not resolve at all.
51
+ * This is the npm counterpart of Gradle `api(...)` on Android and `@_exported
52
+ * import` on Swift — see
53
+ * {@link https://github.com/independo-gmbh/inderun/issues/189 | #189}. The
54
+ * host-service and telemetry blocks in this file re-export their halves of the
55
+ * same contract surface for the same reason.
56
+ *
57
+ * Depend on `@independo/inderun-contracts` directly only for what is not
58
+ * re-exported here: the JSON Schemas and the `get*ValidationIssues` validators.
59
+ */
60
+ export type { IndeRunError, IndeRunErrorClass, StreamEvent, StreamRunHandle, StreamTerminalOutcome, TaskRequest, TaskResult } from "@independo/inderun-contracts";
61
+ /**
62
+ * Telemetry. Pass a `TelemetryService` to observe routing decisions and attempt
63
+ * outcomes; the engine defaults to `NoOpTelemetryService`.
64
+ */
10
65
  export { type TelemetryEventType, type TelemetryEvent, type TelemetryService, NoOpTelemetryService } from "./core/telemetry.js";
66
+ /**
67
+ * The browser implementations of the host services above, and the factory that
68
+ * assembles them. Use these directly only when constructing `IndeRun` by hand.
69
+ */
11
70
  export { BrowserConnectivityService, FetchHttpClient, FetchStreamingHttpClient, SystemClockService, createBrowserHostServices, type CreateBrowserHostServicesOptions, type FetchHttpClientOptions } from "./core/browser-host.js";
71
+ /**
72
+ * The recommended way in: builds host services, registers the providers named in
73
+ * the options, and returns a ready engine.
74
+ */
12
75
  export { createIndeRunWeb, type CreateIndeRunWebOptions } from "./web-sdk.js";
13
76
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,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,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,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,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;GAIG;AACH,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;GAIG;AACH,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;;;GAGG;AACH,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,uEAAuE;AACvE,OAAO,EAAE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,UAAU,EACX,MAAM,8BAA8B,CAAC;AAEtC;;;GAGG;AACH,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAEhC;;;GAGG;AACH,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,13 +1,58 @@
1
+ /**
2
+ * Unified entry point for the IndeRun Web SDK (`@independo/inderun-web`).
3
+ *
4
+ * Everything a browser app needs to run and stream tasks is exported from here:
5
+ * the engine, the routing and provider seams, host services, error and telemetry
6
+ * types, and the contract types the SDK's own signatures use. Provider adapters
7
+ * are the deliberate exception — each ships from its own subpath
8
+ * (`/openai`, `/onnx`, `/system-model`) so this surface stays provider-agnostic.
9
+ */
10
+ /**
11
+ * Host services: the platform capabilities the engine reads and calls through,
12
+ * and the seams an embedder overrides to supply its own (custom transport,
13
+ * credential storage, clock).
14
+ */
1
15
  export {} from "./core/host.js";
16
+ /**
17
+ * The provider contract. Implement `ProviderAdapter` for a Mode 1 backend and add
18
+ * a `stream` for Mode 2; the descriptor and dynamic capability check are what the
19
+ * router plans against.
20
+ */
2
21
  export {} from "./core/provider.js";
22
+ /**
23
+ * Per-run gatekeeper for a Mode 2 stream: assigns the sequence numbers callers
24
+ * order by, and enforces that exactly one terminal outcome is produced with
25
+ * nothing admitted after it. Exported for embedders driving a stream themselves.
26
+ */
3
27
  export { EventGate } from "./core/event-gate.js";
28
+ /** Holds the provider adapters a given engine instance can route to. */
4
29
  export { ProviderRegistry } from "./core/registry.js";
30
+ /**
31
+ * Route selection. `Router` turns a request plus a host capability snapshot into
32
+ * a provider chain; `WasmRoutePlanner` is the shared Rust planner behind it, and
33
+ * the only planner the Web SDK has — there is no JavaScript fallback.
34
+ */
5
35
  export { Router } from "./core/router.js";
6
36
  export { WasmRoutePlanner } from "./core/route-planner.js";
37
+ /**
38
+ * The normalized error taxonomy. Every failure the SDK surfaces is an
39
+ * `IndeRunException` in one of these classes, whatever the provider raised.
40
+ */
7
41
  export { IndeRunException, createCapabilityMismatch, createOffline, createAuthError, createRateLimited, createTimeout, createUnavailable, createInternal, toIndeRunException } from "./core/errors.js";
42
+ /** The engine itself, and the app-facing API surface it implements. */
8
43
  export { IndeRun } from "./core/engine.js";
44
+ /**
45
+ * Telemetry. Pass a `TelemetryService` to observe routing decisions and attempt
46
+ * outcomes; the engine defaults to `NoOpTelemetryService`.
47
+ */
9
48
  export { NoOpTelemetryService } from "./core/telemetry.js";
49
+ /**
50
+ * The browser implementations of the host services above, and the factory that
51
+ * assembles them. Use these directly only when constructing `IndeRun` by hand.
52
+ */
10
53
  export { BrowserConnectivityService, FetchHttpClient, FetchStreamingHttpClient, SystemClockService, createBrowserHostServices } from "./core/browser-host.js";
54
+ /**
55
+ * The recommended way in: builds host services, registers the providers named in
56
+ * the options, and returns a ready engine.
57
+ */
11
58
  export { createIndeRunWeb } from "./web-sdk.js";
12
- // The OpenAI Responses adapter is provider-specific and intentionally excluded
13
- // from this unified index. Import it from "@independo/inderun-web/openai".
package/dist/onnx.d.ts CHANGED
@@ -6,8 +6,29 @@
6
6
  * when registering the adapter manually or when implementing a custom
7
7
  * `OnnxTextGenerationRuntime`; most browser apps should pass `onnx` to
8
8
  * `createIndeRunWeb` from the main entry point instead.
9
+ *
10
+ * See {@link https://github.com/independo-gmbh/inderun/blob/main/docs/architecture/onnx-runtime-provider-family.md | the ONNX Runtime provider family doc}
11
+ * for the model IO contract, supported source types, and error mapping.
9
12
  */
13
+ /** The adapter itself, plus the source types and default id the router plans against. */
10
14
  export { OnnxRuntimeWebProvider, DEFAULT_ONNX_WEB_PROVIDER_ID, SUPPORTED_WEB_MODEL_SOURCE_TYPES, type OnnxProviderOptions } from "./providers/onnx/provider.js";
15
+ /**
16
+ * The runtime seam. The provider does no inference itself: it delegates to an
17
+ * `OnnxTextGenerationRuntime`, so an app can swap in its own engine, or
18
+ * `createFixtureOnnxRuntime()` for demos and tests without shipping a model.
19
+ */
11
20
  export { OnnxRuntimeError, createFixtureOnnxRuntime, type FixtureOnnxRuntimeOptions, type OnnxGenerationInput, type OnnxGenerationMessage, type OnnxGenerationOutput, type OnnxRuntimeAvailability, type OnnxRuntimeErrorKind, type OnnxTextGenerationRuntime } from "./providers/onnx/runtime.js";
21
+ /**
22
+ * The model-description contract types this entry point's options take.
23
+ * Re-exported for the same reason as the contract types on the SDK index — see
24
+ * the note there.
25
+ */
26
+ export type { ModelPackage, ModelSourceType } from "@independo/inderun-contracts";
27
+ /**
28
+ * The default runtime, backed by `@huggingface/transformers`. That package is an
29
+ * optional peer dependency and is reached structurally through
30
+ * `TransformersModule`, so nothing here forces it on apps that supply their own
31
+ * runtime.
32
+ */
12
33
  export { createTransformersJsRuntime, type TransformersJsRuntimeOptions, type TransformersModule, type TransformersTextGenerator } from "./providers/onnx/transformers-runtime.js";
13
34
  //# sourceMappingURL=onnx.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"onnx.d.ts","sourceRoot":"","sources":["../src/onnx.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,gCAAgC,EAChC,KAAK,mBAAmB,EACzB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,2BAA2B,EAC3B,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC/B,MAAM,0CAA0C,CAAC"}
1
+ {"version":3,"file":"onnx.d.ts","sourceRoot":"","sources":["../src/onnx.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,yFAAyF;AACzF,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,gCAAgC,EAChC,KAAK,mBAAmB,EACzB,MAAM,8BAA8B,CAAC;AAEtC;;;;GAIG;AACH,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAElF;;;;;GAKG;AACH,OAAO,EACL,2BAA2B,EAC3B,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC/B,MAAM,0CAA0C,CAAC"}
package/dist/onnx.js CHANGED
@@ -6,7 +6,22 @@
6
6
  * when registering the adapter manually or when implementing a custom
7
7
  * `OnnxTextGenerationRuntime`; most browser apps should pass `onnx` to
8
8
  * `createIndeRunWeb` from the main entry point instead.
9
+ *
10
+ * See {@link https://github.com/independo-gmbh/inderun/blob/main/docs/architecture/onnx-runtime-provider-family.md | the ONNX Runtime provider family doc}
11
+ * for the model IO contract, supported source types, and error mapping.
9
12
  */
13
+ /** The adapter itself, plus the source types and default id the router plans against. */
10
14
  export { OnnxRuntimeWebProvider, DEFAULT_ONNX_WEB_PROVIDER_ID, SUPPORTED_WEB_MODEL_SOURCE_TYPES } from "./providers/onnx/provider.js";
15
+ /**
16
+ * The runtime seam. The provider does no inference itself: it delegates to an
17
+ * `OnnxTextGenerationRuntime`, so an app can swap in its own engine, or
18
+ * `createFixtureOnnxRuntime()` for demos and tests without shipping a model.
19
+ */
11
20
  export { OnnxRuntimeError, createFixtureOnnxRuntime } from "./providers/onnx/runtime.js";
21
+ /**
22
+ * The default runtime, backed by `@huggingface/transformers`. That package is an
23
+ * optional peer dependency and is reached structurally through
24
+ * `TransformersModule`, so nothing here forces it on apps that supply their own
25
+ * runtime.
26
+ */
12
27
  export { createTransformersJsRuntime } from "./providers/onnx/transformers-runtime.js";
package/dist/openai.d.ts CHANGED
@@ -5,6 +5,13 @@
5
5
  * surface stays provider-agnostic. Import from `@independo/inderun-web/openai`
6
6
  * when registering the adapter manually; most browser apps should use
7
7
  * `createIndeRunWeb` from the main entry point instead.
8
+ *
9
+ * Browser apps must point `endpointUrl` at a same-origin proxy that holds the
10
+ * API key server-side. Provider credentials must never reach the browser.
11
+ */
12
+ /**
13
+ * The adapter and its options. Runs Mode 1 and Mode 2 against any
14
+ * OpenAI-Responses-compatible endpoint, not just OpenAI's own.
8
15
  */
9
16
  export { OpenAIResponsesProvider, type OpenAIProviderOptions, DEFAULT_OPENAI_RESPONSES_ENDPOINT } from "./providers/openai/provider.js";
10
17
  //# sourceMappingURL=openai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../src/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,iCAAiC,EAClC,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../src/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;GAGG;AACH,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,iCAAiC,EAClC,MAAM,gCAAgC,CAAC"}
package/dist/openai.js CHANGED
@@ -5,5 +5,12 @@
5
5
  * surface stays provider-agnostic. Import from `@independo/inderun-web/openai`
6
6
  * when registering the adapter manually; most browser apps should use
7
7
  * `createIndeRunWeb` from the main entry point instead.
8
+ *
9
+ * Browser apps must point `endpointUrl` at a same-origin proxy that holds the
10
+ * API key server-side. Provider credentials must never reach the browser.
11
+ */
12
+ /**
13
+ * The adapter and its options. Runs Mode 1 and Mode 2 against any
14
+ * OpenAI-Responses-compatible endpoint, not just OpenAI's own.
8
15
  */
9
16
  export { OpenAIResponsesProvider, DEFAULT_OPENAI_RESPONSES_ENDPOINT } from "./providers/openai/provider.js";
@@ -6,8 +6,21 @@
6
6
  * when registering the adapter manually or when implementing a custom
7
7
  * `SystemModelRuntime`; most browser apps should pass `systemModel` to
8
8
  * `createIndeRunWeb` from the main entry point instead.
9
+ *
10
+ * "System model" means a model the browser itself manages, so availability is a
11
+ * richer answer than a boolean: it may be present, downloadable, mid-download, or
12
+ * blocked for a browser, device, or policy reason. The provider flattens every
13
+ * non-available state into one route rejection and carries the detail as text.
9
14
  */
15
+ /** The adapter itself, plus the default id the router plans against. */
10
16
  export { DEFAULT_SYSTEM_MODEL_WEB_PROVIDER_ID, SystemModelWebProvider, type SystemModelProviderOptions } from "./providers/system-model/provider.js";
17
+ /**
18
+ * The runtime seam. The provider delegates generation to a `SystemModelRuntime`,
19
+ * so an app can target a different browser API, or use
20
+ * `createFixtureSystemModelRuntime()` in demos and tests where no system model
21
+ * exists.
22
+ */
11
23
  export { SystemModelRuntimeError, createFixtureSystemModelRuntime, type FixtureSystemModelRuntimeOptions, type SystemModelAvailability, type SystemModelAvailabilityKind, type SystemModelGenerationInput, type SystemModelGenerationOutput, type SystemModelPromptMessage, type SystemModelRuntime, type SystemModelRuntimeErrorKind } from "./providers/system-model/runtime.js";
24
+ /** The default runtime, backed by Chrome's built-in Prompt API. */
12
25
  export { createChromePromptApiRuntime, type ChromePromptApiGenerationOptions, type ChromePromptApiRuntimeOptions, type PromptApiLanguageModel, type PromptApiSession } from "./providers/system-model/chrome-runtime.js";
13
26
  //# sourceMappingURL=system-model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"system-model.d.ts","sourceRoot":"","sources":["../src/system-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,oCAAoC,EACpC,sBAAsB,EACtB,KAAK,0BAA0B,EAChC,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,KAAK,gCAAgC,EACrC,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EACjC,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EACL,4BAA4B,EAC5B,KAAK,gCAAgC,EACrC,KAAK,6BAA6B,EAClC,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,4CAA4C,CAAC"}
1
+ {"version":3,"file":"system-model.d.ts","sourceRoot":"","sources":["../src/system-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,wEAAwE;AACxE,OAAO,EACL,oCAAoC,EACpC,sBAAsB,EACtB,KAAK,0BAA0B,EAChC,MAAM,sCAAsC,CAAC;AAE9C;;;;;GAKG;AACH,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,KAAK,gCAAgC,EACrC,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EACjC,MAAM,qCAAqC,CAAC;AAE7C,mEAAmE;AACnE,OAAO,EACL,4BAA4B,EAC5B,KAAK,gCAAgC,EACrC,KAAK,6BAA6B,EAClC,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,4CAA4C,CAAC"}
@@ -6,7 +6,20 @@
6
6
  * when registering the adapter manually or when implementing a custom
7
7
  * `SystemModelRuntime`; most browser apps should pass `systemModel` to
8
8
  * `createIndeRunWeb` from the main entry point instead.
9
+ *
10
+ * "System model" means a model the browser itself manages, so availability is a
11
+ * richer answer than a boolean: it may be present, downloadable, mid-download, or
12
+ * blocked for a browser, device, or policy reason. The provider flattens every
13
+ * non-available state into one route rejection and carries the detail as text.
9
14
  */
15
+ /** The adapter itself, plus the default id the router plans against. */
10
16
  export { DEFAULT_SYSTEM_MODEL_WEB_PROVIDER_ID, SystemModelWebProvider } from "./providers/system-model/provider.js";
17
+ /**
18
+ * The runtime seam. The provider delegates generation to a `SystemModelRuntime`,
19
+ * so an app can target a different browser API, or use
20
+ * `createFixtureSystemModelRuntime()` in demos and tests where no system model
21
+ * exists.
22
+ */
11
23
  export { SystemModelRuntimeError, createFixtureSystemModelRuntime } from "./providers/system-model/runtime.js";
24
+ /** The default runtime, backed by Chrome's built-in Prompt API. */
12
25
  export { createChromePromptApiRuntime } from "./providers/system-model/chrome-runtime.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@independo/inderun-web",
3
- "version": "0.3.0-dev.8",
4
- "description": "TypeScript/Web SDK for IndeRun.",
3
+ "version": "0.3.0",
4
+ "description": "On-device AI with automatic cloud fallback for web apps. Runs ONNX Runtime or the Chrome Prompt API in the browser and falls back to an OpenAI-compatible endpoint, with streaming and cancellation behind one API.",
5
5
  "license": "MIT",
6
6
  "author": {
7
7
  "name": "Independo GmbH",
@@ -11,7 +11,7 @@
11
11
  "bugs": "https://github.com/independo-gmbh/inderun/issues",
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "https://github.com/independo-gmbh/inderun.git",
14
+ "url": "git+https://github.com/independo-gmbh/inderun.git",
15
15
  "directory": "packages/inderun-web"
16
16
  },
17
17
  "publishConfig": {
@@ -21,9 +21,19 @@
21
21
  "keywords": [
22
22
  "inderun",
23
23
  "ai",
24
+ "llm",
24
25
  "sdk",
25
26
  "web",
26
- "llm",
27
+ "on-device",
28
+ "on-device-ai",
29
+ "local-llm",
30
+ "offline",
31
+ "cloud-fallback",
32
+ "streaming",
33
+ "onnx",
34
+ "onnxruntime",
35
+ "prompt-api",
36
+ "openai",
27
37
  "routing"
28
38
  ],
29
39
  "engines": {
@@ -52,11 +62,14 @@
52
62
  },
53
63
  "files": [
54
64
  "dist",
65
+ "src",
66
+ "!src/**/*.test.ts",
67
+ "!src/test",
55
68
  "README.md"
56
69
  ],
57
70
  "dependencies": {
58
- "@independo/inderun-contracts": "^0.3.0-dev.8",
59
- "@independo/inderun-route-core-wasm": "^0.3.0-dev.8"
71
+ "@independo/inderun-contracts": "^0.3.0",
72
+ "@independo/inderun-route-core-wasm": "^0.3.0"
60
73
  },
61
74
  "peerDependencies": {
62
75
  "@huggingface/transformers": "^4.0.0"
@@ -67,12 +80,13 @@
67
80
  }
68
81
  },
69
82
  "devDependencies": {
70
- "@types/node": "^26.2.0",
83
+ "@types/node": "^26.5.1",
71
84
  "typescript": "^6.0.3",
72
85
  "vitest": "^4.1.11"
73
86
  },
74
87
  "scripts": {
75
88
  "build": "tsc -p tsconfig.json",
76
- "test": "vitest run"
89
+ "test": "vitest run",
90
+ "verify:packaging": "publint && attw --pack . --profile esm-only"
77
91
  }
78
92
  }