diff --git a/desktop/src/features/agents/channelAgents.ts b/desktop/src/features/agents/channelAgents.ts index 70a431a1e..ebb2f7a7e 100644 --- a/desktop/src/features/agents/channelAgents.ts +++ b/desktop/src/features/agents/channelAgents.ts @@ -61,10 +61,9 @@ export type CreateChannelManagedAgentInput = { /** Team this instance is deployed from; prevents cross-team reuse. */ teamId?: string | null; /** - * True when `runtime` is a runtime the user deliberately picked to override - * the persona (a deploy-dialog runtime selector), as opposed to a - * missing-runtime fallback. Forwarded to the backend so a persona-backed - * create only pins the harness for a deliberate override. + * Pins `runtime` when the persona has no harness or the selection matches + * its harness. A fallback away from an unavailable configured harness stays + * unpinned so the persona remains authoritative. */ harnessOverride?: boolean; /** Preferred model ID from the persona. Passed to createManagedAgent. */ diff --git a/desktop/src/features/channel-templates/useApplyTemplate.ts b/desktop/src/features/channel-templates/useApplyTemplate.ts index 474767acf..dbb91ce67 100644 --- a/desktop/src/features/channel-templates/useApplyTemplate.ts +++ b/desktop/src/features/channel-templates/useApplyTemplate.ts @@ -9,6 +9,7 @@ import { usePersonasQuery, useTeamsQuery, } from "@/features/agents/hooks"; +import { shouldPinSelectedRuntimeForDefinition } from "@/features/agents/lib/instanceInputForDefinition"; import { resolvePersonaRuntime } from "@/features/agents/lib/resolvePersonaRuntime"; import { resolveTeamPersonas } from "@/features/agents/lib/teamPersonas"; import { useLastRuntime } from "@/features/agents/lib/useLastRuntime"; @@ -86,8 +87,9 @@ export function useApplyTemplate() { if (!persona) continue; if (seenPersonaIds.has(persona.id)) continue; seenPersonaIds.add(persona.id); + const requestedRuntimeId = entry.runtime ?? persona.runtime; const resolved = resolvePersonaRuntime( - entry.runtime ?? persona.runtime, + requestedRuntimeId, runtimes, defaultProvider, ); @@ -96,6 +98,10 @@ export function useApplyTemplate() { runtime: resolved.runtime, name: persona.displayName, personaId: persona.id, + harnessOverride: shouldPinSelectedRuntimeForDefinition( + requestedRuntimeId, + resolved.runtime.id, + ), systemPrompt: persona.systemPrompt, avatarUrl: persona.avatarUrl ?? undefined, model: entry.model ?? persona.model ?? undefined, @@ -112,8 +118,9 @@ export function useApplyTemplate() { for (const persona of resolvedPersonas) { if (seenPersonaIds.has(persona.id)) continue; seenPersonaIds.add(persona.id); + const requestedRuntimeId = teamEntry.runtime ?? persona.runtime; const resolved = resolvePersonaRuntime( - teamEntry.runtime ?? persona.runtime, + requestedRuntimeId, runtimes, defaultProvider, ); @@ -122,6 +129,10 @@ export function useApplyTemplate() { runtime: resolved.runtime, name: persona.displayName, personaId: persona.id, + harnessOverride: shouldPinSelectedRuntimeForDefinition( + requestedRuntimeId, + resolved.runtime.id, + ), systemPrompt: persona.systemPrompt, avatarUrl: persona.avatarUrl ?? undefined, model: teamEntry.model ?? persona.model ?? undefined, diff --git a/desktop/src/features/channels/ui/AddChannelBotDialog.tsx b/desktop/src/features/channels/ui/AddChannelBotDialog.tsx index 2c5a7515c..63bf6f438 100644 --- a/desktop/src/features/channels/ui/AddChannelBotDialog.tsx +++ b/desktop/src/features/channels/ui/AddChannelBotDialog.tsx @@ -12,6 +12,7 @@ import { canResolveAllPersonaRuntimes, resolvePersonaRuntime, } from "@/features/agents/lib/resolvePersonaRuntime"; +import { shouldPinSelectedRuntimeForDefinition } from "@/features/agents/lib/instanceInputForDefinition"; import { getUsableTeams } from "@/features/agents/lib/teamPersonas"; import { AddChannelBotPersonasSection } from "@/features/channels/ui/AddChannelBotPersonasSection"; import { AddChannelBotTeamsSection } from "@/features/channels/ui/AddChannelBotTeamsSection"; @@ -159,7 +160,10 @@ export function AddChannelBotDialog({ runtime: resolved.runtime, name: persona.displayName, personaId: persona.id, - harnessOverride: false, + harnessOverride: shouldPinSelectedRuntimeForDefinition( + persona.runtime, + resolved.runtime.id, + ), systemPrompt: persona.systemPrompt, avatarUrl: persona.avatarUrl ?? undefined, model: persona.model ?? undefined,