import { type ProviderDriverKind, 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; prompt: string; modelOptions: ReadonlyArray | null | undefined; }; export type ComposerProviderState = { provider: ProviderDriverKind; promptEffort: string | null; modelOptionsForDispatch: ReadonlyArray | undefined; composerFrameClassName?: string; composerSurfaceClassName?: string; modelPickerIconClassName?: string; }; type TraitsRenderInput = { provider: ProviderDriverKind; threadRef?: ScopedThreadRef; draftId?: DraftId; model: string; models: ReadonlyArray; modelOptions: ReadonlyArray | undefined; prompt: string; onPromptChange: (prompt: string) => void; }; export function getComposerProviderState(input: ComposerProviderStateInput): ComposerProviderState { const { provider, model, models, prompt, modelOptions } = input; const caps = getProviderModelCapabilities(models, model, provider); 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 && isClaudeUltrathinkPrompt(prompt); return { provider, promptEffort, modelOptionsForDispatch: buildProviderOptionSelectionsFromDescriptors(descriptors), ...(ultrathinkActive ? { composerFrameClassName: "ultrathink-frame", composerSurfaceClassName: "shadow-[0_0_0_1px_rgba(255,255,255,0.04)_inset]", modelPickerIconClassName: "ultrathink-chroma", } : {}), }; } function renderTraitsControl( Component: typeof TraitsMenuContent | typeof TraitsPicker, input: TraitsRenderInput, ): ReactNode { const { provider, threadRef, draftId, model, models, modelOptions, prompt, onPromptChange } = input; const hasTarget = threadRef !== undefined || draftId !== undefined; if ( !hasTarget || !shouldRenderTraitsControls({ provider, models, model, modelOptions, prompt }) ) { return null; } return ( ); } export function renderProviderTraitsMenuContent(input: TraitsRenderInput): ReactNode { return renderTraitsControl(TraitsMenuContent, input); } export function renderProviderTraitsPicker(input: TraitsRenderInput): ReactNode { return renderTraitsControl(TraitsPicker, input); }