* Decide whether a prompt should trigger plan-mode.
(userMessage)
| 50 | * Decide whether a prompt should trigger plan-mode. |
| 51 | */ |
| 52 | function shouldPlan(userMessage) { |
| 53 | if (process.env.SMALLCODE_PLAN === 'false') return false; |
| 54 | if (process.env.SMALLCODE_PLAN === 'true') return true; |
| 55 | if (typeof userMessage !== 'string' || userMessage.length === 0) return false; |
| 56 | |
| 57 | // Long messages are usually multi-step |
| 58 | if (userMessage.length > 300) return true; |
| 59 | |
| 60 | // Keyword hints — strong indicators of a multi-step task |
| 61 | if (PLAN_HINTS.some(p => p.test(userMessage))) return true; |
| 62 | |
| 63 | // Multiple imperative sentences AND the message is reasonably long. |
| 64 | // Pure 3-sentence prompts like "Fix the bug in X. It uses Y. Use Z." are |
| 65 | // single-step in practice — we require length > 150 chars too. |
| 66 | if (userMessage.length > 150) { |
| 67 | const sentences = userMessage.split(/[.!?]+/).map(s => s.trim()).filter(s => s.length > 10); |
| 68 | if (sentences.length >= 3) return true; |
| 69 | } |
| 70 | |
| 71 | return false; |
| 72 | } |
| 73 | |
| 74 | /** |
| 75 | * Parse a model response that should contain a plan. Returns null if no |