refactor(core): consolidate tool architecture
This commit is contained in:
parent
0fd73a2976
commit
8db7487c89
466 changed files with 9405 additions and 11071 deletions
17
packages/plugin/src/promise/agent.ts
Normal file
17
packages/plugin/src/promise/agent.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import type { AgentApi } from "@opencode-ai/client/promise/api"
|
||||
import type { Agent } from "@opencode-ai/schema/agent"
|
||||
import type { Transform } from "./registration.js"
|
||||
import type { DeepMutable } from "./types.js"
|
||||
|
||||
export interface AgentDraft {
|
||||
list(): readonly DeepMutable<Agent.Info>[]
|
||||
get(id: string): DeepMutable<Agent.Info> | undefined
|
||||
default(id: string | undefined): void
|
||||
update(id: string, update: (agent: DeepMutable<Agent.Info>) => void): void
|
||||
remove(id: string): void
|
||||
}
|
||||
|
||||
export interface AgentDomain extends AgentApi {
|
||||
readonly transform: Transform<AgentDraft>
|
||||
readonly reload: () => Promise<void>
|
||||
}
|
||||
22
packages/plugin/src/promise/aisdk.ts
Normal file
22
packages/plugin/src/promise/aisdk.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import type { LanguageModelV3 } from "@ai-sdk/provider"
|
||||
import type { Model } from "@opencode-ai/schema/model"
|
||||
import type { Hooks } from "./registration.js"
|
||||
|
||||
export interface AISDKHooks {
|
||||
sdk: {
|
||||
readonly model: Model.Info
|
||||
readonly package: string
|
||||
readonly options: Record<string, any>
|
||||
sdk?: any
|
||||
}
|
||||
language: {
|
||||
readonly model: Model.Info
|
||||
readonly sdk: any
|
||||
readonly options: Record<string, any>
|
||||
language?: LanguageModelV3
|
||||
}
|
||||
}
|
||||
|
||||
export interface AISDKDomain {
|
||||
readonly hook: Hooks<AISDKHooks>
|
||||
}
|
||||
33
packages/plugin/src/promise/catalog.ts
Normal file
33
packages/plugin/src/promise/catalog.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import type { CatalogApi } from "@opencode-ai/client/promise/api"
|
||||
import type { Model } from "@opencode-ai/schema/model"
|
||||
import type { Provider } from "@opencode-ai/schema/provider"
|
||||
import type { Transform } from "./registration.js"
|
||||
import type { DeepMutable } from "./types.js"
|
||||
|
||||
export interface CatalogProviderRecord {
|
||||
readonly provider: DeepMutable<Provider.Info>
|
||||
readonly models: ReadonlyMap<string, DeepMutable<Model.Info>>
|
||||
}
|
||||
|
||||
export interface CatalogDraft {
|
||||
readonly provider: {
|
||||
list(): readonly CatalogProviderRecord[]
|
||||
get(providerID: string): CatalogProviderRecord | undefined
|
||||
update(providerID: string, update: (provider: DeepMutable<Provider.Info>) => void): void
|
||||
remove(providerID: string): void
|
||||
}
|
||||
readonly model: {
|
||||
get(providerID: string, modelID: string): DeepMutable<Model.Info> | undefined
|
||||
update(providerID: string, modelID: string, update: (model: DeepMutable<Model.Info>) => void): void
|
||||
remove(providerID: string, modelID: string): void
|
||||
readonly default: {
|
||||
get(): { providerID: string; modelID: string } | undefined
|
||||
set(providerID: string, modelID: string): void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface CatalogDomain extends CatalogApi {
|
||||
readonly transform: Transform<CatalogDraft>
|
||||
readonly reload: () => Promise<void>
|
||||
}
|
||||
15
packages/plugin/src/promise/command.ts
Normal file
15
packages/plugin/src/promise/command.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import type { CommandApi } from "@opencode-ai/client/promise/api"
|
||||
import type { CommandInfo } from "@opencode-ai/client"
|
||||
import type { Transform } from "./registration.js"
|
||||
|
||||
export interface CommandDraft {
|
||||
list(): readonly CommandInfo[]
|
||||
get(name: string): CommandInfo | undefined
|
||||
update(name: string, update: (command: CommandInfo) => void): void
|
||||
remove(name: string): void
|
||||
}
|
||||
|
||||
export interface CommandDomain extends CommandApi {
|
||||
readonly transform: Transform<CommandDraft>
|
||||
readonly reload: () => Promise<void>
|
||||
}
|
||||
3
packages/plugin/src/promise/event.ts
Normal file
3
packages/plugin/src/promise/event.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import type { EventApi } from "@opencode-ai/client/promise/api"
|
||||
|
||||
export interface EventDomain extends Pick<EventApi, "subscribe"> {}
|
||||
13
packages/plugin/src/promise/index.ts
Normal file
13
packages/plugin/src/promise/index.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
export type { PluginOptions } from "../options.js"
|
||||
export * as Plugin from "./plugin.js"
|
||||
|
||||
export { Agent } from "@opencode-ai/schema/agent"
|
||||
export { Command } from "@opencode-ai/schema/command"
|
||||
export { Connection } from "@opencode-ai/schema/connection"
|
||||
export { Credential } from "@opencode-ai/schema/credential"
|
||||
export { Integration } from "@opencode-ai/schema/integration"
|
||||
export { Model } from "@opencode-ai/schema/model"
|
||||
export { Provider } from "@opencode-ai/schema/provider"
|
||||
export { Reference } from "@opencode-ai/schema/reference"
|
||||
export { Skill } from "@opencode-ai/schema/skill"
|
||||
export { WebSearch } from "@opencode-ai/schema/websearch"
|
||||
64
packages/plugin/src/promise/integration.ts
Normal file
64
packages/plugin/src/promise/integration.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import type {
|
||||
ConnectionInfo,
|
||||
IntegrationCommandMethod,
|
||||
IntegrationEnvMethod,
|
||||
IntegrationKeyMethod,
|
||||
IntegrationMethod,
|
||||
IntegrationOAuthMethod,
|
||||
} from "@opencode-ai/client"
|
||||
import type { IntegrationApi } from "@opencode-ai/client/promise/api"
|
||||
import { Credential } from "@opencode-ai/schema/credential"
|
||||
import type { Transform } from "./registration.js"
|
||||
|
||||
type IntegrationInputs = Record<string, string>
|
||||
type IntegrationRef = { id: string; name: string }
|
||||
|
||||
export type IntegrationOAuthAuthorization = {
|
||||
readonly url: string
|
||||
readonly instructions: string
|
||||
readonly expiresAt?: number
|
||||
} & (
|
||||
| {
|
||||
readonly mode: "auto"
|
||||
readonly callback: Promise<Credential.OAuth>
|
||||
}
|
||||
| {
|
||||
readonly mode: "code"
|
||||
readonly callback: (code: string) => Promise<Credential.OAuth>
|
||||
}
|
||||
)
|
||||
|
||||
export type IntegrationOAuthMethodRegistration = {
|
||||
readonly integrationID: string
|
||||
readonly method: IntegrationOAuthMethod
|
||||
readonly authorize: (inputs: IntegrationInputs) => Promise<IntegrationOAuthAuthorization>
|
||||
readonly refresh?: (credential: Credential.OAuth) => Promise<Credential.OAuth>
|
||||
readonly label?: (credential: Credential.OAuth) => string | undefined
|
||||
}
|
||||
|
||||
export type IntegrationMethodRegistration =
|
||||
| IntegrationOAuthMethodRegistration
|
||||
| { readonly integrationID: string; readonly method: IntegrationCommandMethod }
|
||||
| { readonly integrationID: string; readonly method: IntegrationKeyMethod }
|
||||
| { readonly integrationID: string; readonly method: IntegrationEnvMethod }
|
||||
|
||||
export interface IntegrationDraft {
|
||||
list(): readonly IntegrationRef[]
|
||||
get(id: string): IntegrationRef | undefined
|
||||
update(id: string, update: (integration: IntegrationRef) => void): void
|
||||
remove(id: string): void
|
||||
readonly method: {
|
||||
list(integrationID: string): readonly IntegrationMethod[]
|
||||
update(input: IntegrationMethodRegistration): void
|
||||
remove(integrationID: string, method: IntegrationMethod): void
|
||||
}
|
||||
}
|
||||
|
||||
export interface IntegrationDomain extends Omit<IntegrationApi, "wellknown"> {
|
||||
readonly transform: Transform<IntegrationDraft>
|
||||
readonly reload: () => Promise<void>
|
||||
readonly connection: {
|
||||
readonly active: (integrationID: string) => Promise<ConnectionInfo | undefined>
|
||||
readonly resolve: (connection: ConnectionInfo) => Promise<Credential.Value | undefined>
|
||||
}
|
||||
}
|
||||
42
packages/plugin/src/promise/plugin.ts
Normal file
42
packages/plugin/src/promise/plugin.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import type { PluginApi } from "@opencode-ai/client/promise/api"
|
||||
import type { PluginOptions } from "../options.js"
|
||||
import type { App } from "../app.js"
|
||||
import type { AgentDomain } from "./agent.js"
|
||||
import type { AISDKDomain } from "./aisdk.js"
|
||||
import type { CatalogDomain } from "./catalog.js"
|
||||
import type { CommandDomain } from "./command.js"
|
||||
import type { EventDomain } from "./event.js"
|
||||
import type { IntegrationDomain } from "./integration.js"
|
||||
import type { ReferenceDomain } from "./reference.js"
|
||||
import type { SessionDomain } from "./session.js"
|
||||
import type { SkillDomain } from "./skill.js"
|
||||
import type { ToolDomain } from "./tool.js"
|
||||
import type { WebSearchDomain } from "./websearch.js"
|
||||
|
||||
export interface Context {
|
||||
readonly app: App
|
||||
readonly options: PluginOptions
|
||||
readonly agent: AgentDomain
|
||||
readonly aisdk: AISDKDomain
|
||||
readonly catalog: CatalogDomain
|
||||
readonly command: CommandDomain
|
||||
readonly event: EventDomain
|
||||
readonly integration: IntegrationDomain
|
||||
readonly plugin: PluginApi
|
||||
readonly reference: ReferenceDomain
|
||||
readonly session: SessionDomain
|
||||
readonly skill: SkillDomain
|
||||
readonly tool: ToolDomain
|
||||
readonly websearch: WebSearchDomain
|
||||
}
|
||||
|
||||
export type Cleanup = () => Promise<void> | void
|
||||
|
||||
export interface Plugin {
|
||||
readonly id: string
|
||||
readonly setup: (context: Context) => Promise<Cleanup | void> | Cleanup | void
|
||||
}
|
||||
|
||||
export function define(plugin: Plugin) {
|
||||
return plugin
|
||||
}
|
||||
14
packages/plugin/src/promise/reference.ts
Normal file
14
packages/plugin/src/promise/reference.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import type { ReferenceApi } from "@opencode-ai/client/promise/api"
|
||||
import type { ReferenceGitSource, ReferenceLocalSource } from "@opencode-ai/client"
|
||||
import type { Transform } from "./registration.js"
|
||||
|
||||
export interface ReferenceDraft {
|
||||
add(name: string, source: ReferenceLocalSource | ReferenceGitSource): void
|
||||
remove(name: string): void
|
||||
list(): readonly (readonly [string, ReferenceLocalSource | ReferenceGitSource])[]
|
||||
}
|
||||
|
||||
export interface ReferenceDomain extends ReferenceApi {
|
||||
readonly transform: Transform<ReferenceDraft>
|
||||
readonly reload: () => Promise<void>
|
||||
}
|
||||
10
packages/plugin/src/promise/registration.ts
Normal file
10
packages/plugin/src/promise/registration.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export interface Registration {
|
||||
readonly dispose: () => Promise<void>
|
||||
}
|
||||
|
||||
export type Hooks<Spec> = <Name extends keyof Spec>(
|
||||
name: Name,
|
||||
callback: (input: Spec[Name]) => Promise<void> | void,
|
||||
) => Promise<Registration>
|
||||
|
||||
export type Transform<Input> = (callback: (input: Input) => void) => Promise<Registration>
|
||||
27
packages/plugin/src/promise/session.ts
Normal file
27
packages/plugin/src/promise/session.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import type { SessionApi } from "@opencode-ai/client/promise/api"
|
||||
import type { Message, SystemPart } from "@opencode-ai/ai"
|
||||
import type { Agent } from "@opencode-ai/schema/agent"
|
||||
import type { Model } from "@opencode-ai/schema/model"
|
||||
import type { Session } from "@opencode-ai/schema/session"
|
||||
import type { JsonSchema } from "effect"
|
||||
import type { Hooks } from "./registration.js"
|
||||
|
||||
export interface SessionContext {
|
||||
readonly sessionID: Session.ID
|
||||
readonly agent: Agent.ID
|
||||
readonly model: Model.Ref
|
||||
system: Array<SystemPart>
|
||||
messages: Array<Message>
|
||||
tools: Record<string, { description: string; input: JsonSchema.JsonSchema }>
|
||||
}
|
||||
|
||||
export interface SessionHooks {
|
||||
readonly context: SessionContext
|
||||
}
|
||||
|
||||
export type SessionDomain = Pick<
|
||||
SessionApi,
|
||||
"create" | "get" | "prompt" | "generate" | "command" | "synthetic" | "interrupt"
|
||||
> & {
|
||||
readonly hook: Hooks<SessionHooks>
|
||||
}
|
||||
13
packages/plugin/src/promise/skill.ts
Normal file
13
packages/plugin/src/promise/skill.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import type { SkillApi } from "@opencode-ai/client/promise/api"
|
||||
import type { Skill } from "@opencode-ai/schema/skill"
|
||||
import type { Transform } from "./registration.js"
|
||||
|
||||
export interface SkillDraft {
|
||||
source(source: Skill.Source): void
|
||||
list(): readonly Skill.Source[]
|
||||
}
|
||||
|
||||
export interface SkillDomain extends SkillApi {
|
||||
readonly transform: Transform<SkillDraft>
|
||||
readonly reload: () => Promise<void>
|
||||
}
|
||||
62
packages/plugin/src/promise/tool.ts
Normal file
62
packages/plugin/src/promise/tool.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
export { CallID, Error } from "@opencode-ai/schema/tool"
|
||||
export type { Metadata, Options, Result } from "@opencode-ai/schema/tool"
|
||||
|
||||
import { Tool } from "@opencode-ai/schema/tool"
|
||||
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 type { Hooks, Transform } from "./registration.js"
|
||||
|
||||
export interface ToolContext extends Omit<Tool.Context, "progress"> {
|
||||
readonly progress: (update: Tool.Metadata) => Promise<void>
|
||||
}
|
||||
|
||||
export type Info<
|
||||
Input extends Tool.ValueSchema<any> = Tool.ValueSchema<any>,
|
||||
Output extends Tool.ValueSchema<any> | undefined = Tool.ValueSchema<any> | undefined,
|
||||
> = Omit<Tool.Info<Input, Output>, "execute"> & {
|
||||
readonly execute: (
|
||||
input: Parameters<Tool.Info<Input, Output>["execute"]>[0],
|
||||
context: ToolContext,
|
||||
) => Promise<Tool.Result<Output>>
|
||||
}
|
||||
|
||||
interface ToolDraft {
|
||||
add<
|
||||
Input extends Tool.ValueSchema<any>,
|
||||
Output extends Tool.ValueSchema<any> | undefined,
|
||||
>(tool: Info<Input, Output>): void
|
||||
}
|
||||
|
||||
interface ToolHooks {
|
||||
readonly "execute.before": {
|
||||
readonly tool: string
|
||||
readonly sessionID: Session.ID
|
||||
readonly agent: Agent.ID
|
||||
readonly messageID: SessionMessage.ID
|
||||
readonly callID: Tool.CallID
|
||||
input: unknown
|
||||
}
|
||||
readonly "execute.after": {
|
||||
readonly tool: string
|
||||
readonly sessionID: Session.ID
|
||||
readonly agent: Agent.ID
|
||||
readonly messageID: SessionMessage.ID
|
||||
readonly callID: Tool.CallID
|
||||
readonly input: unknown
|
||||
} & (
|
||||
| {
|
||||
readonly status: "completed"
|
||||
result: Tool.Result
|
||||
}
|
||||
| {
|
||||
readonly status: "error"
|
||||
error: Tool.Error
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export interface ToolDomain {
|
||||
readonly transform: Transform<ToolDraft>
|
||||
readonly hook: Hooks<ToolHooks>
|
||||
}
|
||||
9
packages/plugin/src/promise/types.ts
Normal file
9
packages/plugin/src/promise/types.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export type DeepMutable<A> = A extends (...args: never[]) => unknown
|
||||
? A
|
||||
: A extends ReadonlyMap<infer K, infer V>
|
||||
? Map<DeepMutable<K>, DeepMutable<V>>
|
||||
: A extends ReadonlyArray<infer I>
|
||||
? DeepMutable<I>[]
|
||||
: A extends object
|
||||
? { -readonly [K in keyof A]: DeepMutable<A[K]> }
|
||||
: A
|
||||
25
packages/plugin/src/promise/websearch.ts
Normal file
25
packages/plugin/src/promise/websearch.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import type { WebSearch } from "@opencode-ai/schema/websearch"
|
||||
import type { WebSearchApi } from "@opencode-ai/client/promise/api"
|
||||
import type { Transform } from "./registration.js"
|
||||
|
||||
export interface WebSearchDefinition {
|
||||
readonly id: string
|
||||
readonly name: string
|
||||
readonly execute: (
|
||||
input: WebSearch.ProviderInput,
|
||||
context: { readonly signal: AbortSignal },
|
||||
) => Promise<readonly WebSearch.Result[]>
|
||||
}
|
||||
|
||||
export interface WebSearchDomain extends WebSearchApi {
|
||||
readonly transform: Transform<WebSearchDraft>
|
||||
readonly reload: () => Promise<void>
|
||||
}
|
||||
|
||||
export interface WebSearchDraft {
|
||||
add(definition: WebSearchDefinition): void
|
||||
readonly default: {
|
||||
get(): string | undefined
|
||||
set(providerID: string): void
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue