feat(core): add command registry (#30624)

This commit is contained in:
Dax
2026-06-04 02:57:43 -04:00
committed by GitHub
parent 70bb710715
commit 1ff19103a2
150 changed files with 4753 additions and 2657 deletions
+3 -2
View File
@@ -3,6 +3,7 @@ import { Command } from "@/command"
import { InstanceRef } from "@/effect/instance-ref"
import { InstanceStore } from "@/project/instance-store"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { ModelV2 } from "@opencode-ai/core/model"
import { Provider } from "@/provider/provider"
import { Context, Effect, Layer, SynchronizedRef } from "effect"
import type * as ACPError from "./error"
@@ -10,7 +11,7 @@ import type * as ACPError from "./error"
export type ModelOption = {
readonly providerID: ProviderV2.ID
readonly providerName: string
readonly modelID: ProviderV2.ModelID
readonly modelID: ModelV2.ID
readonly modelName: string
}
@@ -24,7 +25,7 @@ export type ModelVariants = NonNullable<Provider.Model["variants"]>
export type DefaultModel = {
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
readonly modelID: ModelV2.ID
}
export type Snapshot = {
+6 -5
View File
@@ -42,6 +42,7 @@ import { ACPSession } from "./session"
import { UsageService } from "./usage"
import { ACPProfile } from "./profile"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { ModelV2 } from "@opencode-ai/core/model"
import { Provider } from "@/provider/provider"
import type { Command } from "@/command"
@@ -650,7 +651,7 @@ function makeUsageService(sdk: OpencodeClient) {
const size = yield* contextLimit({
directory: params.directory,
providerID: ProviderV2.ID.make(message.providerID),
modelID: ProviderV2.ModelID.make(message.modelID),
modelID: ModelV2.ID.make(message.modelID),
})
if (!size) return
@@ -812,7 +813,7 @@ function selectDefaultModel(snapshot: Directory.Snapshot) {
if (snapshot.defaultModel) return snapshot.defaultModel
const model = snapshot.modelOptions[0]
if (model) return { providerID: model.providerID, modelID: model.modelID }
return { providerID: "unknown" as ProviderV2.ID, modelID: "unknown" as ProviderV2.ModelID }
return { providerID: "unknown" as ProviderV2.ID, modelID: "unknown" as ModelV2.ID }
}
function detectSlashCommand(parts: ReturnType<typeof promptContentToParts>) {
@@ -872,7 +873,7 @@ function configOptions(snapshot: Directory.Snapshot, session: ConfigState) {
function parseSelectedModel(snapshot: Directory.Snapshot, modelId: string) {
const selected = parseModelSelection(modelId, Object.values(snapshot.providers))
const provider = snapshot.providers[ProviderV2.ID.make(selected.model.providerID)]
const model = provider?.models[ProviderV2.ModelID.make(selected.model.modelID)]
const model = provider?.models[ModelV2.ID.make(selected.model.modelID)]
if (!model) {
return Effect.fail(
new ACPError.InvalidModelError({
@@ -1000,7 +1001,7 @@ function restoreFromMessages(messages: readonly MessageInfo[]) {
)
if (user?.model?.providerID && user.model.modelID) {
return {
model: { providerID: user.model.providerID as ProviderV2.ID, modelID: user.model.modelID as ProviderV2.ModelID },
model: { providerID: user.model.providerID as ProviderV2.ID, modelID: user.model.modelID as ModelV2.ID },
variant: user.model.variant,
modeId: user.agent,
}
@@ -1009,7 +1010,7 @@ function restoreFromMessages(messages: readonly MessageInfo[]) {
const assistant = messages.findLast((message) => message.providerID && message.modelID)
if (assistant?.providerID && assistant.modelID) {
return {
model: { providerID: assistant.providerID as ProviderV2.ID, modelID: assistant.modelID as ProviderV2.ModelID },
model: { providerID: assistant.providerID as ProviderV2.ID, modelID: assistant.modelID as ModelV2.ID },
variant: assistant.variant,
modeId: assistant.mode ?? assistant.agent,
}
+2 -1
View File
@@ -1,12 +1,13 @@
import type { McpServer } from "@agentclientprotocol/sdk"
import type { Message, Part } from "@opencode-ai/sdk/v2"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { ModelV2 } from "@opencode-ai/core/model"
import { Context, Effect, Layer, Ref } from "effect"
import * as ACPError from "./error"
export type SelectedModel = {
providerID: ProviderV2.ID
modelID: ProviderV2.ModelID
modelID: ModelV2.ID
}
export type KnownMessagePartMetadata = {
+6 -5
View File
@@ -4,6 +4,7 @@ import type { AssistantMessage as OpenCodeAssistantMessage, Message } from "@ope
import { InstanceRef } from "@/effect/instance-ref"
import { InstanceStore } from "@/project/instance-store"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { ModelV2 } from "@opencode-ai/core/model"
import { Provider } from "@/provider/provider"
import { Context, Effect, Layer, SynchronizedRef } from "effect"
@@ -50,7 +51,7 @@ export interface Interface {
readonly contextLimit: (input: {
readonly directory: string
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
readonly modelID: ModelV2.ID
}) => Effect.Effect<number | undefined>
readonly sendUpdate: (input: {
readonly connection: UsageConnection
@@ -112,7 +113,7 @@ export function totalSessionCost(messages: readonly SessionMessage[]): number {
export function findContextLimit(
providers: Record<ProviderV2.ID, Provider.Info>,
providerID: ProviderV2.ID,
modelID: ProviderV2.ModelID,
modelID: ModelV2.ID,
): number | undefined {
return providers[providerID]?.models[modelID]?.limit.context
}
@@ -144,7 +145,7 @@ export const layer = Layer.effect(
const cachedLimit = Effect.fnUntraced(function* (input: {
readonly directory: string
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
readonly modelID: ModelV2.ID
}) {
return yield* SynchronizedRef.modifyEffect(
limits,
@@ -171,7 +172,7 @@ export const layer = Layer.effect(
const contextLimit = Effect.fn("ACPUsage.contextLimit")(function* (input: {
readonly directory: string
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
readonly modelID: ModelV2.ID
}) {
return yield* yield* cachedLimit(input)
})
@@ -198,7 +199,7 @@ export const layer = Layer.effect(
const size = yield* contextLimit({
directory: input.directory,
providerID: ProviderV2.ID.make(message.providerID),
modelID: ProviderV2.ModelID.make(message.modelID),
modelID: ModelV2.ID.make(message.modelID),
})
if (!size) return