fix: preserve conversation settings for models and scheduled messages

Preserve explicit Runtime model selections and Harness configuration rules without pinning resolved defaults. Expose fixed Runtime models in project settings and keep SSH conversations inheriting their project selection.

Dispatch scheduled instructions through ordinary conversation requests using current history, Runtime, work mode, and knowledge scope. Persist conversation work modes and update scheduling documentation and regression tests.

Validation checkpoint: typecheck, lint, and 104 focused tests passed. The SSH inheritance regression passed in isolation, but its process timed out on exit. Full-suite completion, remaining model documentation review, and real end-to-end validation are still pending.

Release note: Preserve fixed model choices and let scheduled messages use their conversation's current settings and history.
This commit is contained in:
mesalogo
2026-09-10 10:17:45 +08:00
parent fedafa21bd
commit 444902d8ad
22 changed files with 628 additions and 353 deletions
+3 -2
View File
@@ -482,6 +482,7 @@ export const conversationSnapshotSchema = z
projectId: assistantIdSchema.optional(),
runtimeSelection: agentRuntimeSelectionSchema.optional(),
knowledgeLibraryIds: z.array(assistantIdSchema).max(20).optional(),
workMode: workModeSchema.optional(),
knowledgeRetrievalMode: z.enum(['auto', 'always']).optional(),
contextMetrics: conversationContextMetricsSchema.optional(),
contextCompressionState:
@@ -721,9 +722,9 @@ export const scheduleCreateSchema = z
})
.strict()
export type ScheduleCreateInput = z.infer<typeof scheduleCreateSchema>
export type ScheduleCreateInput = z.input<typeof scheduleCreateSchema>
export type AssistantSchedule = ScheduleCreateInput & {
export type AssistantSchedule = z.output<typeof scheduleCreateSchema> & {
id: string
taskId: string
conversationId: string
+7 -2
View File
@@ -397,8 +397,13 @@ export type ConversationQueueUserInput = z.infer<
export type ConversationQueueDispatch = {
item: ConversationQueueItem
input: ConversationQueueUserInput
}
} & (
| { scheduled?: false; input: ConversationQueueUserInput }
| {
scheduled: true
input: Pick<ConversationQueueUserInput, 'conversationId' | 'projectId' | 'prompt'>
}
)
export const runtimeProviderSchema = z.enum([
'auto',
+1 -1
View File
@@ -182,7 +182,7 @@ export function repairChannelRuntimeSelection(
selection.provider === 'opencode' ||
selection.provider === 'continue'
) {
return { provider: selection.provider }
return repairAgentRuntimeSelection(selection, settings)
}
if (selection.provider === 'deepseek-harness') {
const repaired = repairAgentRuntimeSelection(selection, settings)