import type { Tool } from "../effect/tool.js" import type { Agent } from "@opencode-ai/schema/agent" import type { Session } from "@opencode-ai/schema/session" import type { SessionMessage } from "@opencode-ai/schema/session-message" import type { JsonSchema, Schema } from "effect" import type { Hooks, Transform } from "./registration.js" export type Context = Tool.Context export type SchemaType = Tool.SchemaType export type Content = Tool.Content export type DynamicOutput = Tool.DynamicOutput export type Definition< Input extends SchemaType, Output extends SchemaType, Structured extends SchemaType = Output, > = { readonly name: string readonly options?: RegisterOptions readonly description: string readonly input: Input readonly output: Output readonly structured?: Structured readonly toStructuredOutput?: (input: { readonly input: Schema.Schema.Type readonly output: Output["Encoded"] }) => Schema.Schema.Type readonly execute: ( input: Schema.Schema.Type, context: Context, ) => Promise> readonly toModelOutput?: (input: { readonly input: Schema.Schema.Type readonly output: Output["Encoded"] }) => ReadonlyArray } export type DynamicDefinition = { readonly name: string readonly options?: RegisterOptions readonly description: string readonly jsonSchema: JsonSchema.JsonSchema readonly outputSchema?: JsonSchema.JsonSchema readonly execute: (input: unknown, context: Context) => Promise } export type AnyTool = Definition | DynamicDefinition export interface ToolExecuteBeforeEvent { readonly tool: string readonly sessionID: Session.ID readonly agent: Agent.ID readonly assistantMessageID: SessionMessage.ID readonly toolCallID: string input: unknown } export interface ToolExecuteAfterEvent { readonly tool: string readonly sessionID: Session.ID readonly agent: Agent.ID readonly assistantMessageID: SessionMessage.ID readonly toolCallID: string readonly input: unknown result: Tool.ToolExecuteAfterEvent["result"] output?: Tool.ToolExecuteAfterEvent["output"] outputPaths?: ReadonlyArray } export interface RegisterOptions { readonly group?: string /** Defaults to true. False exposes the tool directly to the provider. */ readonly codemode?: boolean } export interface ToolDraft { add< Input extends SchemaType, Output extends SchemaType, Structured extends SchemaType = Output, >(tool: Definition): void add(tool: DynamicDefinition): void } export interface ToolHooks { readonly "execute.before": ToolExecuteBeforeEvent readonly "execute.after": ToolExecuteAfterEvent } export interface ToolDomain { readonly transform: Transform readonly hook: Hooks }