@independo/inderun-web 0.3.0-dev.12 → 0.3.0-dev.14
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 +2 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -2
- package/dist/onnx.d.ts +21 -0
- package/dist/onnx.d.ts.map +1 -1
- package/dist/onnx.js +15 -0
- package/dist/openai.d.ts +7 -0
- package/dist/openai.d.ts.map +1 -1
- package/dist/openai.js +7 -0
- package/dist/system-model.d.ts +13 -0
- package/dist/system-model.d.ts.map +1 -1
- package/dist/system-model.js +13 -0
- package/package.json +10 -6
- package/src/core/browser-host.ts +339 -0
- package/src/core/engine.ts +540 -0
- package/src/core/errors.ts +220 -0
- package/src/core/event-gate.ts +71 -0
- package/src/core/generated/inderun-api.ts +19 -0
- package/src/core/host.ts +15 -0
- package/src/core/provider.ts +231 -0
- package/src/core/registry.ts +48 -0
- package/src/core/route-planner.ts +261 -0
- package/src/core/router.ts +149 -0
- package/src/core/sse.ts +134 -0
- package/src/core/telemetry.ts +20 -0
- package/src/index.ts +147 -0
- package/src/onnx.ts +57 -0
- package/src/openai.ts +21 -0
- package/src/providers/onnx/provider.ts +300 -0
- package/src/providers/onnx/runtime.ts +188 -0
- package/src/providers/onnx/transformers-runtime.ts +345 -0
- package/src/providers/openai/provider.ts +765 -0
- package/src/providers/system-model/chrome-runtime.ts +221 -0
- package/src/providers/system-model/provider.ts +260 -0
- package/src/providers/system-model/runtime.ts +202 -0
- package/src/system-model.ts +49 -0
- package/src/web-sdk.ts +114 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
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
|
+
/**
|
|
12
|
+
* Host services: the platform capabilities the engine reads and calls through,
|
|
13
|
+
* and the seams an embedder overrides to supply its own (custom transport,
|
|
14
|
+
* credential storage, clock).
|
|
15
|
+
*/
|
|
16
|
+
export {
|
|
17
|
+
type AbortSignalLike,
|
|
18
|
+
type ConnectivityService,
|
|
19
|
+
type DeviceConstraintsService,
|
|
20
|
+
type SecureStorageService,
|
|
21
|
+
type ClockService,
|
|
22
|
+
type HttpClientService,
|
|
23
|
+
type HttpRequest,
|
|
24
|
+
type HttpResponse,
|
|
25
|
+
type HttpStreamResponse,
|
|
26
|
+
type HttpStreamingClientService,
|
|
27
|
+
type HostServices,
|
|
28
|
+
type ThermalState
|
|
29
|
+
} from "./core/host.js";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The provider contract. Implement `ProviderAdapter` for a Mode 1 backend and add
|
|
33
|
+
* a `stream` for Mode 2; the descriptor and dynamic capability check are what the
|
|
34
|
+
* router plans against.
|
|
35
|
+
*/
|
|
36
|
+
export {
|
|
37
|
+
type ProviderDescriptor,
|
|
38
|
+
type ProviderDynamicCapabilities,
|
|
39
|
+
type ProviderCapabilitySnapshot,
|
|
40
|
+
type RunContext,
|
|
41
|
+
type ProviderAdapter,
|
|
42
|
+
type ProviderStreamContext,
|
|
43
|
+
type ProviderStreamEvent,
|
|
44
|
+
type StreamRun
|
|
45
|
+
} from "./core/provider.js";
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Per-run gatekeeper for a Mode 2 stream: assigns the sequence numbers callers
|
|
49
|
+
* order by, and enforces that exactly one terminal outcome is produced with
|
|
50
|
+
* nothing admitted after it. Exported for embedders driving a stream themselves.
|
|
51
|
+
*/
|
|
52
|
+
export { EventGate } from "./core/event-gate.js";
|
|
53
|
+
|
|
54
|
+
/** Holds the provider adapters a given engine instance can route to. */
|
|
55
|
+
export { ProviderRegistry } from "./core/registry.js";
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Route selection. `Router` turns a request plus a host capability snapshot into
|
|
59
|
+
* a provider chain; `WasmRoutePlanner` is the shared Rust planner behind it, and
|
|
60
|
+
* the only planner the Web SDK has — there is no JavaScript fallback.
|
|
61
|
+
*/
|
|
62
|
+
export { type RouteSelection, Router } from "./core/router.js";
|
|
63
|
+
export {
|
|
64
|
+
type RoutePlanner,
|
|
65
|
+
type PlannerOutcome,
|
|
66
|
+
type WasmUnavailableReason,
|
|
67
|
+
type SharedPlannerInput,
|
|
68
|
+
type SharedPlannerRoutePlan,
|
|
69
|
+
WasmRoutePlanner
|
|
70
|
+
} from "./core/route-planner.js";
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The normalized error taxonomy. Every failure the SDK surfaces is an
|
|
74
|
+
* `IndeRunException` in one of these classes, whatever the provider raised.
|
|
75
|
+
*/
|
|
76
|
+
export {
|
|
77
|
+
type IndeRunExceptionParams,
|
|
78
|
+
IndeRunException,
|
|
79
|
+
createCapabilityMismatch,
|
|
80
|
+
createOffline,
|
|
81
|
+
createAuthError,
|
|
82
|
+
createRateLimited,
|
|
83
|
+
createTimeout,
|
|
84
|
+
createUnavailable,
|
|
85
|
+
createInternal,
|
|
86
|
+
toIndeRunException
|
|
87
|
+
} from "./core/errors.js";
|
|
88
|
+
|
|
89
|
+
/** The engine itself, and the app-facing API surface it implements. */
|
|
90
|
+
export { IndeRun, type StreamHandleResult } from "./core/engine.js";
|
|
91
|
+
export type { IndeRunApi } from "./core/generated/inderun-api.js";
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The contract types this SDK's own signatures take and return.
|
|
95
|
+
*
|
|
96
|
+
* Re-exported so a typed app needs only the one dependency the README tells it to
|
|
97
|
+
* install. `@independo/inderun-contracts` is ours transitively, and under pnpm's
|
|
98
|
+
* isolated `node_modules` an undeclared import of it does not resolve at all.
|
|
99
|
+
* This is the npm counterpart of Gradle `api(...)` on Android and `@_exported
|
|
100
|
+
* import` on Swift — see
|
|
101
|
+
* {@link https://github.com/independo-gmbh/inderun/issues/189 | #189}. The
|
|
102
|
+
* host-service and telemetry blocks in this file re-export their halves of the
|
|
103
|
+
* same contract surface for the same reason.
|
|
104
|
+
*
|
|
105
|
+
* Depend on `@independo/inderun-contracts` directly only for what is not
|
|
106
|
+
* re-exported here: the JSON Schemas and the `get*ValidationIssues` validators.
|
|
107
|
+
*/
|
|
108
|
+
export type {
|
|
109
|
+
IndeRunError,
|
|
110
|
+
IndeRunErrorClass,
|
|
111
|
+
StreamEvent,
|
|
112
|
+
StreamRunHandle,
|
|
113
|
+
StreamTerminalOutcome,
|
|
114
|
+
TaskRequest,
|
|
115
|
+
TaskResult
|
|
116
|
+
} from "@independo/inderun-contracts";
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Telemetry. Pass a `TelemetryService` to observe routing decisions and attempt
|
|
120
|
+
* outcomes; the engine defaults to `NoOpTelemetryService`.
|
|
121
|
+
*/
|
|
122
|
+
export {
|
|
123
|
+
type TelemetryEventType,
|
|
124
|
+
type TelemetryEvent,
|
|
125
|
+
type TelemetryService,
|
|
126
|
+
NoOpTelemetryService
|
|
127
|
+
} from "./core/telemetry.js";
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The browser implementations of the host services above, and the factory that
|
|
131
|
+
* assembles them. Use these directly only when constructing `IndeRun` by hand.
|
|
132
|
+
*/
|
|
133
|
+
export {
|
|
134
|
+
BrowserConnectivityService,
|
|
135
|
+
FetchHttpClient,
|
|
136
|
+
FetchStreamingHttpClient,
|
|
137
|
+
SystemClockService,
|
|
138
|
+
createBrowserHostServices,
|
|
139
|
+
type CreateBrowserHostServicesOptions,
|
|
140
|
+
type FetchHttpClientOptions
|
|
141
|
+
} from "./core/browser-host.js";
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The recommended way in: builds host services, registers the providers named in
|
|
145
|
+
* the options, and returns a ready engine.
|
|
146
|
+
*/
|
|
147
|
+
export { createIndeRunWeb, type CreateIndeRunWebOptions } from "./web-sdk.js";
|
package/src/onnx.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-specific entry point for the Web member of the ONNX Runtime provider family.
|
|
3
|
+
*
|
|
4
|
+
* Kept out of the unified SDK index (`@independo/inderun-web`) so the top-level
|
|
5
|
+
* surface stays provider-agnostic. Import from `@independo/inderun-web/onnx`
|
|
6
|
+
* when registering the adapter manually or when implementing a custom
|
|
7
|
+
* `OnnxTextGenerationRuntime`; most browser apps should pass `onnx` to
|
|
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.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** The adapter itself, plus the source types and default id the router plans against. */
|
|
15
|
+
export {
|
|
16
|
+
OnnxRuntimeWebProvider,
|
|
17
|
+
DEFAULT_ONNX_WEB_PROVIDER_ID,
|
|
18
|
+
SUPPORTED_WEB_MODEL_SOURCE_TYPES,
|
|
19
|
+
type OnnxProviderOptions
|
|
20
|
+
} from "./providers/onnx/provider.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The runtime seam. The provider does no inference itself: it delegates to an
|
|
24
|
+
* `OnnxTextGenerationRuntime`, so an app can swap in its own engine, or
|
|
25
|
+
* `createFixtureOnnxRuntime()` for demos and tests without shipping a model.
|
|
26
|
+
*/
|
|
27
|
+
export {
|
|
28
|
+
OnnxRuntimeError,
|
|
29
|
+
createFixtureOnnxRuntime,
|
|
30
|
+
type FixtureOnnxRuntimeOptions,
|
|
31
|
+
type OnnxGenerationInput,
|
|
32
|
+
type OnnxGenerationMessage,
|
|
33
|
+
type OnnxGenerationOutput,
|
|
34
|
+
type OnnxRuntimeAvailability,
|
|
35
|
+
type OnnxRuntimeErrorKind,
|
|
36
|
+
type OnnxTextGenerationRuntime
|
|
37
|
+
} from "./providers/onnx/runtime.js";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The model-description contract types this entry point's options take.
|
|
41
|
+
* Re-exported for the same reason as the contract types on the SDK index — see
|
|
42
|
+
* the note there.
|
|
43
|
+
*/
|
|
44
|
+
export type { ModelPackage, ModelSourceType } from "@independo/inderun-contracts";
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The default runtime, backed by `@huggingface/transformers`. That package is an
|
|
48
|
+
* optional peer dependency and is reached structurally through
|
|
49
|
+
* `TransformersModule`, so nothing here forces it on apps that supply their own
|
|
50
|
+
* runtime.
|
|
51
|
+
*/
|
|
52
|
+
export {
|
|
53
|
+
createTransformersJsRuntime,
|
|
54
|
+
type TransformersJsRuntimeOptions,
|
|
55
|
+
type TransformersModule,
|
|
56
|
+
type TransformersTextGenerator
|
|
57
|
+
} from "./providers/onnx/transformers-runtime.js";
|
package/src/openai.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-specific entry point for the OpenAI Responses adapter.
|
|
3
|
+
*
|
|
4
|
+
* Kept out of the unified SDK index (`@independo/inderun-web`) so the top-level
|
|
5
|
+
* surface stays provider-agnostic. Import from `@independo/inderun-web/openai`
|
|
6
|
+
* when registering the adapter manually; most browser apps should use
|
|
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
|
+
/**
|
|
14
|
+
* The adapter and its options. Runs Mode 1 and Mode 2 against any
|
|
15
|
+
* OpenAI-Responses-compatible endpoint, not just OpenAI's own.
|
|
16
|
+
*/
|
|
17
|
+
export {
|
|
18
|
+
OpenAIResponsesProvider,
|
|
19
|
+
type OpenAIProviderOptions,
|
|
20
|
+
DEFAULT_OPENAI_RESPONSES_ENDPOINT
|
|
21
|
+
} from "./providers/openai/provider.js";
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getModelPackageValidationIssues,
|
|
3
|
+
type ModelPackage,
|
|
4
|
+
type ModelSourceType,
|
|
5
|
+
type TaskRequest,
|
|
6
|
+
type TaskResult
|
|
7
|
+
} from "@independo/inderun-contracts";
|
|
8
|
+
import {
|
|
9
|
+
createCapabilityMismatch,
|
|
10
|
+
createInternal,
|
|
11
|
+
createTimeout,
|
|
12
|
+
createUnavailable,
|
|
13
|
+
toIndeRunException,
|
|
14
|
+
type IndeRunException
|
|
15
|
+
} from "../../core/errors.js";
|
|
16
|
+
import type { HostServices } from "../../core/host.js";
|
|
17
|
+
import {
|
|
18
|
+
OnnxRuntimeError,
|
|
19
|
+
type OnnxGenerationMessage,
|
|
20
|
+
type OnnxGenerationOutput,
|
|
21
|
+
type OnnxTextGenerationRuntime
|
|
22
|
+
} from "./runtime.js";
|
|
23
|
+
import { createTransformersJsRuntime } from "./transformers-runtime.js";
|
|
24
|
+
import type {
|
|
25
|
+
ProviderAdapter,
|
|
26
|
+
ProviderDescriptor,
|
|
27
|
+
ProviderDynamicCapabilities,
|
|
28
|
+
RunContext
|
|
29
|
+
} from "../../core/provider.js";
|
|
30
|
+
|
|
31
|
+
/** Default provider id of the Web member of the ONNX Runtime provider family. */
|
|
32
|
+
export const DEFAULT_ONNX_WEB_PROVIDER_ID = "local.onnx.genai.web";
|
|
33
|
+
|
|
34
|
+
/** Task kind this provider implements in Milestone 2 (Mode 1 only). */
|
|
35
|
+
const TEXT_TO_TEXT = "text_to_text";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Model source types the Web member of the ONNX Runtime provider family can honor.
|
|
39
|
+
*
|
|
40
|
+
* `filesystem` is unsupported because browsers do not expose arbitrary local paths, and `remote`
|
|
41
|
+
* is deferred: hosts download model files themselves and then supply them as `bundled`,
|
|
42
|
+
* `app_managed`, or `programmatic`.
|
|
43
|
+
*/
|
|
44
|
+
export const SUPPORTED_WEB_MODEL_SOURCE_TYPES: readonly ModelSourceType[] = [
|
|
45
|
+
"registry",
|
|
46
|
+
"bundled",
|
|
47
|
+
"programmatic",
|
|
48
|
+
"app_managed"
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Configuration for the Web ONNX Runtime provider.
|
|
53
|
+
*/
|
|
54
|
+
export interface OnnxProviderOptions {
|
|
55
|
+
/**
|
|
56
|
+
* Provider id exposed in telemetry and routing explanations.
|
|
57
|
+
*/
|
|
58
|
+
id?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Provider-neutral bootstrap metadata describing the developer-supplied model.
|
|
61
|
+
*/
|
|
62
|
+
modelPackage: ModelPackage;
|
|
63
|
+
/**
|
|
64
|
+
* Runtime implementation used to execute generation. Defaults to the Transformers.js-backed
|
|
65
|
+
* runtime; applications can inject their own implementation of the seam.
|
|
66
|
+
*/
|
|
67
|
+
runtime?: OnnxTextGenerationRuntime;
|
|
68
|
+
/**
|
|
69
|
+
* Optional generation timeout in milliseconds. A request-level `constraints.timeoutMs` wins.
|
|
70
|
+
*/
|
|
71
|
+
timeoutMs?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Local provider adapter that executes Mode-1 text-to-text requests with a developer-supplied ONNX
|
|
76
|
+
* model in the browser.
|
|
77
|
+
*
|
|
78
|
+
* The adapter owns the IndeRun-facing contract (descriptor, capability checks, error taxonomy) and
|
|
79
|
+
* delegates execution to an injectable {@link OnnxTextGenerationRuntime}. ONNX Runtime execution
|
|
80
|
+
* backends (WASM, WebGPU, WebNN) stay behind that seam and are never public routing concepts.
|
|
81
|
+
*/
|
|
82
|
+
export class OnnxRuntimeWebProvider implements ProviderAdapter {
|
|
83
|
+
private readonly id: string;
|
|
84
|
+
private readonly modelPackage: ModelPackage;
|
|
85
|
+
private readonly runtime: OnnxTextGenerationRuntime;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Creates a Web ONNX Runtime provider.
|
|
89
|
+
* @param options - Model package plus optional id, runtime, and timeout overrides.
|
|
90
|
+
*/
|
|
91
|
+
constructor(private readonly options: OnnxProviderOptions) {
|
|
92
|
+
this.id = options.id ?? DEFAULT_ONNX_WEB_PROVIDER_ID;
|
|
93
|
+
this.modelPackage = options.modelPackage;
|
|
94
|
+
this.runtime = options.runtime ?? createTransformersJsRuntime();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Returns static metadata used by the router for deterministic provider selection.
|
|
99
|
+
*/
|
|
100
|
+
describe(): ProviderDescriptor {
|
|
101
|
+
return {
|
|
102
|
+
id: this.id,
|
|
103
|
+
type: "local",
|
|
104
|
+
transport: "in_process",
|
|
105
|
+
supports: {
|
|
106
|
+
run: true,
|
|
107
|
+
streaming: false,
|
|
108
|
+
realtime: false,
|
|
109
|
+
tools: false,
|
|
110
|
+
reasoningEvents: false,
|
|
111
|
+
structuredOutput: false,
|
|
112
|
+
multimodal: false
|
|
113
|
+
},
|
|
114
|
+
cancel: "soft",
|
|
115
|
+
tasks: getDeclaredTasks(this.modelPackage),
|
|
116
|
+
privacy: {
|
|
117
|
+
dataLeavesDevice: false
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Reports dynamic provider availability for the current host.
|
|
124
|
+
*
|
|
125
|
+
* Every failure below is provider-internal detail: the shared route planner flattens it into a
|
|
126
|
+
* single `capability_unavailable` rejection carrying the returned reason.
|
|
127
|
+
*
|
|
128
|
+
* @param _host - Host services available to the engine (unused; ONNX runs in-process).
|
|
129
|
+
*/
|
|
130
|
+
async capabilities(_host: HostServices): Promise<ProviderDynamicCapabilities> {
|
|
131
|
+
const issues = getModelPackageValidationIssues(this.modelPackage);
|
|
132
|
+
if (issues.length > 0) {
|
|
133
|
+
const summary = issues.map((issue) => `${issue.path} ${issue.message}`).join("; ");
|
|
134
|
+
return { available: false, reason: `model package malformed: ${summary}` };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const sourceType = this.modelPackage.source?.sourceType;
|
|
138
|
+
if (sourceType !== undefined && !SUPPORTED_WEB_MODEL_SOURCE_TYPES.includes(sourceType)) {
|
|
139
|
+
return {
|
|
140
|
+
available: false,
|
|
141
|
+
reason:
|
|
142
|
+
sourceType === "filesystem"
|
|
143
|
+
? "model source unavailable: 'filesystem' model sources are unsupported on Web because browsers cannot read arbitrary local paths."
|
|
144
|
+
: `model source unavailable: '${sourceType}' model sources are deferred on Web; supply model files as ${SUPPORTED_WEB_MODEL_SOURCE_TYPES.join(", ")}.`
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const platforms = this.modelPackage.runtime?.platforms;
|
|
149
|
+
if (Array.isArray(platforms) && platforms.length > 0 && !platforms.includes("web")) {
|
|
150
|
+
return {
|
|
151
|
+
available: false,
|
|
152
|
+
reason: `platform unsupported: the model package targets ${platforms.join(", ")} and does not list 'web'.`
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!getDeclaredTasks(this.modelPackage).includes(TEXT_TO_TEXT)) {
|
|
157
|
+
return {
|
|
158
|
+
available: false,
|
|
159
|
+
reason: `unsupported task: the model package declares ${getDeclaredTasks(this.modelPackage).join(", ")} and does not support '${TEXT_TO_TEXT}'.`
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return this.runtime.prepare(this.modelPackage);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Executes a normalized text-to-text task on the developer-supplied local ONNX model.
|
|
168
|
+
* @param request - Canonical IndeRun task request.
|
|
169
|
+
* @param context - Engine execution context containing run id and host services.
|
|
170
|
+
* @returns Normalized IndeRun task result.
|
|
171
|
+
* @throws IndeRunException mapped to the standard error taxonomy.
|
|
172
|
+
*/
|
|
173
|
+
async run(request: TaskRequest, context: RunContext): Promise<TaskResult> {
|
|
174
|
+
const availability = await this.capabilities(context.hostServices);
|
|
175
|
+
if (!availability.available) {
|
|
176
|
+
throw createCapabilityMismatch(
|
|
177
|
+
availability.reason ?? "ONNX Runtime Web provider is unavailable on this host.",
|
|
178
|
+
{ providerId: this.id, runId: context.runId }
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const messages = createMessages(request);
|
|
183
|
+
if (messages.length === 0) {
|
|
184
|
+
throw createInternal("ONNX Runtime Web provider requires a prompt or messages.", {
|
|
185
|
+
providerId: this.id,
|
|
186
|
+
runId: context.runId
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const timeoutMs = request.constraints?.timeoutMs ?? this.options.timeoutMs;
|
|
191
|
+
const controller = new AbortController();
|
|
192
|
+
const timer =
|
|
193
|
+
timeoutMs !== undefined && timeoutMs > 0
|
|
194
|
+
? setTimeout(() => controller.abort(), timeoutMs)
|
|
195
|
+
: undefined;
|
|
196
|
+
|
|
197
|
+
let output: OnnxGenerationOutput;
|
|
198
|
+
try {
|
|
199
|
+
output = await this.runtime.generate(
|
|
200
|
+
{
|
|
201
|
+
modelPackage: this.modelPackage,
|
|
202
|
+
messages,
|
|
203
|
+
...(request.generation !== undefined ? { generation: request.generation } : {})
|
|
204
|
+
},
|
|
205
|
+
controller.signal
|
|
206
|
+
);
|
|
207
|
+
} catch (err) {
|
|
208
|
+
throw this.mapRuntimeError(err, context);
|
|
209
|
+
} finally {
|
|
210
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (typeof output.text !== "string" || output.text.length === 0) {
|
|
214
|
+
throw createInternal("ONNX Runtime Web provider returned no text output.", {
|
|
215
|
+
providerId: this.id,
|
|
216
|
+
runId: context.runId
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const result: TaskResult = {
|
|
221
|
+
schemaVersion: "1.0",
|
|
222
|
+
runId: context.runId,
|
|
223
|
+
output: {
|
|
224
|
+
type: "text",
|
|
225
|
+
text: output.text
|
|
226
|
+
},
|
|
227
|
+
finishReason: output.finishReason ?? "stop",
|
|
228
|
+
telemetry: {
|
|
229
|
+
providerUsed: this.id,
|
|
230
|
+
totalMs: 0
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
if (output.usage) {
|
|
235
|
+
result.usage = output.usage;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private mapRuntimeError(error: unknown, context: RunContext): IndeRunException {
|
|
242
|
+
const extra = { providerId: this.id, runId: context.runId };
|
|
243
|
+
|
|
244
|
+
if (error instanceof OnnxRuntimeError) {
|
|
245
|
+
const details =
|
|
246
|
+
error.originalError !== undefined
|
|
247
|
+
? { details: { originalError: getErrorSummary(error.originalError) } }
|
|
248
|
+
: {};
|
|
249
|
+
|
|
250
|
+
switch (error.kind) {
|
|
251
|
+
case "capability":
|
|
252
|
+
return createCapabilityMismatch(error.message, { ...extra, ...details });
|
|
253
|
+
case "unavailable":
|
|
254
|
+
return createUnavailable(error.message, { ...extra, ...details });
|
|
255
|
+
case "timeout":
|
|
256
|
+
return createTimeout(error.message, { ...extra, ...details });
|
|
257
|
+
default:
|
|
258
|
+
return createInternal(error.message, { ...extra, ...details });
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (isAbortError(error)) {
|
|
263
|
+
return createTimeout("ONNX Runtime Web generation timed out.", extra);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return toIndeRunException(error, extra);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function getDeclaredTasks(modelPackage: ModelPackage): string[] {
|
|
271
|
+
const tasks = modelPackage.tasks;
|
|
272
|
+
return Array.isArray(tasks) && tasks.length > 0 ? tasks : [TEXT_TO_TEXT];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function createMessages(request: TaskRequest): OnnxGenerationMessage[] {
|
|
276
|
+
if (request.messages && request.messages.length > 0) {
|
|
277
|
+
return request.messages.map((message) => ({
|
|
278
|
+
role: message.role,
|
|
279
|
+
content: message.content
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const prompt = request.prompt;
|
|
284
|
+
return prompt !== undefined && prompt.length > 0 ? [{ role: "user", content: prompt }] : [];
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function isAbortError(error: unknown): boolean {
|
|
288
|
+
return (
|
|
289
|
+
typeof error === "object" &&
|
|
290
|
+
error !== null &&
|
|
291
|
+
(error as { name?: unknown }).name === "AbortError"
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function getErrorSummary(error: unknown): Record<string, unknown> {
|
|
296
|
+
if (error instanceof Error) {
|
|
297
|
+
return { name: error.name, message: error.message, stack: error.stack };
|
|
298
|
+
}
|
|
299
|
+
return { message: String(error) };
|
|
300
|
+
}
|