From f359938c73b9a0f711595fa7ef58df17164e6a43 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Wed, 17 Sep 2025 23:14:01 -0400 Subject: [PATCH] sync --- bun.lock | 9 +++++- packages/opencode/src/tool/tool.ts | 45 +----------------------------- packages/plugin/package.json | 7 ++++- packages/plugin/src/example.ts | 23 +++++++++------ packages/plugin/src/index.ts | 39 +++++++++++--------------- 5 files changed, 46 insertions(+), 77 deletions(-) diff --git a/bun.lock b/bun.lock index 18bab7024..82a532962 100644 --- a/bun.lock +++ b/bun.lock @@ -183,6 +183,7 @@ "version": "0.9.11", "dependencies": { "@opencode-ai/sdk": "workspace:*", + "zod": "4.1.9", }, "devDependencies": { "@tsconfig/node22": "catalog:", @@ -2941,7 +2942,7 @@ "zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="], - "zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="], + "zod": ["zod@4.1.9", "", {}, "sha512-HI32jTq0AUAC125z30E8bQNz0RQ+9Uc+4J7V97gLYjZVKRjeydPgGt6dvQzFrav7MYOUGFqqOGiHpA/fdbd0cQ=="], "zod-to-json-schema": ["zod-to-json-schema@3.24.5", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g=="], @@ -3027,6 +3028,8 @@ "@opencode-ai/sdk/@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.81.0", "", { "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", "ansi-colors": "4.1.3", "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", "handlebars": "4.7.8", "js-yaml": "4.1.0", "open": "10.1.2", "semver": "7.7.2" }, "peerDependencies": { "typescript": "^5.5.3" }, "bin": { "openapi-ts": "bin/index.cjs" } }, "sha512-PoJukNBkUfHOoMDpN33bBETX49TUhy7Hu8Sa0jslOvFndvZ5VjQr4Nl/Dzjb9LG1Lp5HjybyTJMA6a1zYk/q6A=="], + "@opencode/cloud-function/zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="], + "@opencode/cloud-resource/@cloudflare/workers-types": ["@cloudflare/workers-types@4.20250913.0", "", {}, "sha512-JjrYEvRn7cyALxwoFTw3XChaQneHSJOXqz2t5iKEpNzAnC2iPQU75rtTK/gw03Jjy4SHY5aEBh/uqQePtonZlA=="], "@opencode/web/@shikijs/transformers": ["@shikijs/transformers@3.4.2", "", { "dependencies": { "@shikijs/core": "3.4.2", "@shikijs/types": "3.4.2" } }, "sha512-I5baLVi/ynLEOZoWSAMlACHNnG+yw5HDmse0oe+GW6U1u+ULdEB3UHiVWaHoJSSONV7tlcVxuaMy74sREDkSvg=="], @@ -3229,10 +3232,14 @@ "nypm/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "openai/zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="], + "opencode/@openauthjs/openauth": ["@openauthjs/openauth@0.4.3", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-RlnjqvHzqcbFVymEwhlUEuac4utA5h4nhSK/i2szZuQmxTIqbGUxZ+nM+avM+VV4Ing+/ZaNLKILoXS3yrkOOw=="], "opencode/ulid": ["ulid@3.0.1", "", { "bin": { "ulid": "dist/cli.js" } }, "sha512-dPJyqPzx8preQhqq24bBG1YNkvigm87K8kVEHCD+ruZg24t6IFEFv00xMWfxcC4djmFtiTLdFuADn4+DOz6R7Q=="], + "opencode/zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="], + "opencontrol/@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.6.1", "", { "dependencies": { "content-type": "^1.0.5", "cors": "^2.8.5", "eventsource": "^3.0.2", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^4.1.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-oxzMzYCkZHMntzuyerehK3fV6A2Kwh5BD6CGEJSVDU2QNEhfLOptf2X7esQgaHZXHZY0oHmMsOtIDLP71UJXgA=="], "opencontrol/hono": ["hono@4.7.4", "", {}, "sha512-Pst8FuGqz3L7tFF+u9Pu70eI0xa5S3LPUmrNd5Jm8nTHze9FxLTK9Kaj5g/k4UcwuJSXTP65SyHOPLrffpcAJg=="], diff --git a/packages/opencode/src/tool/tool.ts b/packages/opencode/src/tool/tool.ts index 6e2b95112..a54c9884d 100644 --- a/packages/opencode/src/tool/tool.ts +++ b/packages/opencode/src/tool/tool.ts @@ -1,44 +1 @@ -import z from "zod/v4" - -export namespace Tool { - interface Metadata { - [key: string]: any - } - export type Context = { - sessionID: string - messageID: string - agent: string - callID?: string - abort: AbortSignal - extra?: { [key: string]: any } - metadata(input: { title?: string; metadata?: M }): void - } - export interface Info { - id: string - init: () => Promise<{ - description: string - parameters: Parameters - execute( - args: z.infer, - ctx: Context, - ): Promise<{ - title: string - metadata: M - output: string - }> - }> - } - - export function define( - id: string, - init: Info["init"] | Awaited["init"]>>, - ): Info { - return { - id, - init: async () => { - if (init instanceof Function) return init() - return init - }, - } - } -} +export { Tool } from "@opencode-ai/plugin/tool" diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 39355a1b1..1fc45014f 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -10,13 +10,18 @@ ".": { "development": "./src/index.ts", "import": "./dist/index.js" + }, + "./tool": { + "development": "./src/tool.ts", + "import": "./dist/tool.js" } }, "files": [ "dist" ], "dependencies": { - "@opencode-ai/sdk": "workspace:*" + "@opencode-ai/sdk": "workspace:*", + "zod": "catalog:" }, "devDependencies": { "@tsconfig/node22": "catalog:", diff --git a/packages/plugin/src/example.ts b/packages/plugin/src/example.ts index 04c48c918..4e269abcb 100644 --- a/packages/plugin/src/example.ts +++ b/packages/plugin/src/example.ts @@ -1,14 +1,21 @@ -import { Plugin } from "./index" +import { Plugin, tool, z } from "./index" -export const ExamplePlugin: Plugin = async ({ - client: _client, - $: _shell, - project: _project, - directory: _directory, - worktree: _worktree, -}) => { +const foo = tool("mytool", { + description: "This is a tool", + parameters: z.object({ + foo: z.string(), + }), + async execute(params) { + return { + output, + } + }, +}) + +export const ExamplePlugin: Plugin = async ({}) => { return { permission: {}, + tool: {}, async "chat.params"(_input, output) { output.topP = 1 }, diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index f8b6d46f7..c5a8dc15f 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -11,6 +11,18 @@ import type { Config, } from "@opencode-ai/sdk" import type { BunShell } from "./shell" +export { z } from "zod/v4" +import { z } from "zod/v4" + +export function tool(input: { + description: string + args: Args + execute: (args: z.infer>) => Promise +}) { + return input +} + +export type ToolDefinition = ReturnType export type PluginInput = { client: ReturnType @@ -18,34 +30,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> @@ -129,7 +123,6 @@ export interface Hooks { "tool.register"?: ( input: {}, output: { - registerHTTP: (tool: HttpToolRegistration) => void | Promise register: (tool: any) => void | Promise // Tool.Info type from opencode }, ) => Promise