Skip to content
Source
Sign inSign up
Open History to see the last commit

ManagedRuntimeModeNotice.tsx

51 lines1.9 KB

1import {
2 clampManagedRuntimeMode,
3 managedRuntimeModeDenial,
4 type ManagedPolicySummary,
5 type RuntimeMode,
6} from "@t3tools/contracts";
7import { View } from "react-native";
8​
9import { AppText } from "../../components/ui/AppText";
10import { Button } from "../../components/ui/Button";
11import {
12 updateComposerDraftSettings,
13 useComposerDraftSettings,
14} from "../../state/use-composer-drafts";
15import { runtimeModeChoicesForSupportedModes } from "./thread-settings-options";
16​
17/**
18 * Shown while a thread's mode is above its environment's managed ceiling, where the server
19 * refuses every turn. Switching sets the draft's mode, which the next send applies first.
20 */
21export function ManagedRuntimeModeNotice(props: {
22 readonly threadKey: string;
23 readonly threadRuntimeMode: RuntimeMode;
24 readonly supportedRuntimeModes: ReadonlyArray<RuntimeMode> | undefined;
25 readonly policy: ManagedPolicySummary | undefined;
26}) {
27 const draftSettings = useComposerDraftSettings(props.threadKey);
28 const runtimeMode = draftSettings.runtimeMode ?? props.threadRuntimeMode;
29 const denial = managedRuntimeModeDenial(props.policy, runtimeMode);
30 if (denial === undefined) return null;
31 const choices = runtimeModeChoicesForSupportedModes(props.supportedRuntimeModes);
32 const target = clampManagedRuntimeMode(
33 props.policy,
34 runtimeMode,
35 choices.map((choice) => choice.mode),
36 );
37 const targetLabel = choices.find((choice) => choice.mode === target)?.label;
38 return (
39 <View className="gap-2 px-4 pb-3">
40 <AppText textRole="footnote" className="text-foreground-muted">
41 {`${denial} Switch this thread's mode to continue.`}
42 </AppText>
43 {target === undefined || targetLabel === undefined ? null : (
44 <Button
45 label={`Switch to ${targetLabel}`}
46 onPress={() => updateComposerDraftSettings(props.threadKey, { runtimeMode: target })}
47 />
48 )}
49 </View>
50 );