refactor(plugin): scope context hook to session (#37175)

Co-authored-by: Dax Raad <d@ironbay.co>
This commit is contained in:
opencode-agent[bot] 2026-07-15 16:32:00 -04:00 committed by GitHub
commit f92d84746b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 85 additions and 97 deletions

View file

@ -80,11 +80,11 @@ yield *
Hooks run sequentially in registration order. Later hooks observe mutations made by earlier hooks.
AI request context is mutable immediately before provider dispatch:
Session context is mutable immediately before provider dispatch:
```ts
yield *
ctx.ai.hook("request", (event) =>
ctx.session.hook("context", (event) =>
Effect.sync(() => {
event.tools.read.description = "Read a file using narrow line ranges."
delete event.tools.write

View file

@ -1,23 +0,0 @@
import type { Message, SystemPart } from "@opencode-ai/ai"
import type { Agent } from "@opencode-ai/schema/agent"
import type { Model } from "@opencode-ai/schema/model"
import type { Session } from "@opencode-ai/schema/session"
import type { JsonSchema } from "effect"
import type { Hooks } from "./registration.js"
export interface AIRequest {
readonly sessionID: Session.ID
readonly agent: Agent.ID
readonly model: Model.Ref
system: Array<SystemPart>
messages: Array<Message>
tools: Record<string, { description: string; input: JsonSchema.JsonSchema }>
}
export interface AIHooks {
readonly request: AIRequest
}
export interface AIDomain {
readonly hook: Hooks<AIHooks>
}

View file

@ -2,7 +2,6 @@ import type { PluginApi } from "@opencode-ai/client/effect/api"
import type { Effect, Scope } from "effect"
import type { PluginOptions } from "../options.js"
import type { AgentDomain } from "./agent.js"
import type { AIDomain } from "./ai.js"
import type { AISDKDomain } from "./aisdk.js"
import type { CatalogDomain } from "./catalog.js"
import type { CommandDomain } from "./command.js"
@ -16,7 +15,6 @@ import type { ToolDomain } from "./tool.js"
export interface Context {
readonly options: PluginOptions
readonly agent: AgentDomain
readonly ai: AIDomain
readonly aisdk: AISDKDomain
readonly catalog: CatalogDomain
readonly command: CommandDomain

View file

@ -1,3 +1,24 @@
import type { SessionApi } from "@opencode-ai/client/effect/api"
import type { Message, SystemPart } from "@opencode-ai/ai"
import type { Agent } from "@opencode-ai/schema/agent"
import type { Model } from "@opencode-ai/schema/model"
import type { Session } from "@opencode-ai/schema/session"
import type { JsonSchema } from "effect"
import type { Hooks } from "./registration.js"
export type SessionDomain = Pick<SessionApi<unknown>, "create" | "get" | "prompt" | "command" | "interrupt">
export interface SessionContext {
readonly sessionID: Session.ID
readonly agent: Agent.ID
readonly model: Model.Ref
system: Array<SystemPart>
messages: Array<Message>
tools: Record<string, { description: string; input: JsonSchema.JsonSchema }>
}
export interface SessionHooks {
readonly context: SessionContext
}
export type SessionDomain = Pick<SessionApi<unknown>, "create" | "get" | "prompt" | "command" | "interrupt"> & {
readonly hook: Hooks<SessionHooks>
}

View file

@ -85,10 +85,10 @@ await ctx.aisdk.hook("language", (event) => {
})
```
AI request context is mutable immediately before provider dispatch:
Session context is mutable immediately before provider dispatch:
```ts
await ctx.ai.hook("request", (event) => {
await ctx.session.hook("context", (event) => {
event.tools.read.description = "Read a file using narrow line ranges."
delete event.tools.write
})

View file

@ -1,23 +0,0 @@
import type { Message, SystemPart } from "@opencode-ai/ai"
import type { Agent } from "@opencode-ai/schema/agent"
import type { Model } from "@opencode-ai/schema/model"
import type { Session } from "@opencode-ai/schema/session"
import type { JsonSchema } from "effect"
import type { Hooks } from "./registration.js"
export interface AIRequest {
readonly sessionID: Session.ID
readonly agent: Agent.ID
readonly model: Model.Ref
system: Array<SystemPart>
messages: Array<Message>
tools: Record<string, { description: string; input: JsonSchema.JsonSchema }>
}
export interface AIHooks {
readonly request: AIRequest
}
export interface AIDomain {
readonly hook: Hooks<AIHooks>
}

View file

@ -1,7 +1,6 @@
import type { PluginApi } from "@opencode-ai/client/promise/api"
import type { PluginOptions } from "../options.js"
import type { AgentDomain } from "./agent.js"
import type { AIDomain } from "./ai.js"
import type { AISDKDomain } from "./aisdk.js"
import type { CatalogDomain } from "./catalog.js"
import type { CommandDomain } from "./command.js"
@ -15,7 +14,6 @@ import type { ToolDomain } from "./tool.js"
export interface Context {
readonly options: PluginOptions
readonly agent: AgentDomain
readonly ai: AIDomain
readonly aisdk: AISDKDomain
readonly catalog: CatalogDomain
readonly command: CommandDomain

View file

@ -1,3 +1,24 @@
import type { SessionApi } from "@opencode-ai/client/promise/api"
import type { Message, SystemPart } from "@opencode-ai/ai"
import type { Agent } from "@opencode-ai/schema/agent"
import type { Model } from "@opencode-ai/schema/model"
import type { Session } from "@opencode-ai/schema/session"
import type { JsonSchema } from "effect"
import type { Hooks } from "./registration.js"
export type SessionDomain = Pick<SessionApi, "create" | "get" | "prompt" | "command" | "interrupt">
export interface SessionContext {
readonly sessionID: Session.ID
readonly agent: Agent.ID
readonly model: Model.Ref
system: Array<SystemPart>
messages: Array<Message>
tools: Record<string, { description: string; input: JsonSchema.JsonSchema }>
}
export interface SessionHooks {
readonly context: SessionContext
}
export type SessionDomain = Pick<SessionApi, "create" | "get" | "prompt" | "command" | "interrupt"> & {
readonly hook: Hooks<SessionHooks>
}