/** * @license * Copyright 2025 Steven Roussey * SPDX-License-Identifier: Apache-2.0 */ import { TaskInput, TaskOutput } from "@workglow/task-graph"; import type { JsonSchema, ServiceRegistry } from "@workglow/util/worker"; import type { AiEmit } from "../capability/AiEmit"; import type { Capability } from "../capability/Capabilities"; import type { AiStrategyResolver, IAiExecutionStrategy } from "../execution/IAiExecutionStrategy"; import type { ModelConfig } from "../model/ModelSchema"; import type { AiProvider } from "./AiProvider"; /** * Type for the preview run function for AiTask.executePreview(). * Computes a fast preview from input alone -- no prior output needed. * No `signal` or `update_progress` -- preview execution is lightweight and synchronous-ish. */ export type AiProviderPreviewRunFn = (input: Input, model: Model | undefined) => Promise; /** * Promise+emit run-fn shape. Output flows through `emit`; the Promise carries * no data and signals completion only. For one-shot capabilities the run-fn * emits a single `finish` event whose `data` carries the result. For streaming * capabilities the run-fn emits delta events and ends with an empty `finish`. * The run-fn MUST NOT accumulate — accumulation lives only at terminal * consumer sites (`AiTask.execute`, `StreamProcessor` `ctx.shouldAccumulate`). */ export type AiProviderRunFn = (input: Input, model: Model | undefined, signal: AbortSignal, emit: AiEmit, outputSchema?: JsonSchema, sessionId?: string) => Promise; /** * A capability-set registration for a provider Promise+emit run function. * * `serves` is the closed set of {@link Capability} values that the run function can * fulfil in a single invocation. The dispatcher matches a task's `requires` array * against `serves` using superset semantics (`requires.every(r => serves.includes(r))`) * and selects the most-specific match (smallest `serves` length wins, ties broken by * registration order). * * Example: * ```ts * { serves: ["text.generation"], runFn: runPlainGeneration } * { serves: ["text.generation", "tool-use"], runFn: runGenerationWithTools } * ``` * * A `requires: ["text.generation"]` lookup picks the plain entry; a * `requires: ["text.generation", "tool-use"]` lookup picks the tool-aware one. */ export interface AiProviderRunFnRegistration { readonly serves: readonly Capability[]; readonly runFn: AiProviderRunFn; } /** * Build the deterministic key used to register a `serves` set on a worker server * and to dispatch worker calls to it. Sorted alphabetically + comma-joined so the * key is stable across registrations and worker boundaries. * * Example: `["tool-use", "text.generation"]` → `"text.generation,tool-use"`. */ export declare function workerKeyForServes(serves: readonly Capability[]): string; /** * Registry that manages provider-specific task execution functions and job queues. */ export declare class AiProviderRegistry { /** * All capability-set registrations grouped by provider name. Each provider may * register multiple registrations whose `serves` sets cover different capability * combinations; lookup picks the most-specific superset of `requires`. */ private readonly runFnsByProvider; private readonly previewRunFnRegistry; private readonly providers; private readonly strategyResolvers; private defaultStrategy; registerProvider(provider: AiProvider): void; /** * Removes a previously registered provider and all of its run/stream/preview functions. * Used for cleanup when provider initialization fails partway through. */ unregisterProvider(name: string): void; getProvider(name: string): AiProvider | undefined; getProviders(): Map>; /** * Stable-sorted ids of all {@link AiProvider} instances currently registered * via {@link registerProvider} (typically after {@link AiProvider.register}). */ getInstalledProviderIds(): string[]; /** * Registers a strategy resolver for a provider. The resolver receives the full * ModelConfig at execution time and returns the appropriate execution strategy. * This allows model-aware decisions (e.g., HFT WebGPU → queued, HFT WASM → direct). */ registerStrategyResolver(providerName: string, resolver: AiStrategyResolver): void; /** * Sets the default execution strategy used when no provider-specific resolver * is registered. Useful in tests to inject a strategy without registering a * full provider. */ setDefaultStrategy(strategy: IAiExecutionStrategy): void; /** * Resolves the execution strategy for a given model config. * Falls back to DirectExecutionStrategy if no resolver is registered. */ getStrategy(model: ModelConfig): IAiExecutionStrategy; /** * Creates a session on the named provider. * @param providerName - The provider to create a session on * @param model - The model configuration for the session * @returns An opaque session ID * @throws If the provider is not registered */ createSession(providerName: string, model: ModelConfig): string; /** * Disposes a session on the named provider. Silently ignores unknown providers. * @param providerName - The provider that owns the session * @param sessionId - The session ID to dispose */ disposeSession(providerName: string, sessionId: string): Promise; /** * Stable-sorted provider ids whose registry contains at least one registration * whose `serves` set is a superset of `requires`. Use this when the UI or * validation should only offer providers that can execute a particular * capability set (e.g. {@link ModelSearchTask}). */ getProviderIdsForCapabilities(requires: readonly Capability[]): string[]; /** * Registers a Promise+emit run function under a capability-set for the given * provider. Multiple registrations per provider are supported -- dispatch * picks the smallest `serves` set that is a superset of the task's `requires`. * * @param providerName - The provider name (e.g., "OPENAI") * @param registration - `{ serves, runFn }` describing what this run function fulfils */ registerRunFn(providerName: string, registration: AiProviderRunFnRegistration): void; private registerRunFnInternal; /** * Registers a worker-proxied run function under a capability-set. * Delegates via `WorkerManager.callWorkerRunFunction` keyed by * {@link workerKeyForServes}(serves). `serves` must match the worker-side * registration's `serves` exactly so the deterministic * `workerKeyForServes` lookup resolves on both sides. */ registerAsWorkerRunFn(providerName: string, serves: readonly Capability[]): void; /** * Resolves a registered run function for `providerName` whose `serves` set * is a superset of `requires`. When multiple registrations match, the * most-specific one wins (smallest `serves.length`); ties are broken by * registration order. * * Empty `requires` matches every registration; the first registered (smallest * after the stable sort) is returned. * * @returns The run function, or `undefined` if no registration matches. */ getRunFnFor(providerName: string, requires: readonly Capability[]): AiProviderRunFn | undefined; /** * Returns the raw list of registrations for a provider (for diagnostics and * tests). Returns an empty array when the provider has none. */ getRunFnRegistrations(providerName: string): readonly AiProviderRunFnRegistration[]; /** * Registers a worker-proxied preview function for a specific task type and model provider. * Creates a proxy that delegates preview execution to a Web Worker via WorkerManager. * Returns undefined (non-throwing) if the worker has no preview function for the task type. */ registerAsWorkerPreviewRunFn(modelProvider: string, taskType: string): void; /** * Registers a preview execution function for a specific task type and model provider. * Called by AiTask.executePreview() to provide a fast, lightweight preview without a network call. */ registerPreviewRunFn(modelProvider: string, taskType: string, previewRunFn: AiProviderPreviewRunFn): void; /** * Retrieves the preview execution function for a task type and model provider. * Returns undefined if no preview function is registered (fallback to default behavior). */ getPreviewRunFn(modelProvider: string, taskType: string): AiProviderPreviewRunFn | undefined; } export declare const AI_PROVIDER_REGISTRY: import("@workglow/util").ServiceToken; /** * Returns the AI provider registry from the given registry (defaults to global). * Lazy-registers a fresh `AiProviderRegistry` if the token is absent — same * pattern as `getLogger`. Makes scoped registries safe to use without an * explicit `registerAiProviderDefaults(registry)` call. */ export declare function getAiProviderRegistry(registry?: ServiceRegistry): AiProviderRegistry; export declare function setAiProviderRegistry(pr: AiProviderRegistry, registry?: ServiceRegistry): void; /** * Registers the AI provider registry default factory on the given registry. * Called by `bootstrapWorkglow` and `createOrchestrationContext`. */ export declare function registerAiProviderDefaults(registry?: ServiceRegistry): void; //# sourceMappingURL=AiProviderRegistry.d.ts.map