/** * @license * Copyright 2025 Steven Roussey * SPDX-License-Identifier: Apache-2.0 */ import type { WorkerServerBase as WorkerServer } from "@workglow/util/worker"; import type { Capability } from "../capability/Capabilities"; import type { ModelConfig, ModelRecord } from "../model/ModelSchema"; import type { AiProviderPreviewRunFn, AiProviderRunFnRegistration } from "./AiProviderRegistry"; /** * Job queue concurrency: one limit for the primary ({@link QueuedAiProvider} hardware) queue, * or per-slot limits. Hugging Face Transformers ONNX uses `gpu` and `cpu` for its two queues. */ export type AiProviderQueueConcurrency = number | Record; export declare const DEFAULT_AI_PROVIDER_WORKER_IDLE_TIMEOUT_MS: number; /** * Resolves the primary (e.g. WebGPU) queue limit for {@link QueuedAiProvider}. * A numeric `concurrency` sets that queue; a record uses `gpu` (default 1). */ export declare function resolveAiProviderGpuQueueConcurrency(concurrency: AiProviderQueueConcurrency | undefined): number; /** * Options for registering an AI provider on the main thread. * * - If the provider was constructed **with** run-fn registrations → **inline** * registration (direct streaming run fns). No `worker` option. * - If the provider was constructed **without** registrations → **worker** * registration (proxies). A `worker` (instance or lazy factory) is **required**. */ export interface AiProviderRegisterOptions { /** * Web Worker for worker-backed registration. Pass a `Worker` or a factory * `() => Worker` to defer instantiation until the first job (lazy worker). */ worker?: Worker | (() => Worker); /** * Idle timeout for factory-backed worker registrations. `0` disables idle termination. * Defaults to 15 minutes for AI providers when `worker` is a factory. */ workerIdleTimeoutMs?: number; /** Job queue configuration */ queue?: { /** * Concurrent jobs on the provider's primary queued path (e.g. GPU), default 1. * Use a record for multiple queues — e.g. `{ gpu: 1, cpu: 4 }` for Hugging Face * Transformers ONNX (`cpu` defaults to 4 in production and 1 under test when omitted). */ concurrency?: AiProviderQueueConcurrency; /** Set to false to skip automatic queue creation. Defaults to true. */ autoCreate?: boolean; }; } /** * Registration context passed to {@link AiProvider.onInitialize}, including whether * the provider is registering inline (run-fns present) or worker-backed (no run-fns). */ export interface AiProviderRegisterContext extends AiProviderRegisterOptions { readonly isInline: boolean; } /** * Abstract base class for AI providers. * * Each provider subclass declares static metadata (`name`, `displayName`, * `isLocal`, `supportsBrowser`). The actual run function implementations * are **injected via the constructor** as a list of capability-set * registrations so heavy ML library imports remain at the call site. This * allows the provider class to be imported on the main thread without pulling * in heavy dependencies when running in worker mode. * * The base class handles: * - Registering capability-set run functions with the AiProviderRegistry * (inline or worker proxies) * - Registering functions on a WorkerServer (for worker-side code) * - Lifecycle management (initialize / dispose) * * @example * ```typescript * // Worker host (main thread) -- lightweight, no heavy task imports: * await new MyProvider().register({ * worker: () => new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }), * }); * * // Inline -- caller provides the run-fn registrations (imports heavy library): * import { MY_RUN_FNS } from "./MyJobRunFns"; * await new MyProvider(MY_RUN_FNS).register(); * * // Worker side -- caller provides the run-fn registrations: * import { MY_RUN_FNS } from "./MyJobRunFns"; * new MyProvider(MY_RUN_FNS).registerOnWorkerServer(workerServer); * ``` */ export declare abstract class AiProvider { abstract readonly name: string; abstract readonly displayName: string; abstract readonly isLocal: boolean; abstract readonly supportsBrowser: boolean; /** * Whether this provider can run server-side (a Bun/Node host process). * Orthogonal to {@link isLocal}: a provider can be local (Ollama) yet * server-capable. builder maps `supportsBrowser` / `supportsServer` / * `isLocal` onto its own `browser | desktop | cloud` deployment taxonomy; * libs deliberately does not know those host names. */ abstract readonly supportsServer: boolean; /** * Promise+emit capability-set run-fn registrations injected via the constructor. * Required for inline and worker-server registration. Not needed for worker-mode * registration on the main thread (proxies are derived from {@link workerRunFnSpecs}). */ protected readonly promiseRunFns?: readonly AiProviderRunFnRegistration[]; /** * Map of task type names to their preview run functions. * Only needed for tasks that provide lightweight previews via executePreview(). */ protected readonly previewTasks?: Record>; constructor(promiseRunFns?: readonly AiProviderRunFnRegistration[], previewTasks?: Record>); /** * Infer the closed set of {@link Capability} values a model supports given its * record. The base implementation returns the model's stored `capabilities` * field (or `[]` if absent), letting providers opt out of inference and use * whatever the user set. Provider subclasses override this with real * heuristics (e.g., parse model id strings, hit provider catalog endpoints). * * Main-thread method only — workers do not run capability inference. */ inferCapabilities(model: ModelRecord): readonly Capability[]; /** * Runtime availability probe for environment-dependent providers (e.g. Chrome * AI, which needs `window.ai`). Returns `true` by default; providers whose * reachability depends on the host environment override it. Replaces the * renderer's ad-hoc `isChromeBuiltinAiAvailable` call as the uniform check. */ isAvailable(): Promise; /** * Register this provider on the main thread. * * Inferred from constructor: **with** run-fns → direct streaming run functions; * **without** run-fns → worker proxies (requires `worker` in options). * * Creates a job queue unless `queue.autoCreate` is set to false. * * @param options - Registration options (worker for worker-backed, queue config) */ register(options?: AiProviderRegisterOptions): Promise; /** * Returns the capability-sets to register as worker proxies when the * provider is registered without inline run-fns. Subclasses with worker * support override this to advertise the same `serves` sets that the * worker-side {@link registerOnWorkerServer} call will register. * * The base implementation derives specs from `promiseRunFns` when present. */ protected workerRunFnSpecs(): readonly { serves: readonly Capability[]; }[]; /** * Register this provider's run functions on a WorkerServer. * Call this inside a Web Worker to make the provider's functions * available for remote invocation from the main thread. * * Requires `promiseRunFns` to have been provided via the constructor. Each * registration is exposed under the deterministic key produced by * {@link workerKeyForServes} so the main-thread proxy resolves to the * matching run function. * * @param workerServer - The WorkerServer instance to register on */ registerOnWorkerServer(workerServer: WorkerServer): void; /** * Hook for provider-specific initialization. * Called at the start of `register()`, before any functions are registered. * Override in subclasses to perform setup (e.g., configuring WASM backends). */ protected onInitialize(_options: AiProviderRegisterContext): Promise; /** * Dispose of provider resources. * Override in subclasses to clean up (e.g., clearing pipeline caches). */ dispose(): Promise; /** * Create a session for the given model configuration. * Returns an opaque session ID that can be passed to run/stream functions * to reuse provider-side resources (e.g., a loaded pipeline or KV cache). * * The base implementation returns a random UUID; provider subclasses * (e.g., HF Transformers, llama-cpp) override this to allocate real resources. */ createSession(_model: ModelConfig): string; /** * Dispose of a previously created session. * Provider subclasses override this to release resources tied to the session. * The base implementation is a no-op. */ disposeSession(_sessionId: string): Promise; /** * Called at the end of {@link register} after registry wiring. * {@link QueuedAiProvider} overrides this to create the default job queue; the base * implementation is a no-op so worker-only provider classes stay free of queue/storage. */ protected afterRegister(_options: AiProviderRegisterOptions): Promise; } //# sourceMappingURL=AiProvider.d.ts.map