From 3b6c0ec0b3b4f2224311888d8f7be178ed2335da Mon Sep 17 00:00:00 2001 From: Dax Date: Thu, 18 Sep 2025 03:58:21 -0400 Subject: support custom tools (#2668) --- packages/plugin/src/example.ts | 20 +++++++++++++------- packages/plugin/src/index.ts | 42 ++++++++---------------------------------- packages/plugin/src/tool.ts | 20 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 41 deletions(-) create mode 100644 packages/plugin/src/tool.ts (limited to 'packages/plugin/src') diff --git a/packages/plugin/src/example.ts b/packages/plugin/src/example.ts index 04c48c918..fd6a404d9 100644 --- a/packages/plugin/src/example.ts +++ b/packages/plugin/src/example.ts @@ -1,14 +1,20 @@ import { Plugin } from "./index" +import { tool } from "./tool" -export const ExamplePlugin: Plugin = async ({ - client: _client, - $: _shell, - project: _project, - directory: _directory, - worktree: _worktree, -}) => { +export const ExamplePlugin: Plugin = async (ctx) => { return { permission: {}, + tool: { + mytool: tool((zod) => ({ + description: "This is a custom tool tool", + args: { + foo: zod.string(), + }, + async execute(args, ctx) { + return `Hello ${args.foo}!` + }, + })), + }, async "chat.params"(_input, output) { output.topP = 1 }, diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index f8b6d46f7..9c2647c60 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -10,7 +10,11 @@ import type { Auth, Config, } from "@opencode-ai/sdk" + import type { BunShell } from "./shell" +import { type ToolDefinition } from "./tool" + +export * from "./tool" export type PluginInput = { client: ReturnType @@ -18,34 +22,16 @@ export type PluginInput = { directory: string worktree: string $: BunShell - Tool: { - define(id: string, init: any | (() => Promise)): any - } - z: any // Zod instance for creating schemas } -export type Plugin = (input: PluginInput) => Promise -// Lightweight schema spec for HTTP-registered tools -export type HttpParamSpec = { - type: "string" | "number" | "boolean" | "array" - description?: string - optional?: boolean - items?: "string" | "number" | "boolean" -} -export type HttpToolRegistration = { - id: string - description: string - parameters: { - type: "object" - properties: Record - } - callbackUrl: string - headers?: Record -} +export type Plugin = (input: PluginInput) => Promise export interface Hooks { event?: (input: { event: Event }) => Promise config?: (input: Config) => Promise + tool?: { + [key: string]: ToolDefinition + } auth?: { provider: string loader?: (auth: () => Promise, provider: Provider) => Promise> @@ -121,16 +107,4 @@ export interface Hooks { metadata: any }, ) => Promise - /** - * Allow plugins to register additional tools with the server. - * Use registerHTTP to add a tool that calls back to your plugin/service. - * Use register to add a native/local tool with direct function execution. - */ - "tool.register"?: ( - input: {}, - output: { - registerHTTP: (tool: HttpToolRegistration) => void | Promise - register: (tool: any) => void | Promise // Tool.Info type from opencode - }, - ) => Promise } diff --git a/packages/plugin/src/tool.ts b/packages/plugin/src/tool.ts new file mode 100644 index 000000000..7c1d3d7c5 --- /dev/null +++ b/packages/plugin/src/tool.ts @@ -0,0 +1,20 @@ +import { z } from "zod/v4" + +export type ToolContext = { + sessionID: string + messageID: string + agent: string + abort: AbortSignal +} + +export function tool( + input: (zod: typeof z) => { + description: string + args: Args + execute: (args: z.infer>, ctx: ToolContext) => Promise + }, +) { + return input(z) +} + +export type ToolDefinition = ReturnType -- cgit v1.2.3