inspect: drop per-inspector model selection from guided setup · Entire
inspect: drop per-inspector model selection from guided setup
66ed712→main·
dipree·1mo ago·1 file·+21 added/-33 removed
Inspectors run on the agent's default model, so the interactive crew flow no longer asks for or edits a per-inspector model:
- adding a slot picks only the agent,
- the slot-edit menu offers Change agent (when >1 candidate) + Remove, no Change model,
- the slot label shows a model only when one was set explicitly (e.g. via scripted --set-slot agent=model, which still works).
The judge keeps its model picker (model matters for the consolidating call). Scripted/runtime model handling is unchanged.
Sessions
cc2e5e5a3dccView transcript
?\ Checkout the hand off doc that I just added.Pi·Opus 4.8·1 step
Changes
1
cmd/entire/cli/review
Mpicker.go+21/-33
366 unmodified lines
367
368
369
370
371
372
370
371
372
373
374
375
376
377
378
379
380
381
382
383
378
379
380
7 unmodified lines
388
389
390
397
398
391
392
393
394
395
396
397
398
404
405
406
407
408
399
400
401
411
412
413
414
402
403
404
405
406
407
2 unmodified lines
410
411
412
423
424
425
426
427
413
414
415
416
23 unmodified lines
440
441
442
457
458
459
443
444
445
446
447
461
448
449
450
451
15 unmodified lines
467
468
469
483
484
485
470
471
472
473
474
487
475
476
477
478
366 unmodified lines
if convErr != nil || idx < 0 || idx >= len(slots) {
continue
}
// The agent identifies the slot, so editing defaults to the model
// (the common case). Swapping the agent is offered as a distinct action,
// and only when there is more than one candidate to switch to.
// Inspectors are identified by their agent and run on the agent's
// default model, so editing only swaps the agent (when more than one is
// available) or removes the slot — there is no per-inspector model.
action, err := promptSlotAction(ctx, slots[idx], len(candidates) > 1)
if err != nil {
return nil, err
}
switch action {
case "model":
model, err := promptCrewModel(ctx, slots[idx].agent, slots[idx].model)
if err != nil {
return nil, err
}
slots[idx].model = model
case "agent":
slot, err := promptChangeAgent(ctx, candidates, slots[idx])
if err != nil {
return crewSlot{}, err
}
}
}
// promptCrewSlot prompts for one slot: an agent then a model. seed pre-selects
// the current agent/model when editing an existing slot (zero value when adding).
// promptCrewSlot prompts for one inspector slot: just the agent. Inspectors run
// on the agent's default model, so no model is asked here. seed pre-selects the
// current agent when editing (zero value when adding).
func promptCrewSlot(ctx context.Context, launchable []string, seed crewSlot) (crewSlot, error) {
agentName, err := promptCrewAgent(ctx, launchable, seed.agent, false)
if err != nil {
return crewSlot{}, err
}
model, err := promptCrewModel(ctx, agentName, seed.model)
if err != nil {
return crewSlot{}, err
}
return crewSlot{agent: agentName, model: model}, nil
return crewSlot{agent: agentName}, nil
}
// promptChangeAgent swaps the agent on an existing slot. Because advertised
// models are agent-specific, picking a different agent re-prompts for the model
// (seeded with the current one, so a still-valid/custom value is preserved).
// Keeping the same agent leaves the slot untouched.
// promptChangeAgent swaps the agent on an existing inspector slot. Keeping the
// same agent leaves the slot untouched (preserving any model set via scripted
// config); choosing a different agent resets to that agent's default model.
func promptChangeAgent(ctx context.Context, candidates []string, seed crewSlot) (crewSlot, error) {
agentName, err := promptCrewAgent(ctx, candidates, seed.agent, true)
if err != nil {
return crewSlot{}, err
}
if agentName == seed.agent {
return seed, nil
}
model, err := promptCrewModel(ctx, agentName, seed.model)
if err != nil {
return crewSlot{}, err
}
return crewSlot{agent: agentName, model: model}, nil
return crewSlot{agent: agentName}, nil
}
// buildCrewProfile turns an ordered slot list into a profile. Each slot becomes
23 unmodified lines
return profile
}
// promptSlotAction asks what to do with an existing slot row. The model is the
// primary edit (the agent identifies the slot); "Change agent" is only offered
// when allowAgentChange is set (more than one candidate agent exists).
// promptSlotAction asks what to do with an existing inspector slot row.
// Inspectors run on the agent's default model, so the only edits are swapping
// the agent (offered when allowAgentChange is set — more than one candidate
// exists) or removing the slot.
func promptSlotAction(ctx context.Context, slot crewSlot, allowAgentChange bool) (string, error) {
options := []huh.Option[string]{huh.NewOption("Change model", "model")}
options := make([]huh.Option[string], 0, 3)
if allowAgentChange {
options = append(options, huh.NewOption("Change agent", "agent"))
}
15 unmodified lines
}
func slotLabel(s crewSlot) string {
model := strings.TrimSpace(s.model)
if model == "" {
model = "default model"
// Inspectors normally run on the agent's default model; only surface a model
// when one was set explicitly (e.g. via scripted --set-slot).
if model := strings.TrimSpace(s.model); model != "" {
return labelForSimpleAgent(s.agent) + " · " + model
}
return labelForSimpleAgent(s.agent) + " · " + model
return labelForSimpleAgent(s.agent)
}
// promptCrewAgent picks the agent for a slot. Auto-selects when only one