Skip to content

fix(core): run dynamic provider fallback after plugin hooks - #42789

Open
abhishekbiyala wants to merge 1 commit into
anomalyco:v2from
abhishekbiyala:dynamic-provider-fallback
Open

fix(core): run dynamic provider fallback after plugin hooks#42789
abhishekbiyala wants to merge 1 commit into
anomalyco:v2from
abhishekbiyala:dynamic-provider-fallback

Conversation

@abhishekbiyala

@abhishekbiyala abhishekbiyala commented Aug 15, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #42788

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

A plugin that registers a provider with an aisdk: package that is not on npm never gets its ctx.aisdk.hook("sdk", ...) callback invoked, and the session fails with UnsupportedPackageError.

DynamicProviderPlugin was in PluginInternal.pre, so its hook always ran before hooks from config-loaded plugins. For an unrecognised package it calls npm.add(...) with Effect.orDie, and the 404 defect aborts the whole runSDK hook chain, skipping every hook registered after it. Built-in providers were unaffected because their own hooks set evt.sdk earlier, so the if (evt.sdk) return guard short-circuited before the npm call.

Two changes:

  • Move it to post so it runs after plugin hooks. It is a last-resort resolver, so it should only run once nothing else has claimed the package.
  • Decline instead of dying when the package cannot be installed. The name may only be a routing key for a plugin's own hook, so an unclaimed package now reports that no plugin supplied an SDK rather than an unrelated npm failure.

Using a package name that is not on npm is an established pattern here: GithubCopilotPlugin sets model.package = "@ai-sdk/github-copilot", claims it in its own sdk hook, and supplies the SDK from a local module, and that name is not published. It works only because ProviderPlugins is ordered ahead of DynamicProviderPlugin within pre, which a config-loaded plugin cannot do.

I confirmed the ordering with temporary logging of each hook index in AISDK.run: hooks 0-21 completed, index 22 (this plugin) entered and never finished, and the chain ended there.

How did you verify your code works?

Reproduced first on the released 0.0.0-next-17444 binary using the standalone plugin in #42788: the hook never ran and the session failed with UnsupportedPackageError. After the fix, running the server from source, the same plugin's hook runs and can supply an SDK. I also confirmed a real third-party provider plugin now completes requests end to end.

Added two tests in packages/core/test/plugin/provider-dynamic.test.ts:

  • a later hook still claims a package this plugin cannot resolve (fails on v2, passes here)
  • this plugin is not in ProviderPlugins, which is registered ahead of config plugins

From packages/core: bun test test/plugin/ passes (218), bun typecheck clean, and oxlint reports no new warnings on the changed files.

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@abhishekbiyala
abhishekbiyala force-pushed the dynamic-provider-fallback branch from 92f076b to b5fcfbe Compare August 15, 2026 16:24
@abhishekbiyala

Copy link
Copy Markdown
Author

Closes #42788 is in the description, but GitHub only populates closingIssuesReferences for PRs that target the default branch (dev), so the check can't see it on a v2-based PR. Same on #42735, #42681 and #42539, which also have the keyword in their descriptions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant