Ask model to plan the task. Returns TaskQueue. Phase 4 (v2.6.4): Planning now uses recursive_infer() so the plan goes through one self-critique + refine cycle, and KB docs are retrieved and injected so the model plans with relevant API/pattern context. Falls back to plain infer
(user_message, project_context='')
| 174 | return merged[:8] |
| 175 | |
| 176 | def plan_tasks(user_message, project_context=''): |
| 177 | """ |
| 178 | Ask model to plan the task. Returns TaskQueue. |
| 179 | |
| 180 | Phase 4 (v2.6.4): Planning now uses recursive_infer() so the plan goes |
| 181 | through one self-critique + refine cycle, and KB docs are retrieved and |
| 182 | injected so the model plans with relevant API/pattern context. |
| 183 | Falls back to plain infer() if anything goes wrong. |
| 184 | """ |
| 185 | plan_prompt = PLAN_PROMPT |
| 186 | if project_context: |
| 187 | plan_prompt += f'\nProject context:\n{project_context}' |
| 188 | # Inject git-repo awareness so model never adds "git init / .gitignore" steps |
| 189 | try: |
| 190 | from core.githelper import is_git_repo |
| 191 | if is_git_repo(): |
| 192 | plan_prompt += ( |
| 193 | '\nIMPORTANT: Already inside an existing git repository. ' |
| 194 | 'Do NOT add git init, .gitignore creation, or initial commit steps.' |
| 195 | ) |
| 196 | except Exception: |
| 197 | pass |
| 198 | |
| 199 | # ── Phase 4: Retrieve KB docs relevant to the planning request ──────────── |
| 200 | # Injected before the task description so the model plans with known patterns. |
| 201 | retrieved_block = "" |
| 202 | try: |
| 203 | from core.retrieval import retrieve |
| 204 | from utils.config import RETRIEVAL_CONFIG |
| 205 | if RETRIEVAL_CONFIG.get("enabled", True): |
| 206 | _retrieved = retrieve(user_message, budget_chars=1200) |
| 207 | if _retrieved: |
| 208 | retrieved_block = _retrieved + "\n\n" |
| 209 | except Exception: |
| 210 | pass # KB unavailable — plan without retrieval |
| 211 | |
| 212 | messages = [ |
| 213 | { |
| 214 | 'role': 'user', |
| 215 | 'content': ( |
| 216 | plan_prompt |
| 217 | + '\n\n' |
| 218 | + retrieved_block |
| 219 | + 'Task: ' + user_message |
| 220 | + '\n\nNumbered steps:' |
| 221 | ), |
| 222 | } |
| 223 | ] |
| 224 | |
| 225 | # ── Phase 4: Use recursive_infer for self-critiquing plan quality ───────── |
| 226 | # task_type="plan" selects CRITIQUE_PLAN so critique checks step count, |
| 227 | # order, redundancy, and completeness rather than code correctness. |
| 228 | # stream=False — planning is an internal call; no tokens shown to user. |
| 229 | # Falls back to plain infer() on any error. |
| 230 | output = "" |
| 231 | try: |
| 232 | from core.recursive import recursive_infer |
| 233 | from utils.config import RECURSIVE_CONFIG |
no test coverage detected