core: allow /model switch while running; detach turnError hook context
- /model command no longer rejects switches while agent is running; needed for turnError hook recovery (freeloader switches model mid-error) - TurnError hook uses context.Background()-derived context so hook can safely issue ctl commands without cancelling its own execution - update TestCommand_Model_WhileRunning to expect success Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d350c9f412
commit
9ce1e63788
|
|
@ -126,10 +126,6 @@ func (s *agent) handleCommand(ctx context.Context, input string, handler EventHa
|
|||
handler(infoEvent(s.cfg.Backend.Model()))
|
||||
return
|
||||
}
|
||||
if s.IsRunning() {
|
||||
handler(infoEvent("error: cannot switch model while agent is running"))
|
||||
return
|
||||
}
|
||||
s.cfg.Backend.SetModel(args[0])
|
||||
handler(infoEvent("switched model to: " + args[0]))
|
||||
},
|
||||
|
|
|
|||
|
|
@ -310,8 +310,12 @@ func NewAgentCore(cfg AgentCoreConfig) Core {
|
|||
a.changeCond = sync.NewCond(&a.changeMu)
|
||||
a.pushSessionEnv()
|
||||
a.pushLockDir()
|
||||
a.cfg.TurnError = func(ctx context.Context, errType, errMsg string) HookResult {
|
||||
return a.hooks.Run(ctx, HookTurnError, map[string]string{
|
||||
a.cfg.TurnError = func(_ context.Context, errType, errMsg string) HookResult {
|
||||
// Use a detached context so the hook can safely write "stop" to ctl
|
||||
// without cancelling its own execution via the action context.
|
||||
hookCtx, cancel := context.WithTimeout(context.Background(), time.Duration(hookTimeout)*time.Second)
|
||||
defer cancel()
|
||||
return a.hooks.Run(hookCtx, HookTurnError, map[string]string{
|
||||
"session_id": a.sessionID,
|
||||
"cwd": a.CWD(),
|
||||
"model": a.cfg.Backend.Model(),
|
||||
|
|
|
|||
|
|
@ -1071,19 +1071,19 @@ func TestCommand_Model_WhileRunning(t *testing.T) {
|
|||
}()
|
||||
waitState(t, c, "thinking")
|
||||
|
||||
// /model is now allowed while running (needed for turnError hook recovery).
|
||||
evs := collectEvents(context.Background(), c, "/model new-model")
|
||||
|
||||
close(unblock)
|
||||
<-done
|
||||
|
||||
found := false
|
||||
for _, s := range byRole(evs, "info") {
|
||||
if strings.Contains(s, "error") {
|
||||
found = true
|
||||
t.Errorf("/model while running: unexpected error: %s", s)
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("/model while running: expected error event, got: %v", byRole(evs, "info"))
|
||||
if got := be.Model(); got != "new-model" {
|
||||
t.Errorf("model = %q; want new-model", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in New Issue