feat(core): add command registry (#30624)
This commit is contained in:
@@ -21,6 +21,7 @@ import { RuntimeFlags } from "@/effect/runtime-flags"
|
||||
import { EventV2Bridge } from "@/event-v2-bridge"
|
||||
import { SessionEvent } from "@opencode-ai/core/session/event"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
import { EventV2 } from "@opencode-ai/core/event"
|
||||
|
||||
const log = Log.create({ service: "session.compaction" })
|
||||
@@ -201,7 +202,7 @@ export interface Interface {
|
||||
readonly create: (input: {
|
||||
sessionID: SessionID
|
||||
agent: string
|
||||
model: { providerID: ProviderV2.ID; modelID: ProviderV2.ModelID }
|
||||
model: { providerID: ProviderV2.ID; modelID: ModelV2.ID }
|
||||
auto: boolean
|
||||
overflow?: boolean
|
||||
}) => Effect.Effect<void>
|
||||
@@ -585,7 +586,7 @@ export const layer = Layer.effect(
|
||||
const create = Effect.fn("SessionCompaction.create")(function* (input: {
|
||||
sessionID: SessionID
|
||||
agent: string
|
||||
model: { providerID: ProviderV2.ID; modelID: ProviderV2.ModelID }
|
||||
model: { providerID: ProviderV2.ID; modelID: ModelV2.ID }
|
||||
auto: boolean
|
||||
overflow?: boolean
|
||||
}) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { NonNegativeInt } from "@opencode-ai/core/schema"
|
||||
import { MessageError } from "./message-error"
|
||||
import { AuthError, OutputLengthError } from "./message-error"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
export { AuthError, OutputLengthError } from "./message-error"
|
||||
|
||||
export const ToolCall = Schema.Struct({
|
||||
@@ -120,7 +121,7 @@ export const Info = Schema.Struct({
|
||||
assistant: Schema.optional(
|
||||
Schema.Struct({
|
||||
system: Schema.Array(Schema.String),
|
||||
modelID: ProviderV2.ModelID,
|
||||
modelID: ModelV2.ID,
|
||||
providerID: ProviderV2.ID,
|
||||
path: Schema.Struct({
|
||||
cwd: Schema.String,
|
||||
|
||||
@@ -241,7 +241,7 @@ export const layer = Layer.effect(
|
||||
session: Session.Info
|
||||
history: SessionV1.WithParts[]
|
||||
providerID: ProviderV2.ID
|
||||
modelID: ProviderV2.ModelID
|
||||
modelID: ModelV2.ID
|
||||
}) {
|
||||
if (input.session.parentID) return
|
||||
if (!Session.isDefaultTitle(input.session.title)) return
|
||||
@@ -653,7 +653,7 @@ export const layer = Layer.effect(
|
||||
|
||||
const getModel = Effect.fn("SessionPrompt.getModel")(function* (
|
||||
providerID: ProviderV2.ID,
|
||||
modelID: ProviderV2.ModelID,
|
||||
modelID: ModelV2.ID,
|
||||
sessionID: SessionID,
|
||||
) {
|
||||
const exit = yield* provider.getModel(providerID, modelID).pipe(Effect.exit)
|
||||
@@ -681,7 +681,7 @@ export const layer = Layer.effect(
|
||||
if (current?.model) {
|
||||
return {
|
||||
providerID: ProviderV2.ID.make(current.model.providerID),
|
||||
modelID: ProviderV2.ModelID.make(current.model.id),
|
||||
modelID: ModelV2.ID.make(current.model.id),
|
||||
...(current.model.variant && current.model.variant !== "default" ? { variant: current.model.variant } : {}),
|
||||
}
|
||||
}
|
||||
@@ -1679,7 +1679,7 @@ export const defaultLayer = Layer.suspend(() =>
|
||||
)
|
||||
const ModelRef = Schema.Struct({
|
||||
providerID: ProviderV2.ID,
|
||||
modelID: ProviderV2.ModelID,
|
||||
modelID: ModelV2.ID,
|
||||
})
|
||||
|
||||
export const PromptInput = Schema.Struct({
|
||||
|
||||
@@ -40,9 +40,10 @@ import type { Provider } from "@/provider/provider"
|
||||
import { Permission } from "@/permission"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Effect, Layer, Option, Context, Schema, Types } from "effect"
|
||||
import { AbsolutePath, NonNegativeInt, optionalOmitUndefined } from "@opencode-ai/core/schema"
|
||||
import { NonNegativeInt, optionalOmitUndefined } from "@opencode-ai/core/schema"
|
||||
import { RuntimeFlags } from "@/effect/runtime-flags"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
|
||||
const log = Log.create({ service: "session" })
|
||||
const runtime = makeRuntime(Database.Service, Database.defaultLayer)
|
||||
@@ -82,7 +83,7 @@ export function fromRow(row: SessionRow): Info {
|
||||
agent: row.agent ?? undefined,
|
||||
model: row.model
|
||||
? {
|
||||
id: ProviderV2.ModelID.make(row.model.id),
|
||||
id: ModelV2.ID.make(row.model.id),
|
||||
providerID: ProviderV2.ID.make(row.model.providerID),
|
||||
variant: row.model.variant,
|
||||
}
|
||||
@@ -112,13 +113,6 @@ export function fromRow(row: SessionRow): Info {
|
||||
}
|
||||
}
|
||||
|
||||
function eventLocation(info: Pick<Info, "directory" | "workspaceID">) {
|
||||
return {
|
||||
directory: AbsolutePath.make(info.directory),
|
||||
workspaceID: info.workspaceID,
|
||||
}
|
||||
}
|
||||
|
||||
export function toRow(info: Info) {
|
||||
return {
|
||||
id: info.id,
|
||||
@@ -209,7 +203,7 @@ const Revert = Schema.Struct({
|
||||
})
|
||||
|
||||
const Model = Schema.Struct({
|
||||
id: ProviderV2.ModelID,
|
||||
id: ModelV2.ID,
|
||||
providerID: ProviderV2.ID,
|
||||
variant: optionalOmitUndefined(Schema.String),
|
||||
})
|
||||
@@ -544,20 +538,6 @@ export const layer: Layer.Layer<
|
||||
const events = yield* EventV2Bridge.Service
|
||||
const flags = yield* RuntimeFlags.Service
|
||||
|
||||
const locationForSession = Effect.fnUntraced(function* (sessionID: SessionID) {
|
||||
const row = yield* db
|
||||
.select({ directory: SessionTable.directory, workspaceID: SessionTable.workspace_id })
|
||||
.from(SessionTable)
|
||||
.where(eq(SessionTable.id, sessionID))
|
||||
.get()
|
||||
.pipe(Effect.orDie)
|
||||
if (!row) return
|
||||
return {
|
||||
directory: AbsolutePath.make(row.directory),
|
||||
workspaceID: row.workspaceID ?? undefined,
|
||||
}
|
||||
})
|
||||
|
||||
const createNext = Effect.fn("Session.createNext")(function* (input: {
|
||||
id?: SessionID
|
||||
title?: string
|
||||
@@ -597,7 +577,6 @@ export const layer: Layer.Layer<
|
||||
yield* events.publish(
|
||||
SessionV1.Event.Created,
|
||||
{ sessionID: result.id, info: result },
|
||||
{ location: eventLocation(result) },
|
||||
)
|
||||
|
||||
return result
|
||||
@@ -688,7 +667,6 @@ export const layer: Layer.Layer<
|
||||
yield* events.publish(
|
||||
SessionV1.Event.Deleted,
|
||||
{ sessionID, info: session },
|
||||
{ location: eventLocation(session) },
|
||||
)
|
||||
yield* events.remove(sessionID)
|
||||
} catch (e) {
|
||||
@@ -698,14 +676,12 @@ export const layer: Layer.Layer<
|
||||
|
||||
const updateMessage = <T extends SessionV1.Info>(msg: T): Effect.Effect<T> =>
|
||||
Effect.gen(function* () {
|
||||
const location = yield* locationForSession(msg.sessionID)
|
||||
yield* events.publish(SessionV1.Event.MessageUpdated, { sessionID: msg.sessionID, info: msg }, { location })
|
||||
yield* events.publish(SessionV1.Event.MessageUpdated, { sessionID: msg.sessionID, info: msg })
|
||||
return msg
|
||||
}).pipe(Effect.withSpan("Session.updateMessage"))
|
||||
|
||||
const updatePart = <T extends SessionV1.Part>(part: T): Effect.Effect<T> =>
|
||||
Effect.gen(function* () {
|
||||
const location = yield* locationForSession(part.sessionID)
|
||||
yield* events.publish(
|
||||
SessionV1.Event.PartUpdated,
|
||||
{
|
||||
@@ -713,7 +689,6 @@ export const layer: Layer.Layer<
|
||||
part: structuredClone(part),
|
||||
time: Date.now(),
|
||||
},
|
||||
{ location },
|
||||
)
|
||||
return part
|
||||
}).pipe(Effect.withSpan("Session.updatePart"))
|
||||
@@ -819,7 +794,7 @@ export const layer: Layer.Layer<
|
||||
revert: info.revert === null ? undefined : (info.revert ?? current.revert),
|
||||
permission: info.permission === null ? undefined : (info.permission ?? current.permission),
|
||||
} as Info
|
||||
yield* events.publish(SessionV1.Event.Updated, { sessionID, info: next }, { location: eventLocation(next) })
|
||||
yield* events.publish(SessionV1.Event.Updated, { sessionID, info: next })
|
||||
})
|
||||
|
||||
const touch = Effect.fn("Session.touch")(function* (sessionID: SessionID) {
|
||||
@@ -917,14 +892,12 @@ export const layer: Layer.Layer<
|
||||
sessionID: SessionID
|
||||
messageID: MessageID
|
||||
}) {
|
||||
const location = yield* locationForSession(input.sessionID)
|
||||
yield* events.publish(
|
||||
SessionV1.Event.MessageRemoved,
|
||||
{
|
||||
sessionID: input.sessionID,
|
||||
messageID: input.messageID,
|
||||
},
|
||||
{ location },
|
||||
)
|
||||
return input.messageID
|
||||
})
|
||||
@@ -934,7 +907,6 @@ export const layer: Layer.Layer<
|
||||
messageID: MessageID
|
||||
partID: PartID
|
||||
}) {
|
||||
const location = yield* locationForSession(input.sessionID)
|
||||
yield* events.publish(
|
||||
SessionV1.Event.PartRemoved,
|
||||
{
|
||||
@@ -942,7 +914,6 @@ export const layer: Layer.Layer<
|
||||
messageID: input.messageID,
|
||||
partID: input.partID,
|
||||
},
|
||||
{ location },
|
||||
)
|
||||
return input.partID
|
||||
})
|
||||
|
||||
@@ -20,6 +20,7 @@ import { PartID } from "./schema"
|
||||
import { Log } from "@opencode-ai/core/util/log"
|
||||
import { EffectBridge } from "@/effect/bridge"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
|
||||
const log = Log.create({ service: "session.tools" })
|
||||
|
||||
@@ -75,7 +76,7 @@ export const resolve = Effect.fn("SessionTools.resolve")(function* (input: {
|
||||
})
|
||||
|
||||
for (const item of yield* registry.tools({
|
||||
modelID: ProviderV2.ModelID.make(input.model.api.id),
|
||||
modelID: ModelV2.ID.make(input.model.api.id),
|
||||
providerID: input.model.providerID,
|
||||
agent: input.agent,
|
||||
})) {
|
||||
|
||||
Reference in New Issue
Block a user