Files
opencode/packages/plugin/src/index.ts

140 lines
3.8 KiB
TypeScript

import type {
Event,
createOpencodeClient,
Project,
Model,
Provider,
Permission,
UserMessage,
Part,
Auth,
Config,
} from "@opencode-ai/sdk"
import type { BunShell } from "./shell"
export type PluginInput = {
client: ReturnType<typeof createOpencodeClient>
project: Project
directory: string
worktree: string
$: BunShell
Tool: {
define(
id: string,
init: any | (() => Promise<any>)
): any
}
z: any // Zod instance for creating schemas
}
export type Plugin = (input: PluginInput) => Promise<Hooks>
// 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<string, HttpParamSpec>
}
callbackUrl: string
headers?: Record<string, string>
}
export interface Hooks {
event?: (input: { event: Event }) => Promise<void>
config?: (input: Config) => Promise<void>
auth?: {
provider: string
loader?: (auth: () => Promise<Auth>, provider: Provider) => Promise<Record<string, any>>
methods: (
| {
type: "oauth"
label: string
authorize(): Promise<
{ url: string; instructions: string } & (
| {
method: "auto"
callback(): Promise<
| ({
type: "success"
} & (
| {
refresh: string
access: string
expires: number
}
| { key: string }
))
| {
type: "failed"
}
>
}
| {
method: "code"
callback(code: string): Promise<
| ({
type: "success"
} & (
| {
refresh: string
access: string
expires: number
}
| { key: string }
))
| {
type: "failed"
}
>
}
)
>
}
| { type: "api"; label: string }
)[]
}
/**
* Called when a new message is received
*/
"chat.message"?: (input: {}, output: { message: UserMessage; parts: Part[] }) => Promise<void>
/**
* Modify parameters sent to LLM
*/
"chat.params"?: (
input: { model: Model; provider: Provider; message: UserMessage },
output: { temperature: number; topP: number; options: Record<string, any> },
) => Promise<void>
"permission.ask"?: (input: Permission, output: { status: "ask" | "deny" | "allow" }) => Promise<void>
"tool.execute.before"?: (
input: { tool: string; sessionID: string; callID: string },
output: { args: any },
) => Promise<void>
"tool.execute.after"?: (
input: { tool: string; sessionID: string; callID: string },
output: {
title: string
output: string
metadata: any
},
) => Promise<void>
/**
* 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<void>
register: (tool: any) => void | Promise<void> // Tool.Info type from opencode
},
) => Promise<void>
}