feat: configure supervisor model and story graph use per conversation

Add a supervisor text-model selector using existing connections and a per-conversation story graph switch above knowledge settings. Hide the switch when Supervisor is disabled and enforce conversation preferences at local and remote tool execution boundaries.

Release note: Choose a dedicated supervisor model and control whether each conversation can query existing stories and experiences. Enabling graph access does not start a review or automatically insert context.
This commit is contained in:
mesalogo
2026-10-03 19:16:35 +08:00
parent 492f1d208a
commit 48d7526b7e
47 changed files with 778 additions and 81 deletions
@@ -73,6 +73,7 @@ const applicationPreferencesSchema = z
heartbeatReportTimeoutSeconds: supervisionTimeoutSecondsSchema.optional(),
supervisorOrganizeTimeoutSeconds: supervisionTimeoutSecondsSchema.optional(),
supervisorModelConcurrency: supervisorModelConcurrencySchema.optional(),
supervisorModelProfileId: z.string().uuid().nullable().optional(),
supervisionReview: supervisionReviewSettingsSchema.optional(),
magicNotesShowIncompleteTodoCount: z.boolean().default(true),
magicNoteCommentMode: magicNoteCommentModeSchema.default('immediate'),
+6
View File
@@ -620,6 +620,7 @@ export const conversationSnapshotSchema = z
knowledgeLibraryIds: z.array(assistantIdSchema).max(20).optional(),
workMode: workModeSchema.optional(),
knowledgeRetrievalMode: z.enum(['auto', 'always']).optional(),
storyGraphEnabled: z.boolean().optional(),
contextMetrics: conversationContextMetricsSchema.optional(),
contextCompressionState:
conversationContextCompressionStateSchema.optional(),
@@ -671,6 +672,11 @@ export const conversationSetPinnedSchema = z.object({
pinned: z.boolean()
}).strict()
export const conversationSetStoryGraphSchema = z.object({
conversationId: assistantIdSchema,
enabled: z.boolean()
}).strict()
export type ConversationSetPinnedInput = z.infer<
typeof conversationSetPinnedSchema
>
+1
View File
@@ -2100,6 +2100,7 @@ export type DesktopApi = {
replace: (conversations: ConversationSnapshot[]) => Promise<void>
saveLocal: (batch: LocalConversationSaveBatch) => Promise<void>
setPinned: (input: ConversationSetPinnedInput) => Promise<void>
setStoryGraph: (input: { conversationId: string; enabled: boolean }) => Promise<void>
branchLocal: (
input: ConversationBranchInput
) => Promise<ConversationSnapshot>
+1
View File
@@ -228,6 +228,7 @@ export const ipcChannels = {
conversationsReplace: 'conversations:replace',
conversationsSaveLocal: 'conversations:save-local',
conversationsSetPinned: 'conversations:set-pinned',
conversationsSetStoryGraph: 'conversations:set-story-graph',
conversationsBranchLocal: 'conversations:branch-local',
conversationsDeleteLocal: 'conversations:delete-local',
conversationsChanged: 'conversations:changed',