import { useNavigate } from "@tanstack/react-router"; import { useRef, useState } from "react"; import type { ProviderInstanceId, SourceControlWritingStyleMode } from "@t3tools/contracts"; import { DEFAULT_UNIFIED_SETTINGS } from "@t3tools/contracts/settings"; import { createModelSelection } from "@t3tools/shared/model"; import { resolveSourceControlWriterModelSelection } from "@t3tools/shared/serverSettings"; import { useScopedSettings, useScopedSettingsMixed, useUpdateScopedSettings, } from "./useScopedSettings"; import { useScopedModelDisabledReason } from "./useScopedModelAvailability"; import { useSettingsScope } from "./SettingsScopeContext"; import { applyProviderInstanceSettings, deriveProviderInstanceEntries, sortProviderInstanceEntries, } from "../../providerInstances"; import { getCustomModelOptionsByInstance, resolveAppModelSelectionState, } from "../../modelSelection"; import { EMPTY_SERVER_PROVIDERS } from "../../state/server"; import { ProviderModelPicker } from "../chat/ProviderModelPicker"; import { Select, SelectItem, SelectPopup, SelectTrigger, SelectValue } from "../ui/select"; import { Switch } from "../ui/switch"; import { Textarea } from "../ui/textarea"; import { toastManager } from "../ui/toast"; import { Button } from "../ui/button"; import { SETTINGS_PICKER_TRIGGER_CLASSNAME, SettingResetButton, SettingsRow, SettingsSection, } from "./settingsLayout"; import { searchableSetting } from "./settingsSearch"; const MODE_OPTIONS: Record = { repo_conventions: { label: "Repository conventions", description: "In each project, matches recent change descriptions and change request titles.", }, conventional_commits: { label: "Conventional Commits", description: "Use Conventional Commit prefixes and keep change request text concise.", }, custom: { label: "Custom instructions", description: "Use your instructions for change descriptions and change requests in every project.", }, }; export function SourceControlWritingSettingsSection() { const settings = useScopedSettings(); const updateSettings = useUpdateScopedSettings(); const navigate = useNavigate(); const { environment, connectedEnvironments } = useSettingsScope(); // The representative supplies the provider list; a model choice is checked // against every target before it fans out. const environmentId = environment?.environmentId ?? null; const hasServerTargets = connectedEnvironments.length > 0; const serverProviders = environment?.serverConfig?.providers ?? EMPTY_SERVER_PROVIDERS; const writingStyleMixed = useScopedSettingsMixed(["sourceControlWritingStyle"]); const customInstructionsRef = useRef(null); const [editingAllInstructions, setEditingAllInstructions] = useState(false); const [allInstructions, setAllInstructions] = useState(null); const style = settings.sourceControlWritingStyle; const defaults = DEFAULT_UNIFIED_SETTINGS.sourceControlWritingStyle; const isSourceControlWritingStyleDirty = writingStyleMixed || style.mode !== defaults.mode || style.customInstructions !== defaults.customInstructions; const textGenerationProviders = serverProviders.filter( (provider) => provider.supportsTextGeneration !== false, ); const defaultModelSelection = resolveAppModelSelectionState(settings, textGenerationProviders); const usesDedicatedModel = settings.sourceControlWriterModelSelection !== null; const activeSelection = resolveAppModelSelectionState( { ...settings, textGenerationModelSelection: resolveSourceControlWriterModelSelection( settings, textGenerationProviders, ), }, textGenerationProviders, ); const instanceEntries = sortProviderInstanceEntries( applyProviderInstanceSettings(deriveProviderInstanceEntries(textGenerationProviders), settings), ); const canEnableDedicatedModel = instanceEntries.some( (entry) => entry.instanceId === defaultModelSelection.instanceId && entry.enabled && entry.isAvailable, ); const modelOptionsByInstance = getCustomModelOptionsByInstance( settings, textGenerationProviders, activeSelection.instanceId, activeSelection.model, ); const writerModelDisabledReason = useScopedModelDisabledReason(settings, instanceEntries); return ( updateSettings({ sourceControlWritingStyle: { mode: defaults.mode, customInstructions: defaults.customInstructions, }, }) } /> ) : null } control={ } > {writingStyleMixed ? (
{editingAllInstructions ? ( <>