refactor(core): move database schema ownership (#29068)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
Dax
2026-05-30 21:08:38 -04:00
committed by GitHub
parent 6bcb9cb9bb
commit 7f571d36ea
390 changed files with 11127 additions and 9164 deletions
+3 -3
View File
@@ -1,9 +1,9 @@
import type { ContentBlock, ContentChunk, ResourceLink, Role } from "@agentclientprotocol/sdk"
import path from "node:path"
import { pathToFileURL } from "node:url"
import type { MessageV2 } from "@/session/message-v2"
import { SessionLegacy } from "@opencode-ai/core/session/legacy"
export type PromptPart = MessageV2.TextPartInput | MessageV2.FilePartInput
export type PromptPart = SessionLegacy.TextPartInput | SessionLegacy.FilePartInput
export type ReplayPart =
| {
@@ -141,7 +141,7 @@ function uriToFilePart(
uri: string,
mime: string,
filename?: string,
): MessageV2.FilePartInput | MessageV2.TextPartInput {
): SessionLegacy.FilePartInput | SessionLegacy.TextPartInput {
try {
if (uri.startsWith("file://")) {
return {
+7 -7
View File
@@ -2,15 +2,15 @@ import { Agent } from "@/agent/agent"
import { Command } from "@/command"
import { InstanceRef } from "@/effect/instance-ref"
import { InstanceStore } from "@/project/instance-store"
import { ModelID, ProviderID } from "@/provider/schema"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { Provider } from "@/provider/provider"
import { Context, Effect, Layer, SynchronizedRef } from "effect"
import type * as ACPError from "./error"
export type ModelOption = {
readonly providerID: ProviderID
readonly providerID: ProviderV2.ID
readonly providerName: string
readonly modelID: ModelID
readonly modelID: ProviderV2.ModelID
readonly modelName: string
}
@@ -23,13 +23,13 @@ export type ModeOption = {
export type ModelVariants = NonNullable<Provider.Model["variants"]>
export type DefaultModel = {
readonly providerID: ProviderID
readonly modelID: ModelID
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
}
export type Snapshot = {
readonly directory: string
readonly providers: Record<ProviderID, Provider.Info>
readonly providers: Record<ProviderV2.ID, Provider.Info>
readonly modelOptions: readonly ModelOption[]
readonly variantsByModel: Readonly<Record<string, ModelVariants>>
readonly availableModes: readonly ModeOption[]
@@ -58,7 +58,7 @@ export const variants = (snapshot: Snapshot, model: DefaultModel) => snapshot.va
export const build = (input: {
readonly directory: string
readonly providers: Record<ProviderID, Provider.Info>
readonly providers: Record<ProviderV2.ID, Provider.Info>
readonly modes: readonly ModeOption[]
readonly defaultModeID: string
readonly commands: readonly Command.Info[]
+12 -12
View File
@@ -41,7 +41,7 @@ import { ACPEvent } from "./event"
import { ACPSession } from "./session"
import { UsageService } from "./usage"
import { ACPProfile } from "./profile"
import { ModelID, ProviderID } from "@/provider/schema"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { Provider } from "@/provider/provider"
import type { Command } from "@/command"
@@ -603,7 +603,7 @@ function makeUsageService(sdk: OpencodeClient) {
.then((response) => {
const providers = Object.fromEntries(
(response.data?.providers ?? []).map((provider) => [provider.id, provider]),
) as Record<ProviderID, Provider.Info>
) as Record<ProviderV2.ID, Provider.Info>
return UsageService.findContextLimit(providers, params.providerID, params.modelID)
})
.catch((error: unknown) => {
@@ -642,8 +642,8 @@ function makeUsageService(sdk: OpencodeClient) {
const size = yield* contextLimit({
directory: params.directory,
providerID: ProviderID.make(message.providerID),
modelID: ModelID.make(message.modelID),
providerID: ProviderV2.ID.make(message.providerID),
modelID: ProviderV2.ModelID.make(message.modelID),
})
if (!size) return
@@ -745,7 +745,7 @@ async function loadDirectorySnapshot(sdk: OpencodeClient, directory: string) {
const commandsData = commandsResponse.data!
const skills = skillsResponse.data!
const providers = Object.fromEntries(providersData.providers.map((provider) => [provider.id, provider])) as Record<
ProviderID,
ProviderV2.ID,
Provider.Info
>
const defaultModelStarted = performance.now()
@@ -784,7 +784,7 @@ async function loadDirectorySnapshot(sdk: OpencodeClient, directory: string) {
function defaultModelFromConfig(
configuredModel: string | undefined,
providers: Record<ProviderID, Provider.Info>,
providers: Record<ProviderV2.ID, Provider.Info>,
): Directory.DefaultModel | undefined {
const configured = configuredModel ? Provider.parseModel(configuredModel) : undefined
if (configured && providers[configured.providerID]?.models[configured.modelID]) return configured
@@ -792,7 +792,7 @@ function defaultModelFromConfig(
// First-session ACP startup must not scan historical sessions just to infer
// a default. Configured model, opencode provider, then sorted best model keep
// the protocol response deterministic without extra session/message reads.
const opencodeProvider = providers[ProviderID.make("opencode")]
const opencodeProvider = providers[ProviderV2.ID.make("opencode")]
const opencodeModel = opencodeProvider ? Provider.sort(Object.values(opencodeProvider.models))[0] : undefined
if (opencodeProvider && opencodeModel) return { providerID: opencodeProvider.id, modelID: opencodeModel.id }
@@ -805,7 +805,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 ProviderID, modelID: "unknown" as ModelID }
return { providerID: "unknown" as ProviderV2.ID, modelID: "unknown" as ProviderV2.ModelID }
}
function detectSlashCommand(parts: ReturnType<typeof promptContentToParts>) {
@@ -864,8 +864,8 @@ 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[ProviderID.make(selected.model.providerID)]
const model = provider?.models[ModelID.make(selected.model.modelID)]
const provider = snapshot.providers[ProviderV2.ID.make(selected.model.providerID)]
const model = provider?.models[ProviderV2.ModelID.make(selected.model.modelID)]
if (!model) {
return Effect.fail(
new ACPError.InvalidModelError({
@@ -993,7 +993,7 @@ function restoreFromMessages(messages: readonly MessageInfo[]) {
)
if (user?.model?.providerID && user.model.modelID) {
return {
model: { providerID: user.model.providerID as ProviderID, modelID: user.model.modelID as ModelID },
model: { providerID: user.model.providerID as ProviderV2.ID, modelID: user.model.modelID as ProviderV2.ModelID },
variant: user.model.variant,
modeId: user.agent,
}
@@ -1002,7 +1002,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 ProviderID, modelID: assistant.modelID as ModelID },
model: { providerID: assistant.providerID as ProviderV2.ID, modelID: assistant.modelID as ProviderV2.ModelID },
variant: assistant.variant,
modeId: assistant.mode ?? assistant.agent,
}
+3 -3
View File
@@ -1,12 +1,12 @@
import type { McpServer } from "@agentclientprotocol/sdk"
import type { Message, Part } from "@opencode-ai/sdk/v2"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { Context, Effect, Layer, Ref } from "effect"
import type { ModelID, ProviderID } from "../provider/schema"
import * as ACPError from "./error"
export type SelectedModel = {
providerID: ProviderID
modelID: ModelID
providerID: ProviderV2.ID
modelID: ProviderV2.ModelID
}
export type KnownMessagePartMetadata = {
+13 -13
View File
@@ -3,7 +3,7 @@ import * as Log from "@opencode-ai/core/util/log"
import type { AssistantMessage as OpenCodeAssistantMessage, Message } from "@opencode-ai/sdk/v2"
import { InstanceRef } from "@/effect/instance-ref"
import { InstanceStore } from "@/project/instance-store"
import { ModelID, ProviderID } from "@/provider/schema"
import { ProviderV2 } from "@opencode-ai/core/provider"
import { Provider } from "@/provider/provider"
import { Context, Effect, Layer, SynchronizedRef } from "effect"
@@ -38,7 +38,7 @@ export interface MessageLoaderInterface {
}
export interface ContextLimitLoaderInterface {
readonly providers: (directory: string) => Effect.Effect<Record<ProviderID, Provider.Info>, unknown>
readonly providers: (directory: string) => Effect.Effect<Record<ProviderV2.ID, Provider.Info>, unknown>
}
export type UsageConnection = Pick<AgentSideConnection, "sessionUpdate">
@@ -49,8 +49,8 @@ export interface Interface {
readonly totalSessionCost: (messages: readonly SessionMessage[]) => number
readonly contextLimit: (input: {
readonly directory: string
readonly providerID: ProviderID
readonly modelID: ModelID
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
}) => Effect.Effect<number | undefined>
readonly sendUpdate: (input: {
readonly connection: UsageConnection
@@ -110,9 +110,9 @@ export function totalSessionCost(messages: readonly SessionMessage[]): number {
}
export function findContextLimit(
providers: Record<ProviderID, Provider.Info>,
providerID: ProviderID,
modelID: ModelID,
providers: Record<ProviderV2.ID, Provider.Info>,
providerID: ProviderV2.ID,
modelID: ProviderV2.ModelID,
): number | undefined {
return providers[providerID]?.models[modelID]?.limit.context
}
@@ -143,8 +143,8 @@ export const layer = Layer.effect(
const cachedLimit = Effect.fnUntraced(function* (input: {
readonly directory: string
readonly providerID: ProviderID
readonly modelID: ModelID
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
}) {
return yield* SynchronizedRef.modifyEffect(
limits,
@@ -170,8 +170,8 @@ export const layer = Layer.effect(
const contextLimit = Effect.fn("ACPUsage.contextLimit")(function* (input: {
readonly directory: string
readonly providerID: ProviderID
readonly modelID: ModelID
readonly providerID: ProviderV2.ID
readonly modelID: ProviderV2.ModelID
}) {
return yield* yield* cachedLimit(input)
})
@@ -197,8 +197,8 @@ export const layer = Layer.effect(
const size = yield* contextLimit({
directory: input.directory,
providerID: ProviderID.make(message.providerID),
modelID: ModelID.make(message.modelID),
providerID: ProviderV2.ID.make(message.providerID),
modelID: ProviderV2.ModelID.make(message.modelID),
})
if (!size) return