Files
opencode/packages/core/test/plugin-hooks.test.ts
2026-07-21 19:11:08 +00:00

77 lines
3.0 KiB
TypeScript

import { describe, expect } from "bun:test"
import { Message, SystemPart } from "@opencode-ai/ai"
import { Agent } from "@opencode-ai/schema/agent"
import { Model } from "@opencode-ai/schema/model"
import { Provider } from "@opencode-ai/schema/provider"
import { Session } from "@opencode-ai/schema/session"
import type { SessionHooks } from "@opencode-ai/plugin/v2/effect/session"
import { Effect, Layer } from "effect"
import { PluginHooks } from "../src/plugin/hooks"
import { testEffect } from "./lib/effect"
const layer = PluginHooks.node.implementation as Layer.Layer<PluginHooks.Service>
const it = testEffect(layer)
describe("PluginHooks", () => {
it.effect("registers scoped session hooks and triggers them sequentially", () =>
Effect.gen(function* () {
const hooks = yield* PluginHooks.Service
const seen: string[] = []
yield* hooks.register("session", "context", (event) =>
Effect.sync(() => {
seen.push("first")
event.system.push(SystemPart.make("second"))
}),
)
yield* hooks.register("session", "context", (event) =>
Effect.sync(() => {
seen.push(event.system[1]?.text ?? "missing")
event.messages = [Message.user("changed")]
}),
)
const event: SessionHooks["context"] = {
sessionID: Session.ID.make("ses_hooks"),
agent: Agent.ID.make("build"),
model: Model.Ref.make({ providerID: Provider.ID.make("test"), id: Model.ID.make("model") }),
system: [SystemPart.make("first")],
messages: [Message.user("original")],
tools: {},
}
expect(yield* hooks.trigger("session", "context", event)).toBe(event)
expect(seen).toEqual(["first", "second"])
expect(event.messages).toEqual([Message.user("changed")])
}),
)
it.effect("registers session request hooks and triggers them sequentially", () =>
Effect.gen(function* () {
const hooks = yield* PluginHooks.Service
yield* hooks.register("session", "request", (event) =>
Effect.sync(() => {
event.headers.authorization = "Bearer changed"
delete event.body.max_output_tokens
event.body.store = false
}),
)
yield* hooks.register("session", "request", (event) =>
Effect.sync(() => {
event.headers = { ...event.headers, "x-store": String(event.body.store) }
event.body = { input: event.body.input ?? [] }
}),
)
const event: SessionHooks["request"] = {
sessionID: Session.ID.make("ses_request_hooks"),
agent: Agent.ID.make("build"),
model: Model.Ref.make({ providerID: Provider.ID.make("test"), id: Model.ID.make("model") }),
headers: { authorization: "Bearer original" },
body: { input: ["hello"], max_output_tokens: 1024 },
}
expect(yield* hooks.trigger("session", "request", event)).toBe(event)
expect(event.headers).toEqual({ authorization: "Bearer changed", "x-store": "false" })
expect(event.body).toEqual({ input: ["hello"] })
}),
)
})