Repository navigation
LOU-D10, LOU-D19: lazy provider loading (importing the SDK never loads or requires a provider peer) - #60
Merged
Conversation
…s or requires a provider peer) Provider peers (@ai-sdk/openai, @ai-sdk/anthropic, ollama-ai-provider) and the heavy dependencies undici (http tool), dockerode (SubprocessSandbox) and @modelcontextprotocol/sdk (serveMcp) are now loaded with a dynamic import() on first use instead of at import time. A missing package throws MissingPeerDependencyError (packageName, installCommand; install hint shared with providerSpec) on first use. Constructors and resolveProvider/createAgent stay synchronous. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Importing any entry point of the SDK no longer loads an optional peer or a heavy optional dependency. Each is loaded with a dynamic
import()on first use:@ai-sdk/openai(OpenAI, OpenRouter),@ai-sdk/anthropic,ollama-ai-provider: inside the provider'sgenerate()/stream()(viacreateModel()).undici: first request of the built-inhttptool.dockerode: firstSubprocessSandbox.run().@modelcontextprotocol/sdk: firstserveMcp()call (buildServer()is now async; pure helpers moved totoolNames.ts).A missing package throws
MissingPeerDependencyError(packageName,installCommand) on first use, never at import. The install command comes fromproviderSpec.ts(newpeerInstallCommand(), also used by the existingresolveProviderhint), so there is one source. The error is exported from the root andprovidersbarrels.Provider constructors,
resolveProvider()andcreateAgent({ model })stay synchronous with unchanged signatures.Why
LOU-D10 / LOU-D19:
createAgentcould fail at import when a peer the user never uses was missing, so the LOU-D1 install hint never got to show; every consumer paid the load cost of all provider SDKs, undici, dockerode and the MCP SDK.Import graph (third-party packages loaded by
require('dist/index.js'), measured withModule._loadpatched)Before:
@ai-sdk/anthropic,@ai-sdk/openai,ollama-ai-provider,undici,dockerode(+docker-modem,ssh2,protobufjs,@grpc/*,tar-fs, ...),@modelcontextprotocol/sdk(+hono,@hono/node-server,ajv, ...), plusai,zod,@opentelemetry/api,nanoid,yamland their deps (about 75 packages).After:
ai(+@ai-sdk/provider,provider-utils,ui-utils,secure-json-parse,zod-to-json-schema),zod,@opentelemetry/api,nanoid,yaml. Sub-entriescore,testing: onlynanoid.How verified
Run on the result of merging
origin/main(b5cd5f5, LOU-X6):npx tsc --noEmit: cleannpm run lint: 0 errors (433 warnings, same count as before)npm run build+ create-loushy-agent build: successnpm run test:coverage: 115 files passed; 1625 passed, 4 skipped; All files 86.93 / 91.4 / 89.9 / 86.93npm run fallow: exit 0npm run docs:verify-snippets: all 52 snippets type-check; 6 run cleanlynpm run test:types: no type errorsnpm run docs:llms:check: ok (regeneratedllms.txt/llms-full.txt)New tests:
importGraph.test.ts(built CJS and ESM of 6 entries load none of the six packages; needsdist/, like other dist-dependent tests),missingPeer.test.ts(each provider and SubprocessSandbox with the peer mocked missing: constructs, rejects with the rightinstallCommand; plus loader unit tests). All existing provider tests pass unchanged. Deploy adapter tests (incl. Cloudflare) pass.Notes for reviewer
enginesNOT lowered. With undici now lazy, nothing at import time appears to need Node >= 22.19; your call.package.jsonsideEffectsunchanged on purpose: theproviders/indexside effect isLLMProviderRegistry.register(...)of factories that only construct provider objects, which still works and no longer loads a peer.@opentelemetry/api(optional peer) is still loaded at import by the tracing code; out of scope here, suggest a follow-up ticket.serveMcp.test.tsnowawaitsbuildServer()(it became async because loading the MCP SDK is lazy).aistays external; tsup keeps the dynamic imports of externals as realimport()/requirein both builds (checked in dist). The Worker bundle path is unchanged (esbuild bundles the peers there).🤖 Generated with Claude Code