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
}