Goal
Make @gemstack/ai-sdk a fully framework-agnostic engine with zero @rudderjs/* coupling, matching the GemStack charter ("engines, not bindings"). Today the main entry (.) is already clean (only zod is required), but several opt-in subpaths and two lazy feature paths still reach into the Rudder ecosystem.
This epic plans the removal. The pattern is the one ai-sdk already uses for storage contracts: neutral seam in the engine, binding on the framework side. Each coupling becomes either (a) a BYO-adapter neutral seam, or (b) a binding that relocates to the Rudder side (the @rudderjs/ai package or a small rudder adapter).
Current coupling inventory (audited 2026-06-26)
Static (hard) imports:
| Site |
Package |
Kind |
src/server/provider.ts |
@rudderjs/core (ServiceProvider, config, bootNotice) |
binding (/server subpath) |
src/conversation-orm/index.ts, src/memory-orm/index.ts, src/budget-orm/index.ts |
@rudderjs/orm (Model) |
binding (*-orm subpaths) |
src/doctor.ts |
@rudderjs/console (registerDoctorCheck) |
binding (CLI) |
src/commands/make-agent.ts |
@rudderjs/console (MakeSpec type) |
binding (CLI) |
Lazy (dynamic) imports:
| Site |
Package |
Kind |
src/image.ts, src/audio.ts (.store()) |
@rudderjs/storage |
feature seam (not even a declared peer) |
src/agent-run-store.ts, src/sub-agent-run-store.ts |
@rudderjs/cache |
feature seam (already structural) |
src/commands/ai-eval.ts, src/server/provider.ts |
@rudderjs/core, @rudderjs/console |
binding (CLI/provider) |
Doc-comment-only references (no code dep): @rudderjs/contracts, /support, /panels, /telescope, /http.
Declared peers (all already optional): @rudderjs/console, @rudderjs/core, @rudderjs/orm.
Strategy
- Seams stay, rudder leaves.
cache and storage become BYO neutral adapters (drop the hardcoded @rudderjs/* specifier). The existing neutral contracts (ConversationStore, UserMemory, BudgetStorage) already define the persistence seam; the *-orm adapters are bindings that relocate.
- Bindings move to the Rudder side (
@rudderjs/ai re-export package or a small @rudderjs/ai-rudder adapter): the /server provider, the ORM-backed stores, and the doctor/make:agent/CLI integrations. They consume the engine, not the reverse.
- No behavior loss for Rudder users - they pick the relocated binding up via
@rudderjs/ai.
Children
Status (2026-06-27)
The data-layer couplings (@rudderjs/cache, @rudderjs/storage, @rudderjs/orm) and the doctor check are decoupled. Remaining: the /server provider, make:agent, and ai-eval — all gated on the #46 prereq exports, which forces a 3-release sequence (gemstack adds exports → rudder inlines → gemstack removes + drops @rudderjs/core/@rudderjs/console). These are optional peers, so the engine is already usable with zero @rudderjs/* for the data layer.
Done when
grep -rn '@rudderjs' packages/ai-sdk/src returns nothing, package.json has no @rudderjs/* peers, and Rudder users get identical functionality via @rudderjs/ai.
(Context: the message-prefix and issue-URL part of the de-rudder work already shipped in #34. This epic is the dependency removal.)
Goal
Make
@gemstack/ai-sdka fully framework-agnostic engine with zero@rudderjs/*coupling, matching the GemStack charter ("engines, not bindings"). Today the main entry (.) is already clean (onlyzodis required), but several opt-in subpaths and two lazy feature paths still reach into the Rudder ecosystem.This epic plans the removal. The pattern is the one ai-sdk already uses for storage contracts: neutral seam in the engine, binding on the framework side. Each coupling becomes either (a) a BYO-adapter neutral seam, or (b) a binding that relocates to the Rudder side (the
@rudderjs/aipackage or a small rudder adapter).Current coupling inventory (audited 2026-06-26)
Static (hard) imports:
src/server/provider.ts@rudderjs/core(ServiceProvider,config,bootNotice)/serversubpath)src/conversation-orm/index.ts,src/memory-orm/index.ts,src/budget-orm/index.ts@rudderjs/orm(Model)*-ormsubpaths)src/doctor.ts@rudderjs/console(registerDoctorCheck)src/commands/make-agent.ts@rudderjs/console(MakeSpectype)Lazy (dynamic) imports:
src/image.ts,src/audio.ts(.store())@rudderjs/storagesrc/agent-run-store.ts,src/sub-agent-run-store.ts@rudderjs/cachesrc/commands/ai-eval.ts,src/server/provider.ts@rudderjs/core,@rudderjs/consoleDoc-comment-only references (no code dep):
@rudderjs/contracts,/support,/panels,/telescope,/http.Declared peers (all already
optional):@rudderjs/console,@rudderjs/core,@rudderjs/orm.Strategy
cacheandstoragebecome BYO neutral adapters (drop the hardcoded@rudderjs/*specifier). The existing neutral contracts (ConversationStore,UserMemory,BudgetStorage) already define the persistence seam; the*-ormadapters are bindings that relocate.@rudderjs/aire-export package or a small@rudderjs/ai-rudderadapter): the/serverprovider, the ORM-backed stores, and the doctor/make:agent/CLI integrations. They consume the engine, not the reverse.@rudderjs/ai.Children
@rudderjs/cachelazy fallback; require a BYOCacheAdapter— doneStorageAdapterforimage/audio.store(); drop@rudderjs/storage— done/conversation-orm,/memory-orm,/budget-orm,/memory-embedding) to the Rudder side — done@rudderjs/console) to the Rudder side — doneGoogleCacheRegistry+ eval fixtures helpers from@gemstack/ai-sdk(unblocks ai-sdk decouple: relocate the /server provider (@rudderjs/core) to Rudder side #39 + ai-eval)/serverprovider +make:agent(@rudderjs/core/@rudderjs/console) — blocked on ai-sdk: export GoogleCacheRegistry + eval fixtures helpers (prereq for #39 + ai-eval relocation) #46ai-evalCLI command — blocked on ai-sdk: export GoogleCacheRegistry + eval fixtures helpers (prereq for #39 + ai-eval relocation) #46@rudderjs/*peers frompackage.jsonStatus (2026-06-27)
The data-layer couplings (
@rudderjs/cache,@rudderjs/storage,@rudderjs/orm) and the doctor check are decoupled. Remaining: the/serverprovider,make:agent, andai-eval— all gated on the #46 prereq exports, which forces a 3-release sequence (gemstack adds exports → rudder inlines → gemstack removes + drops@rudderjs/core/@rudderjs/console). These are optional peers, so the engine is already usable with zero@rudderjs/*for the data layer.Done when
grep -rn '@rudderjs' packages/ai-sdk/srcreturns nothing,package.jsonhas no@rudderjs/*peers, and Rudder users get identical functionality via@rudderjs/ai.(Context: the message-prefix and issue-URL part of the de-rudder work already shipped in #34. This epic is the dependency removal.)