feat(plugin): add namespaced hook API (#33416)

This commit is contained in:
Dax
2026-06-22 19:06:57 -04:00
committed by GitHub
parent 47546248f2
commit 9371e151f4
150 changed files with 3286 additions and 3916 deletions
@@ -17,7 +17,7 @@ import { PluginTestLayer } from "./fixture"
const fixtureProvider = new URL("./fixtures/provider-factory.ts", import.meta.url).href
const fixtureProviderPath = fileURLToPath(fixtureProvider)
const it = testEffect(PluginTestLayer)
const itWithAISDK = testEffect(AISDK.layer.pipe(Layer.provideMerge(PluginTestLayer)))
const itWithAISDK = testEffect(AISDK.locationLayer.pipe(Layer.provideMerge(PluginTestLayer)))
function npmEntrypoint(entrypoint?: string) {
return Npm.Service.of({
@@ -29,11 +29,8 @@ function npmEntrypoint(entrypoint?: string) {
const addPlugin = Effect.fn(function* (npm?: Npm.Interface) {
const plugin = yield* PluginV2.Service
const host = yield* PluginHost.make()
yield* plugin.add({
id: DynamicProviderPlugin.id,
effect: DynamicProviderPlugin.effect(npm ? { ...host, npm } : host),
})
const host = yield* PluginHost.make(plugin)
yield* DynamicProviderPlugin.effect(host).pipe(Effect.provideService(Npm.Service, npm ?? (yield* Npm.Service)))
})
function tempEntrypoint(source: string) {
@@ -51,20 +48,16 @@ function tempEntrypoint(source: string) {
describe("DynamicProviderPlugin", () => {
it.effect("creates an SDK from a provider factory export", () =>
Effect.gen(function* () {
const plugin = yield* PluginV2.Service
const aisdk = yield* AISDK.Service
yield* addPlugin()
const result = yield* plugin.trigger(
"aisdk.sdk",
{
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
}),
package: fixtureProvider,
options: { name: "custom", marker: "dynamic" },
},
{},
)
const result = yield* aisdk.runSDK({
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
}),
package: fixtureProvider,
options: { name: "custom", marker: "dynamic" },
})
expect(result.sdk.options).toEqual({ marker: "dynamic", name: "custom" })
expect(result.sdk.languageModel("x")).toEqual({ modelID: "x", options: { marker: "dynamic", name: "custom" } })
}),
@@ -72,68 +65,56 @@ describe("DynamicProviderPlugin", () => {
it.effect("does not override an SDK already supplied by an earlier plugin", () =>
Effect.gen(function* () {
const plugin = yield* PluginV2.Service
const aisdk = yield* AISDK.Service
const sdk = { marker: "existing" }
yield* addPlugin()
const result = yield* plugin.trigger(
"aisdk.sdk",
{
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
}),
package: fixtureProvider,
options: { name: "custom", marker: "dynamic" },
},
{ sdk },
)
const result = yield* aisdk.runSDK({
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("custom"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
}),
package: fixtureProvider,
options: { name: "custom", marker: "dynamic" },
sdk,
})
expect(result.sdk).toBe(sdk)
}),
)
it.effect("injects the provider ID as the SDK factory name", () =>
Effect.gen(function* () {
const plugin = yield* PluginV2.Service
const aisdk = yield* AISDK.Service
yield* addPlugin()
const result = yield* plugin.trigger(
"aisdk.sdk",
{
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("custom-provider"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
}),
package: fixtureProvider,
options: { name: "custom-provider", marker: "dynamic" },
},
{},
)
const result = yield* aisdk.runSDK({
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("custom-provider"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: fixtureProvider },
}),
package: fixtureProvider,
options: { name: "custom-provider", marker: "dynamic" },
})
expect(result.sdk.options).toEqual({ marker: "dynamic", name: "custom-provider" })
}),
)
it.effect("loads npm packages through their resolved import entrypoint", () =>
Effect.gen(function* () {
const plugin = yield* PluginV2.Service
const aisdk = yield* AISDK.Service
yield* addPlugin(npmEntrypoint(fixtureProviderPath))
const result = yield* plugin.trigger(
"aisdk.sdk",
{
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("npm-provider"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: "fixture-provider" },
}),
package: "fixture-provider",
options: { name: "npm-provider", marker: "npm" },
},
{},
)
const result = yield* aisdk.runSDK({
model: new ModelV2.Info({
...ModelV2.Info.empty(ProviderV2.ID.make("npm-provider"), ModelV2.ID.make("test-model")),
api: { id: ModelV2.ID.make("test-model"), type: "aisdk", package: "fixture-provider" },
}),
package: "fixture-provider",
options: { name: "npm-provider", marker: "npm" },
})
expect(result.sdk.languageModel("x")).toEqual({ modelID: "x", options: { marker: "npm", name: "npm-provider" } })
}),
)
itWithAISDK.effect("wraps missing npm entrypoint failures as AISDK init errors", () =>
Effect.gen(function* () {
const plugin = yield* PluginV2.Service
const aisdk = yield* AISDK.Service
yield* addPlugin(npmEntrypoint())
const exit = yield* aisdk
@@ -151,7 +132,6 @@ describe("DynamicProviderPlugin", () => {
itWithAISDK.effect("wraps dynamic import failures as AISDK init errors", () =>
Effect.gen(function* () {
const plugin = yield* PluginV2.Service
const aisdk = yield* AISDK.Service
yield* addPlugin()
const exit = yield* aisdk