mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-15 00:52:35 +00:00
Persist session model switches outside event flag (#26765)
This commit is contained in:
@@ -758,7 +758,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
||||
yield* bus.publish(Session.Event.Error, { sessionID: input.sessionID, error: error.toObject() })
|
||||
throw error
|
||||
}
|
||||
const model = input.model ?? agent.model ?? (yield* lastModel(input.sessionID))
|
||||
const model = input.model ?? agent.model ?? (yield* currentModel(input.sessionID))
|
||||
const userMsg: MessageV2.User = {
|
||||
id: input.messageID ?? MessageID.ascending(),
|
||||
sessionID: input.sessionID,
|
||||
@@ -916,7 +916,17 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
||||
return yield* Effect.failCause(exit.cause)
|
||||
})
|
||||
|
||||
const lastModel = Effect.fnUntraced(function* (sessionID: SessionID) {
|
||||
const currentModel = Effect.fnUntraced(function* (sessionID: SessionID) {
|
||||
const current = Database.use((db) =>
|
||||
db.select({ model: SessionTable.model }).from(SessionTable).where(eq(SessionTable.id, sessionID)).get(),
|
||||
)
|
||||
if (current?.model) {
|
||||
return {
|
||||
providerID: ProviderID.make(current.model.providerID),
|
||||
modelID: ModelID.make(current.model.id),
|
||||
...(current.model.variant && current.model.variant !== "default" ? { variant: current.model.variant } : {}),
|
||||
}
|
||||
}
|
||||
const match = yield* sessions.findMessage(sessionID, (m) => m.info.role === "user" && !!m.info.model)
|
||||
if (Option.isSome(match) && match.value.info.role === "user") return match.value.info.model
|
||||
return yield* provider.defaultModel()
|
||||
@@ -933,7 +943,14 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
||||
throw error
|
||||
}
|
||||
|
||||
const model = input.model ?? ag.model ?? (yield* lastModel(input.sessionID))
|
||||
const current = Database.use((db) =>
|
||||
db
|
||||
.select({ agent: SessionTable.agent, model: SessionTable.model })
|
||||
.from(SessionTable)
|
||||
.where(eq(SessionTable.id, input.sessionID))
|
||||
.get(),
|
||||
)
|
||||
const model = input.model ?? ag.model ?? (yield* currentModel(input.sessionID))
|
||||
const same = ag.model && model.providerID === ag.model.providerID && model.modelID === ag.model.modelID
|
||||
const full =
|
||||
!input.variant && ag.variant && same
|
||||
@@ -957,34 +974,35 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
||||
format: input.format,
|
||||
}
|
||||
|
||||
const current = Database.use((db) =>
|
||||
db
|
||||
.select({ agent: SessionTable.agent, model: SessionTable.model })
|
||||
.from(SessionTable)
|
||||
.where(eq(SessionTable.id, input.sessionID))
|
||||
.get(),
|
||||
)
|
||||
if (current?.agent !== info.agent) {
|
||||
EventV2.run(SessionEvent.AgentSwitched.Sync, {
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(info.time.created),
|
||||
agent: info.agent,
|
||||
})
|
||||
EventV2.run(
|
||||
SessionEvent.AgentSwitched.Sync,
|
||||
{
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(info.time.created),
|
||||
agent: info.agent,
|
||||
},
|
||||
{ bypassExperimentalEventSystem: true },
|
||||
)
|
||||
}
|
||||
if (
|
||||
current?.model?.providerID !== info.model.providerID ||
|
||||
current.model.id !== info.model.modelID ||
|
||||
current.model.variant !== info.model.variant
|
||||
(current.model.variant === "default" ? undefined : current.model.variant) !== info.model.variant
|
||||
) {
|
||||
EventV2.run(SessionEvent.ModelSwitched.Sync, {
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(info.time.created),
|
||||
model: {
|
||||
id: Modelv2.ID.make(info.model.modelID),
|
||||
providerID: Modelv2.ProviderID.make(info.model.providerID),
|
||||
variant: Modelv2.VariantID.make(info.model.variant ?? "default"),
|
||||
EventV2.run(
|
||||
SessionEvent.ModelSwitched.Sync,
|
||||
{
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(info.time.created),
|
||||
model: {
|
||||
id: Modelv2.ID.make(info.model.modelID),
|
||||
providerID: Modelv2.ProviderID.make(info.model.providerID),
|
||||
variant: Modelv2.VariantID.make(info.model.variant ?? "default"),
|
||||
},
|
||||
},
|
||||
})
|
||||
{ bypassExperimentalEventSystem: true },
|
||||
)
|
||||
}
|
||||
|
||||
yield* Effect.addFinalizer(() => instruction.clear(info.id))
|
||||
@@ -1704,7 +1722,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
||||
if (cmdAgent?.model) return cmdAgent.model
|
||||
}
|
||||
if (input.model) return Provider.parseModel(input.model)
|
||||
return yield* lastModel(input.sessionID)
|
||||
return yield* currentModel(input.sessionID)
|
||||
})
|
||||
|
||||
yield* getModel(taskModel.providerID, taskModel.modelID, input.sessionID)
|
||||
@@ -1737,7 +1755,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
||||
const userModel = isSubtask
|
||||
? input.model
|
||||
? Provider.parseModel(input.model)
|
||||
: yield* lastModel(input.sessionID)
|
||||
: yield* currentModel(input.sessionID)
|
||||
: taskModel
|
||||
|
||||
yield* plugin.trigger(
|
||||
|
||||
@@ -44,9 +44,10 @@ export function define<const Type extends string, Fields extends Schema.Struct.F
|
||||
export function run<Def extends SyncEvent.Definition>(
|
||||
def: Def,
|
||||
data: SyncEvent.Event<Def>["data"],
|
||||
options?: { publish?: boolean },
|
||||
// Temporary escape hatch while the full v2 event system remains experimental.
|
||||
options?: { publish?: boolean; bypassExperimentalEventSystem?: boolean },
|
||||
) {
|
||||
if (!Flag.OPENCODE_EXPERIMENTAL_EVENT_SYSTEM) return
|
||||
if (!options?.bypassExperimentalEventSystem && !Flag.OPENCODE_EXPERIMENTAL_EVENT_SYSTEM) return
|
||||
SyncEvent.run(def, data, options)
|
||||
}
|
||||
|
||||
|
||||
@@ -269,18 +269,26 @@ export const layer = Layer.effect(
|
||||
shell: Effect.fn("V2Session.shell")(function* (_input) {}),
|
||||
skill: Effect.fn("V2Session.skill")(function* (_input) {}),
|
||||
switchAgent: Effect.fn("V2Session.switchAgent")(function* (input) {
|
||||
EventV2.run(SessionEvent.AgentSwitched.Sync, {
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(Date.now()),
|
||||
agent: input.agent,
|
||||
})
|
||||
EventV2.run(
|
||||
SessionEvent.AgentSwitched.Sync,
|
||||
{
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(Date.now()),
|
||||
agent: input.agent,
|
||||
},
|
||||
{ bypassExperimentalEventSystem: true },
|
||||
)
|
||||
}),
|
||||
switchModel: Effect.fn("V2Session.switchModel")(function* (input) {
|
||||
EventV2.run(SessionEvent.ModelSwitched.Sync, {
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(Date.now()),
|
||||
model: input.model,
|
||||
})
|
||||
EventV2.run(
|
||||
SessionEvent.ModelSwitched.Sync,
|
||||
{
|
||||
sessionID: input.sessionID,
|
||||
timestamp: DateTime.makeUnsafe(Date.now()),
|
||||
model: input.model,
|
||||
},
|
||||
{ bypassExperimentalEventSystem: true },
|
||||
)
|
||||
}),
|
||||
subagent: Effect.fn("V2Session.subagent")(function* (input) {
|
||||
const parent = yield* result.get(input.parentID)
|
||||
|
||||
Reference in New Issue
Block a user