feat: add dynamic tool registration for plugins and external services (#2420)

This commit is contained in:
Zack Jackson
2025-09-09 04:25:04 +08:00
committed by GitHub
parent f0f6e9cad7
commit ab3c22b77a
7 changed files with 727 additions and 12 deletions

View File

@@ -10,6 +10,15 @@ import type {
EventSubscribeResponses,
ConfigGetData,
ConfigGetResponses,
ToolRegisterData,
ToolRegisterResponses,
ToolRegisterErrors,
ToolIdsData,
ToolIdsResponses,
ToolIdsErrors,
ToolListData,
ToolListResponses,
ToolListErrors,
PathGetData,
PathGetResponses,
SessionListData,
@@ -178,6 +187,42 @@ class Config extends _HeyApiClient {
}
}
class Tool extends _HeyApiClient {
/**
* Register a new HTTP callback tool
*/
public register<ThrowOnError extends boolean = false>(options?: Options<ToolRegisterData, ThrowOnError>) {
return (options?.client ?? this._client).post<ToolRegisterResponses, ToolRegisterErrors, ThrowOnError>({
url: "/experimental/tool/register",
...options,
headers: {
"Content-Type": "application/json",
...options?.headers,
},
})
}
/**
* List all tool IDs (including built-in and dynamically registered)
*/
public ids<ThrowOnError extends boolean = false>(options?: Options<ToolIdsData, ThrowOnError>) {
return (options?.client ?? this._client).get<ToolIdsResponses, ToolIdsErrors, ThrowOnError>({
url: "/experimental/tool/ids",
...options,
})
}
/**
* List tools with JSON schema parameters for a provider/model
*/
public list<ThrowOnError extends boolean = false>(options: Options<ToolListData, ThrowOnError>) {
return (options.client ?? this._client).get<ToolListResponses, ToolListErrors, ThrowOnError>({
url: "/experimental/tool",
...options,
})
}
}
class Path extends _HeyApiClient {
/**
* Get the current path
@@ -649,6 +694,7 @@ export class OpencodeClient extends _HeyApiClient {
project = new Project({ client: this._client })
event = new Event({ client: this._client })
config = new Config({ client: this._client })
tool = new Tool({ client: this._client })
path = new Path({ client: this._client })
session = new Session({ client: this._client })
command = new Command({ client: this._client })

View File

@@ -1053,6 +1053,44 @@ export type McpRemoteConfig = {
export type LayoutConfig = "auto" | "stretch"
export type _Error = {
data: {
[key: string]: unknown
}
}
export type HttpToolRegistration = {
id: string
description: string
parameters: {
type: "object"
properties: {
[key: string]: HttpParamSpec
}
}
callbackUrl: string
headers?: {
[key: string]: string
}
}
export type HttpParamSpec = {
type: "string" | "number" | "boolean" | "array"
description?: string
optional?: boolean
items?: "string" | "number" | "boolean"
}
export type ToolIds = Array<string>
export type ToolList = Array<ToolListItem>
export type ToolListItem = {
id: string
description: string
parameters?: unknown
}
export type Path = {
state: string
config: string
@@ -1060,12 +1098,6 @@ export type Path = {
directory: string
}
export type _Error = {
data: {
[key: string]: unknown
}
}
export type TextPartInput = {
id?: string
type: "text"
@@ -1276,6 +1308,89 @@ export type ConfigGetResponses = {
export type ConfigGetResponse = ConfigGetResponses[keyof ConfigGetResponses]
export type ToolRegisterData = {
body?: HttpToolRegistration
path?: never
query?: {
directory?: string
}
url: "/experimental/tool/register"
}
export type ToolRegisterErrors = {
/**
* Bad request
*/
400: _Error
}
export type ToolRegisterError = ToolRegisterErrors[keyof ToolRegisterErrors]
export type ToolRegisterResponses = {
/**
* Tool registered successfully
*/
200: boolean
}
export type ToolRegisterResponse = ToolRegisterResponses[keyof ToolRegisterResponses]
export type ToolIdsData = {
body?: never
path?: never
query?: {
directory?: string
}
url: "/experimental/tool/ids"
}
export type ToolIdsErrors = {
/**
* Bad request
*/
400: _Error
}
export type ToolIdsError = ToolIdsErrors[keyof ToolIdsErrors]
export type ToolIdsResponses = {
/**
* Tool IDs
*/
200: ToolIds
}
export type ToolIdsResponse = ToolIdsResponses[keyof ToolIdsResponses]
export type ToolListData = {
body?: never
path?: never
query: {
directory?: string
provider: string
model: string
}
url: "/experimental/tool"
}
export type ToolListErrors = {
/**
* Bad request
*/
400: _Error
}
export type ToolListError = ToolListErrors[keyof ToolListErrors]
export type ToolListResponses = {
/**
* Tools
*/
200: ToolList
}
export type ToolListResponse = ToolListResponses[keyof ToolListResponses]
export type PathGetData = {
body?: never
path?: never