1- import { ArrowLeft , ArrowRight , Check } from "@phosphor-icons/react" ;
1+ import {
2+ ArrowLeft ,
3+ ArrowRight ,
4+ CaretRight ,
5+ Check ,
6+ } from "@phosphor-icons/react" ;
27import type { LoopSchemas } from "@posthog/api-client/loops" ;
38import { SettingsOptionSelect } from "@posthog/ui/features/settings/SettingsOptionSelect" ;
49import { 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
0 commit comments