[feat] Add reactive execution support to AiProvider and related classes - #219
[feat] Add reactive execution support to AiProvider and related classes#219sroussey wants to merge 1 commit into
Conversation
sroussey
commented
Feb 20, 2026
- Introduced AiProviderReactiveRunFn type for lightweight reactive task execution.
- Enhanced AiProvider to support reactiveTasks, allowing for fast previews of task outputs.
- Updated AiProviderRegistry to register and retrieve reactive run functions.
- Modified AiTask to delegate to provider-registered reactive functions when available.
- Updated various provider classes to include reactiveTasks in their constructors.
- Introduced AiProviderReactiveRunFn type for lightweight reactive task execution. - Enhanced AiProvider to support reactiveTasks, allowing for fast previews of task outputs. - Updated AiProviderRegistry to register and retrieve reactive run functions. - Modified AiTask to delegate to provider-registered reactive functions when available. - Updated various provider classes to include reactiveTasks in their constructors.
There was a problem hiding this comment.
Pull request overview
This pull request adds reactive execution support to the AI provider system, enabling lightweight, fast preview generation for task outputs without making network calls. The feature introduces a new AiProviderReactiveRunFn type alongside existing run and stream function types, and integrates it throughout the provider and task infrastructure.
Changes:
- Introduced
AiProviderReactiveRunFntype for provider-registered reactive execution functions - Enhanced
AiTask.executeReactive()to delegate to provider-registered reactive functions when available - Updated all provider classes to accept
reactiveTasksparameter in their constructors
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ai/src/task/base/AiTask.ts | Added executeReactive override to delegate to provider-registered functions |
| packages/ai/src/provider/AiProviderRegistry.ts | Added registry support for reactive functions with registration and retrieval methods |
| packages/ai/src/provider/AiProvider.ts | Added reactiveTasks field, getter method, and registration logic for reactive functions |
| packages/ai-provider/src/tf-mediapipe/TensorFlowMediaPipeProvider.ts | Updated constructor to accept reactiveTasks parameter |
| packages/ai-provider/src/provider-openai/OpenAiProvider.ts | Updated constructor to accept reactiveTasks parameter |
| packages/ai-provider/src/provider-ollama/OllamaProvider.ts | Updated constructor to accept reactiveTasks parameter |
| packages/ai-provider/src/provider-llamacpp/LlamaCppProvider.ts | Updated constructor to accept reactiveTasks parameter |
| packages/ai-provider/src/provider-hf-inference/HfInferenceProvider.ts | Updated constructor to accept reactiveTasks parameter |
| packages/ai-provider/src/hf-transformers/HuggingFaceTransformersProvider.ts | Updated constructor to accept reactiveTasks parameter |
| packages/ai-provider/src/google-gemini/GoogleGeminiProvider.ts | Updated constructor to accept reactiveTasks parameter |
| packages/ai-provider/src/anthropic/AnthropicProvider.ts | Updated constructor to accept reactiveTasks parameter |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| override async executeReactive( | ||
| input: Input, | ||
| output: Output, | ||
| context: IExecuteReactiveContext | ||
| ): Promise<Output | undefined> { | ||
| const model = input.model as ModelConfig | undefined; | ||
| if (model && typeof model === "object" && model.provider) { | ||
| const taskType = (this.constructor as any).runtype ?? (this.constructor as any).type; | ||
| const reactiveFn = getAiProviderRegistry().getReactiveRunFn<Input, Output>( | ||
| model.provider, | ||
| taskType | ||
| ); | ||
| if (reactiveFn) { | ||
| return reactiveFn(input, output, model); | ||
| } | ||
| } | ||
| return super.executeReactive(input, output, context); |
There was a problem hiding this comment.
The context parameter is received but never passed to the reactive function. The AiProviderReactiveRunFn type signature accepts only (input, output, model), but the IExecuteReactiveContext contains the own method which allows tasks to create and track subtasks during execution. This could be needed by provider-registered reactive functions that want to delegate to other tasks.
Consider either:
- Adding
contextas a fourth parameter toAiProviderReactiveRunFnto enable reactive functions to usecontext.own(), or - If the design intentionally excludes context from reactive functions (because they should be lightweight), add a comment explaining why context is not passed through.
| if (this.reactiveTasks) { | ||
| for (const [taskType, fn] of Object.entries(this.reactiveTasks)) { | ||
| registry.registerReactiveRunFn(this.name, taskType, fn as AiProviderReactiveRunFn); | ||
| } | ||
| } |
There was a problem hiding this comment.
The registerOnWorkerServer method registers tasks and streamTasks with the WorkerServer, but does not register reactiveTasks. This creates an inconsistency where reactive functions are available in inline mode but not when using workers.
If reactive functions should be available in worker mode, add registration for them here. If they are intentionally excluded from worker mode (perhaps because they should be lightweight and local-only), consider adding a comment explaining this design decision.