agent: revert auto-nudge — model choice is the right fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
76c5e696d5
commit
078428881c
|
|
@ -12,29 +12,6 @@ import (
|
|||
)
|
||||
|
||||
const maxRateLimitRetries = 3
|
||||
const maxNudges = 2
|
||||
|
||||
// nudgeMsg is injected as a user turn when the model narrates intent without
|
||||
// acting. It is ephemeral — added to the history slice for the next ChatStream
|
||||
// call but never persisted to State, so it won't appear in future sessions.
|
||||
const nudgeMsg = "Continue. Use execute_code now — do not describe what you will do."
|
||||
|
||||
// narrationPhrases are case-insensitive prefixes/substrings that indicate the
|
||||
// model is narrating intent rather than acting.
|
||||
var narrationPhrases = []string{
|
||||
"let me",
|
||||
"i'll ",
|
||||
"i will ",
|
||||
"i'm going to",
|
||||
"i am going to",
|
||||
"i need to",
|
||||
"first, i",
|
||||
"first i'll",
|
||||
"now i'll",
|
||||
"now i will",
|
||||
"to do this",
|
||||
"i'll now",
|
||||
}
|
||||
|
||||
type ToolExecutor func(name string, args json.RawMessage) (string, error)
|
||||
type OutputFn func(msg OutputMsg)
|
||||
|
|
@ -62,19 +39,11 @@ func Run(ctx context.Context, cfg Config, state State) error {
|
|||
maxSteps = 1
|
||||
}
|
||||
|
||||
var pendingNudge string
|
||||
nudgeCount := 0
|
||||
|
||||
for step := range maxSteps {
|
||||
history := state.History()
|
||||
if cfg.SystemPrompt != "" {
|
||||
history = append([]backend.Message{{Role: "system", Content: cfg.SystemPrompt}}, history...)
|
||||
}
|
||||
// Inject nudge from previous step if the model narrated instead of acted.
|
||||
if pendingNudge != "" {
|
||||
history = append(history, backend.Message{Role: "user", Content: pendingNudge})
|
||||
pendingNudge = ""
|
||||
}
|
||||
|
||||
// Stream the assistant's response, retrying on HTTP 429.
|
||||
var ch <-chan backend.StreamEvent
|
||||
|
|
@ -161,14 +130,6 @@ func Run(ctx context.Context, cfg Config, state State) error {
|
|||
}
|
||||
|
||||
if len(toolCalls) == 0 {
|
||||
// If the model narrated intent without acting, nudge it to continue
|
||||
// rather than treating the turn as completion.
|
||||
if nudgeCount < maxNudges && isNarration(content.String()) {
|
||||
nudgeCount++
|
||||
pendingNudge = nudgeMsg
|
||||
emit(cfg, OutputMsg{Role: "nudge", Content: nudgeMsg})
|
||||
continue
|
||||
}
|
||||
if err := state.MarkComplete(); err != nil {
|
||||
return fmt.Errorf("mark complete: %w", err)
|
||||
}
|
||||
|
|
@ -182,23 +143,6 @@ func Run(ctx context.Context, cfg Config, state State) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// isNarration returns true when text looks like the model is describing what it
|
||||
// is about to do rather than doing it. Only short responses are considered —
|
||||
// a longer response likely contains actual content or analysis.
|
||||
func isNarration(text string) bool {
|
||||
text = strings.TrimSpace(text)
|
||||
if text == "" || len(text) > 800 {
|
||||
return false
|
||||
}
|
||||
lower := strings.ToLower(text)
|
||||
for _, phrase := range narrationPhrases {
|
||||
if strings.Contains(lower, phrase) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func emit(cfg Config, msg OutputMsg) {
|
||||
if cfg.Output != nil {
|
||||
cfg.Output(msg)
|
||||
|
|
|
|||
4
main.go
4
main.go
|
|
@ -468,10 +468,6 @@ func (m *model) apply(am agentMsg) {
|
|||
}
|
||||
m.display = append(m.display, "= "+s)
|
||||
|
||||
case "nudge":
|
||||
// Model narrated without acting; loop injected a continuation prompt.
|
||||
m.display = append(m.display, "[nudge: continuing…]")
|
||||
|
||||
case "retry":
|
||||
m.state = agentRetrying
|
||||
if secs, err := strconv.Atoi(am.content); err == nil {
|
||||
|
|
|
|||
Reference in New Issue