refactor(core): consolidate tool architecture

This commit is contained in:
Dax Raad 2026-07-26 20:08:55 -04:00
commit 8db7487c89
466 changed files with 9405 additions and 11071 deletions

View file

@ -1,21 +1,15 @@
import { Plugin } from "@opencode-ai/plugin/v2/effect"
import { AgentV2 } from "@opencode-ai/core/agent"
import { Plugin } from "@opencode-ai/plugin/effect"
import type { IntegrationMethodRegistration } from "@opencode-ai/plugin/effect/integration"
import { Agent } from "@opencode-ai/core/agent"
import { Catalog } from "@opencode-ai/core/catalog"
import { Credential } from "@opencode-ai/core/credential"
import { Integration } from "@opencode-ai/core/integration"
import { Location } from "@opencode-ai/core/location"
import { ModelV2 } from "@opencode-ai/core/model"
import { Model } from "@opencode-ai/core/model"
import { Project } from "@opencode-ai/core/project"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { Provider } from "@opencode-ai/core/provider"
import { AbsolutePath } from "@opencode-ai/core/schema"
import { WebSearch } from "@opencode-ai/core/websearch"
import type {
CredentialOAuth,
IntegrationCommandMethod,
IntegrationEnvMethod,
IntegrationKeyMethod,
IntegrationOAuthMethod,
} from "@opencode-ai/sdk/v2/types"
import { Effect, Stream } from "effect"
type Overrides = Partial<Omit<Plugin.Context, "options" | "session">> & {
@ -41,7 +35,6 @@ export function host(overrides: Overrides = {}): Plugin.Context {
get: () => Effect.die("unused catalog.provider.get"),
},
model: {
get: () => Effect.die("unused catalog.model.get"),
list: () => Effect.die("unused catalog.model.list"),
default: () => Effect.die("unused catalog.model.default"),
},
@ -116,9 +109,22 @@ export function host(overrides: Overrides = {}): Plugin.Context {
}
}
export function agentHost(agent: AgentV2.Interface): Plugin.Context["agent"] {
export function agentHost(agent: Agent.Interface): Plugin.Context["agent"] {
return {
get: (id) => agent.get(AgentV2.ID.make(id)).pipe(Effect.map((value) => value && agentInfo(value))),
get: (input) =>
agent.get(input.agentID).pipe(
Effect.flatMap((value) =>
value
? Effect.succeed({
location: new Location.Info({
directory: AbsolutePath.make("/"),
project: { id: Project.ID.make("test"), directory: AbsolutePath.make("/") },
}),
data: agentInfo(value),
})
: Effect.fail(new Error(`Agent not found: ${input.agentID}`)),
),
),
list: () => Effect.die("unused agent.list"),
reload: agent.reload,
transform: (callback) =>
@ -126,17 +132,17 @@ export function agentHost(agent: AgentV2.Interface): Plugin.Context["agent"] {
callback({
list: () => draft.list().map(agentInfo),
get: (id) => {
const value = draft.get(AgentV2.ID.make(id))
const value = draft.get(Agent.ID.make(id))
return value && agentInfo(value)
},
default: (id) => draft.default(id === undefined ? undefined : AgentV2.ID.make(id)),
default: (id) => draft.default(id === undefined ? undefined : Agent.ID.make(id)),
update: (id, update) =>
draft.update(AgentV2.ID.make(id), (value) => {
draft.update(Agent.ID.make(id), (value) => {
const current = agentInfo(value)
update(current)
Object.assign(value, current, { id: AgentV2.ID.make(current.id) })
Object.assign(value, current, { id: Agent.ID.make(current.id) })
}),
remove: (id) => draft.remove(AgentV2.ID.make(id)),
remove: (id) => draft.remove(Agent.ID.make(id)),
}),
),
}
@ -149,10 +155,6 @@ export function catalogHost(catalog: Catalog.Interface): Plugin.Context["catalog
get: () => Effect.die("unused catalog.provider.get"),
},
model: {
get: (providerID, modelID) =>
catalog.model
.get(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID))
.pipe(Effect.map((value) => value && modelInfo(value))),
list: () => Effect.die("unused catalog.model.list"),
default: () => Effect.die("unused catalog.model.default"),
},
@ -167,7 +169,7 @@ export function catalogHost(catalog: Catalog.Interface): Plugin.Context["catalog
models: new Map(Array.from(value.models, ([id, model]) => [id, modelInfo(model)])),
})),
get: (id) => {
const value = draft.provider.get(ProviderV2.ID.make(id))
const value = draft.provider.get(Provider.ID.make(id))
return (
value && {
provider: providerInfo(value.provider),
@ -176,41 +178,41 @@ export function catalogHost(catalog: Catalog.Interface): Plugin.Context["catalog
)
},
update: (id, update) =>
draft.provider.update(ProviderV2.ID.make(id), (value) => {
draft.provider.update(Provider.ID.make(id), (value) => {
const current = providerInfo(value)
update(current)
Object.assign(value, current, { id: ProviderV2.ID.make(current.id) })
Object.assign(value, current, { id: Provider.ID.make(current.id) })
}),
remove: (id) => draft.provider.remove(ProviderV2.ID.make(id)),
remove: (id) => draft.provider.remove(Provider.ID.make(id)),
},
model: {
get: (providerID, modelID) => {
const value = draft.model.get(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID))
const value = draft.model.get(Provider.ID.make(providerID), Model.ID.make(modelID))
return value && modelInfo(value)
},
update: (providerID, modelID, update) =>
draft.model.update(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID), (value) => {
draft.model.update(Provider.ID.make(providerID), Model.ID.make(modelID), (value) => {
const current = modelInfo(value)
update(current)
Object.assign(value, current, {
id: ModelV2.ID.make(current.id),
providerID: ProviderV2.ID.make(current.providerID),
family: current.family === undefined ? undefined : ModelV2.Family.make(current.family),
id: Model.ID.make(current.id),
providerID: Provider.ID.make(current.providerID),
family: current.family === undefined ? undefined : Model.Family.make(current.family),
variants: current.variants?.map((variant) => ({
...variant,
id: ModelV2.VariantID.make(variant.id),
id: Model.VariantID.make(variant.id),
})),
})
}),
remove: (providerID, modelID) =>
draft.model.remove(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID)),
draft.model.remove(Provider.ID.make(providerID), Model.ID.make(modelID)),
default: {
get: () => {
const value = draft.model.default.get()
return value && { providerID: value.providerID, modelID: value.modelID }
},
set: (providerID, modelID) =>
draft.model.default.set(ProviderV2.ID.make(providerID), ModelV2.ID.make(modelID)),
draft.model.default.set(Provider.ID.make(providerID), Model.ID.make(modelID)),
},
},
}),
@ -370,7 +372,7 @@ export function webSearchHost(websearch: WebSearch.Interface): Plugin.Context["w
}
}
function oauthCredential(value: CredentialOAuth) {
function oauthCredential(value: Credential.OAuth) {
return Credential.OAuth.make({ ...value, methodID: Integration.MethodID.make(value.methodID) })
}
@ -390,7 +392,7 @@ function method(value: Integration.Method) {
}
function internalMethod(
value: IntegrationOAuthMethod | IntegrationCommandMethod | IntegrationKeyMethod | IntegrationEnvMethod,
value: IntegrationMethodRegistration["method"],
): Integration.Method {
if (value.type === "env") return value
if (value.type === "key") return value
@ -407,7 +409,7 @@ function internalMethod(
}
}
function agentInfo(value: AgentV2.Info) {
function agentInfo(value: Agent.Info) {
return {
...value,
model: value.model && { ...value.model },
@ -420,7 +422,7 @@ function agentInfo(value: AgentV2.Info) {
}
}
function providerInfo(value: ProviderV2.MutableInfo) {
function providerInfo(value: Provider.MutableInfo) {
return {
...value,
settings: value.settings && { ...value.settings },
@ -429,7 +431,7 @@ function providerInfo(value: ProviderV2.MutableInfo) {
}
}
function modelInfo(value: ModelV2.Info | ModelV2.MutableInfo) {
function modelInfo(value: Model.Info | Model.MutableInfo) {
return {
...value,
settings: value.settings && { ...value.settings },