refactor(plugin): simplify promise tool declarations

This commit is contained in:
Dax Raad 2026-07-10 00:17:37 -04:00
commit efeff63749
7 changed files with 91 additions and 60 deletions

View file

@ -85,20 +85,19 @@ await ctx.session.hook("request", (event) => {
})
```
Promise tools use the same schemas and registration model as Effect tools, with async executors:
Promise tools use plain object declarations with async executors:
```ts
import { Schema } from "effect"
import { Tool } from "@opencode-ai/plugin/v2/tool"
const echo = Tool.make({
description: "Echo text",
input: Schema.Struct({ text: Schema.String }),
output: Schema.Struct({ text: Schema.String }),
execute: async ({ text }) => ({ text }),
await ctx.tool.transform((tools) => {
tools.add("echo", {
description: "Echo text",
input: Schema.Struct({ text: Schema.String }),
output: Schema.Struct({ text: Schema.String }),
execute: async ({ text }) => ({ text }),
})
})
await ctx.tool.transform((tools) => tools.add("echo", echo))
```
## Reloading A Domain

View file

@ -1,8 +1,6 @@
export type { PluginOptions } from "../options.js"
export * as Plugin from "./plugin.js"
export { Tool } from "./tool.js"
export { Agent } from "@opencode-ai/schema/agent"
export { Command } from "@opencode-ai/schema/command"
export { Connection } from "@opencode-ai/schema/connection"

View file

@ -1,24 +1,16 @@
export * as Tool from "./tool.js"
import { Tool } from "../effect/tool.js"
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 { Effect, type JsonSchema, type Schema } from "effect"
import type { JsonSchema, Schema } from "effect"
import type { Hooks, Transform } from "./registration.js"
export type Context = Tool.Context
export type SchemaType<A> = Tool.SchemaType<A>
export type Definition<Input extends SchemaType<any>, Output extends SchemaType<any>> = Tool.Definition<Input, Output>
export type AnyTool = Tool.AnyTool
export const Failure = Tool.Failure
export type Failure = Tool.Failure
export const RegistrationError = Tool.RegistrationError
export type RegistrationError = Tool.RegistrationError
export type Content = Tool.Content
export type DynamicOutput = Tool.DynamicOutput
type Config<
export type Definition<
Input extends SchemaType<any>,
Output extends SchemaType<any>,
Structured extends SchemaType<any> = Output,
@ -41,32 +33,14 @@ type Config<
}) => ReadonlyArray<Content>
}
type DynamicConfig = {
export type DynamicDefinition = {
readonly description: string
readonly jsonSchema: JsonSchema.JsonSchema
readonly outputSchema?: JsonSchema.JsonSchema
readonly execute: (input: unknown, context: Context) => Promise<DynamicOutput>
}
export function make<
Input extends SchemaType<any>,
Output extends SchemaType<any>,
Structured extends SchemaType<any> = Output,
>(config: Config<Input, Output, Structured>): Definition<Input, Structured>
export function make(config: DynamicConfig): AnyTool
export function make(config: Config<any, any, any> | DynamicConfig): AnyTool {
if ("jsonSchema" in config)
return Tool.make({
...config,
execute: (input, context) => Effect.promise(() => config.execute(input, context)),
})
return Tool.make({
...config,
execute: (input, context) => Effect.promise(() => config.execute(input, context)),
})
}
export const withPermission = Tool.withPermission
export type AnyTool = Definition<any, any, any> | DynamicDefinition
export interface ToolExecuteBeforeEvent {
readonly tool: string
@ -95,7 +69,12 @@ export interface RegisterOptions {
}
export interface ToolDraft {
add(name: string, tool: AnyTool, options?: RegisterOptions): void
add<
Input extends SchemaType<any>,
Output extends SchemaType<any>,
Structured extends SchemaType<any> = Output,
>(name: string, tool: Definition<Input, Output, Structured>, options?: RegisterOptions): void
add(name: string, tool: DynamicDefinition, options?: RegisterOptions): void
}
export interface ToolHooks {