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<ServerProviderModel>; prompt: string; modelOptions: ReadonlyArray<ProviderOptionSelection> | null | undefined;}; export type ComposerProviderState = { provider: ProviderDriverKind; promptEffort: string | null; modelOptionsForDispatch: ReadonlyArray<ProviderOptionSelection> | undefined; composerFrameClassName?: string; composerSurfaceClassName?: string; modelPickerIconClassName?: string;}; type TraitsRenderInput = { provider: ProviderDriverKind; instanceId?: ProviderInstanceId; threadRef?: ScopedThreadRef; draftId?: DraftId; model: string; models: ReadonlyArray<ServerProviderModel>; modelOptions: ReadonlyArray<ProviderOptionSelection> | 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.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, } = input; const hasTarget = threadRef !== undefined || draftId !== undefined; if ( !hasTarget || !shouldRenderTraitsControls({ provider, models, model, modelOptions, prompt }) ) { return null; } return ( <Component provider={provider} {...(instanceId ? { instanceId } : {})} models={models} {...(threadRef ? { threadRef } : {})} {...(draftId ? { draftId } : {})} model={model} modelOptions={modelOptions} prompt={prompt} onPromptChange={onPromptChange} /> );} export function renderProviderTraitsMenuContent(input: TraitsRenderInput): ReactNode { return renderTraitsControl(TraitsMenuContent, input);} export function renderProviderTraitsPicker(input: TraitsRenderInput): ReactNode { return renderTraitsControl(TraitsPicker, input);}
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<ServerProviderModel>;
prompt: string;
modelOptions: ReadonlyArray<ProviderOptionSelection> | null | undefined;
};
export type ComposerProviderState = {
provider: ProviderDriverKind;
promptEffort: string | null;
modelOptionsForDispatch: ReadonlyArray<ProviderOptionSelection> | undefined;
composerFrameClassName?: string;
composerSurfaceClassName?: string;
modelPickerIconClassName?: string;
};
type TraitsRenderInput = {
provider: ProviderDriverKind;
instanceId?: ProviderInstanceId;
threadRef?: ScopedThreadRef;
draftId?: DraftId;
model: string;
models: ReadonlyArray<ServerProviderModel>;
modelOptions: ReadonlyArray<ProviderOptionSelection> | 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.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,
} = input;
const hasTarget = threadRef !== undefined || draftId !== undefined;
if (
!hasTarget ||
!shouldRenderTraitsControls({ provider, models, model, modelOptions, prompt })
) {
return null;
}
return (
<Component
provider={provider}
{...(instanceId ? { instanceId } : {})}
models={models}
{...(threadRef ? { threadRef } : {})}
{...(draftId ? { draftId } : {})}
model={model}
modelOptions={modelOptions}
prompt={prompt}
onPromptChange={onPromptChange}
/>
);
}
export function renderProviderTraitsMenuContent(input: TraitsRenderInput): ReactNode {
return renderTraitsControl(TraitsMenuContent, input);
}
export function renderProviderTraitsPicker(input: TraitsRenderInput): ReactNode {
return renderTraitsControl(TraitsPicker, input);
}