import { type ProviderDriverKind, type ProviderInstanceId, type ProviderOptionSelection, type ScopedThreadRef, type ServerProviderModel, } from "@t3tools/contracts"; import { buildProviderOptionSelectionsFromDescriptors, getProviderOptionCurrentValue, getProviderOptionDescriptors, isClaudeUltrathinkPrompt, } from "@t3tools/shared/model"; import type { ReactNode } from "react"; import type { DraftId } from "../../composerDraftStore"; import { getProviderModelCapabilities } from "../../providerModels"; import { shouldRenderTraitsControls, TraitsMenuContent, TraitsPicker } from "./TraitsPicker"; export type ComposerProviderStateInput = { provider: ProviderDriverKind; model: string; models: ReadonlyArray; promptInjectionState?: ComposerPromptInjectionState; modelOptions: ReadonlyArray | null | undefined; planModeEnabled: boolean; }; export type ComposerPromptInjectionState = "none" | "ultrathink"; export type ComposerProviderState = { provider: ProviderDriverKind; promptEffort: string | null; modelOptionsForDispatch: ReadonlyArray | undefined; composerFrameClassName?: string; composerSurfaceClassName?: string; modelPickerIconClassName?: string; }; type TraitsRenderInput = { provider: ProviderDriverKind; instanceId?: ProviderInstanceId; threadRef?: ScopedThreadRef; draftId?: DraftId; model: string; models: ReadonlyArray; modelOptions: ReadonlyArray | undefined; prompt: string; onPromptChange: (prompt: string) => void; planModeEnabled: boolean; }; export function getComposerPromptInjectionState(prompt: string): ComposerPromptInjectionState { return isClaudeUltrathinkPrompt(prompt) ? "ultrathink" : "none"; } export function getComposerProviderState(input: ComposerProviderStateInput): ComposerProviderState { const { provider, model, models, modelOptions, promptInjectionState = "none", planModeEnabled, } = input; const caps = getProviderModelCapabilities(models, model, provider, planModeEnabled); const descriptors = getProviderOptionDescriptors({ caps, selections: modelOptions }); const primarySelectDescriptor = descriptors.find( (descriptor): descriptor is Extract<(typeof descriptors)[number], { type: "select" }> => descriptor.type === "select", ); const primaryValue = getProviderOptionCurrentValue(primarySelectDescriptor ?? null); const promptEffort = typeof primaryValue === "string" ? primaryValue : null; const ultrathinkActive = (primarySelectDescriptor?.promptInjectedValues?.length ?? 0) > 0 && promptInjectionState === "ultrathink"; return { provider, promptEffort, modelOptionsForDispatch: buildProviderOptionSelectionsFromDescriptors(descriptors), ...(ultrathinkActive ? { composerFrameClassName: "ultrathink-frame", composerSurfaceClassName: "shadow-[0_0_0_1px_rgba(255,255,255,0.07)_inset]", modelPickerIconClassName: "ultrathink-chroma", } : {}), }; } function renderTraitsControl( Component: typeof TraitsMenuContent | typeof TraitsPicker, input: TraitsRenderInput, ): ReactNode { const { provider, instanceId, threadRef, draftId, model, models, modelOptions, prompt, onPromptChange, planModeEnabled, } = input; const hasTarget = threadRef !== undefined || draftId !== undefined; if ( !hasTarget || !shouldRenderTraitsControls({ provider, models, model, modelOptions, prompt, planModeEnabled, }) ) { return null; } return ( ); } export function renderProviderTraitsMenuContent(input: TraitsRenderInput): ReactNode { return renderTraitsControl(TraitsMenuContent, input); } export function renderProviderTraitsPicker(input: TraitsRenderInput): ReactNode { return renderTraitsControl(TraitsPicker, input); }