Skip to content

Commit 542dfab

Browse files
committed
feat(loops): move model behind advanced with server-picked default
1 parent 154c0c3 commit 542dfab

3 files changed

Lines changed: 65 additions & 29 deletions

File tree

packages/ui/src/features/loops/components/LoopForm.tsx

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { ArrowLeft, ArrowRight, Check } from "@phosphor-icons/react";
1+
import {
2+
ArrowLeft,
3+
ArrowRight,
4+
CaretRight,
5+
Check,
6+
} from "@phosphor-icons/react";
27
import type { LoopSchemas } from "@posthog/api-client/loops";
38
import { SettingsOptionSelect } from "@posthog/ui/features/settings/SettingsOptionSelect";
49
import { useSetHeaderContent } from "@posthog/ui/hooks/useSetHeaderContent";
@@ -59,6 +64,11 @@ export function LoopForm({ loop }: LoopFormProps) {
5964
return { ...emptyLoopFormValues(), ...(prefill ?? {}) };
6065
});
6166
const [step, setStep] = useState(0);
67+
// Open when editing a loop that already pins a model, so the pinned value
68+
// is visible without hunting for it.
69+
const [showAdvanced, setShowAdvanced] = useState(
70+
() => !!(loop && (loop.model || loop.reasoning_effort)),
71+
);
6272

6373
useEffect(() => {
6474
if (!loop) useLoopDraftStore.getState().setPrefill(null);
@@ -74,7 +84,7 @@ export function LoopForm({ loop }: LoopFormProps) {
7484
const stepComplete = [
7585
!!values.name.trim() && !!values.instructions.trim(),
7686
values.triggers.every(isTriggerDraftValid),
77-
!!values.model.trim(),
87+
true,
7888
isLoopFormValid(values),
7989
];
8090
const isLastStep = step === STEPS.length - 1;
@@ -174,7 +184,7 @@ export function LoopForm({ loop }: LoopFormProps) {
174184
{step === 2 ? (
175185
<Step
176186
title="Options"
177-
description="Who can see it, which model runs it, and how you hear about runs."
187+
description="Who can see it and how you hear about runs."
178188
>
179189
<Field label="Visibility" className="max-w-[340px]">
180190
<SettingsOptionSelect
@@ -192,20 +202,6 @@ export function LoopForm({ loop }: LoopFormProps) {
192202

193203
<Divider />
194204

195-
<LoopModelFields
196-
adapter={values.runtimeAdapter}
197-
model={values.model}
198-
reasoningEffort={values.reasoningEffort}
199-
disabled={isSubmitting}
200-
onAdapterChange={(runtimeAdapter) => patch({ runtimeAdapter })}
201-
onModelChange={(model) => patch({ model })}
202-
onReasoningEffortChange={(reasoningEffort) =>
203-
patch({ reasoningEffort })
204-
}
205-
/>
206-
207-
<Divider />
208-
209205
<Field
210206
label="Repository"
211207
hint={
@@ -241,6 +237,44 @@ export function LoopForm({ loop }: LoopFormProps) {
241237
onChange={(notifications) => patch({ notifications })}
242238
/>
243239
</Field>
240+
241+
<Divider />
242+
243+
<Flex direction="column" gap="4">
244+
<button
245+
type="button"
246+
onClick={() => setShowAdvanced((open) => !open)}
247+
className="flex items-center gap-1.5 text-left"
248+
>
249+
<CaretRight
250+
size={12}
251+
className={`text-gray-10 transition-transform ${
252+
showAdvanced ? "rotate-90" : ""
253+
}`}
254+
/>
255+
<Text className="font-medium text-[12.5px] text-gray-11">
256+
Advanced
257+
</Text>
258+
<Text className="text-[11.5px] text-gray-9">
259+
Model and reasoning
260+
</Text>
261+
</button>
262+
{showAdvanced ? (
263+
<LoopModelFields
264+
adapter={values.runtimeAdapter}
265+
model={values.model}
266+
reasoningEffort={values.reasoningEffort}
267+
disabled={isSubmitting}
268+
onAdapterChange={(runtimeAdapter) =>
269+
patch({ runtimeAdapter })
270+
}
271+
onModelChange={(model) => patch({ model })}
272+
onReasoningEffortChange={(reasoningEffort) =>
273+
patch({ reasoningEffort })
274+
}
275+
/>
276+
) : null}
277+
</Flex>
244278
</Step>
245279
) : null}
246280

@@ -420,7 +454,7 @@ function ReviewList({ values }: { values: LoopFormValues }) {
420454
<ReviewRow
421455
label="Model"
422456
value={`${ADAPTER_LABELS[values.runtimeAdapter]} · ${
423-
values.model || "Not selected"
457+
values.model || "Default model"
424458
} · ${reasoning} reasoning`}
425459
/>
426460
<ReviewRow

packages/ui/src/features/loops/components/LoopModelFields.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const ADAPTER_OPTIONS: {
1414
];
1515

1616
const AUTO_REASONING_VALUE = "auto";
17+
const DEFAULT_MODEL_VALUE = "__default__";
1718

1819
const REASONING_EFFORT_OPTIONS: {
1920
value: LoopSchemas.LoopReasoningEffortEnum | typeof AUTO_REASONING_VALUE;
@@ -76,23 +77,28 @@ export function LoopModelFields({
7677
if (model) {
7778
ids.add(model);
7879
}
79-
return Array.from(ids)
80+
const catalogOptions = Array.from(ids)
8081
.sort((a, b) => a.localeCompare(b))
8182
.map((id) => ({ value: id, label: id }));
83+
return [
84+
{ value: DEFAULT_MODEL_VALUE, label: "Default (recommended)" },
85+
...catalogOptions,
86+
];
8287
}, [catalog, model]);
8388

8489
return (
8590
<Flex direction="column" gap="4">
8691
<Field
8792
label="Model"
88-
required
89-
hint="Validated against the available model catalog when the loop runs."
93+
hint="Default lets PostHog pick the model each run; choose one to pin it."
9094
>
9195
<SettingsOptionSelect
92-
value={model}
96+
value={model || DEFAULT_MODEL_VALUE}
9397
options={modelOptions}
94-
placeholder="Select a model"
95-
onValueChange={onModelChange}
98+
placeholder="Default (recommended)"
99+
onValueChange={(value) =>
100+
onModelChange(value === DEFAULT_MODEL_VALUE ? "" : value)
101+
}
96102
disabled={disabled}
97103
ariaLabel="Model"
98104
/>

packages/ui/src/features/loops/loopFormTypes.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,7 @@ export function formValuesToLoopWrite(
117117
}
118118

119119
export function isLoopFormValid(values: LoopFormValues): boolean {
120-
if (
121-
!values.name.trim() ||
122-
!values.instructions.trim() ||
123-
!values.model.trim()
124-
) {
120+
if (!values.name.trim() || !values.instructions.trim()) {
125121
return false;
126122
}
127123
return values.triggers.every((trigger) => isTriggerDraftValid(trigger));

0 commit comments

Comments
 (0)