[Design] Inline phase 重新設計:對稱 condense(入場摘要 + attempt_inline_completion 離場摘要)
關聯 issue #9 (nesting depth / auto-flatten 設計)。本提案基於實際測試觀察(depth-2 task、qwen3.8-27b、workspace ai_test_project_4),重新定義 inline 模式的語義與 context 行為。
1. 現狀與問題
目前 inlineSubtask(auto-flatten,depth limit 觸發)只做四件事:
#
位置
作用
1
NewTaskTool.ts:126
flatten 時設 marker {message, todos}
2
NewTaskTool.ts:111
phase 中再呼叫 new_task → reject-nested(紅 banner)
3
AttemptCompletionTool.ts:85-89
phase 中 attempt_completion → 只清 marker、task 繼續
4
Task.ts:2332
abort 時清 marker
沒有 :獨立 Task instance、獨立 context/history、獨立 todo list、completion routing。本質是一個 phase flag + prompt directive ,不是 subtask。
實際測試觀察到的問題
沒有 clean context :inline「子任務」在同一對話流裡執行,看得到父對話全部 raw history(system prompt、environment_details、之前所有 tool results)。對 auto-workflow 而言,handoff 沒有隔離、沒有摘要。
raw messages 永久累積 :phase 期間的 list_files/update_todo_list 等雜訊留在對話裡,長 run 不斷膨脹(condense 只按 token threshold 觸發,不按邏輯邊界)。
無持久提示 → 重試迴圈風險 :environment_details 的 Task Context block 只有 Nesting depth / Parent task,不告知模型 phase 進行中 。唯一防線是反應式的 reject tool_result;弱模型可能 new_task → reject → new_task → reject 循環,每次多一個 API round-trip + 紅 banner。
UX 誤導 :紅色「巢狀子任務被拒絕」banner 是用來給 LLM 看的 guard,卻以錯誤樣式呈現給用戶;用戶看不到任何 tab 變化,只看到一個莫名其妙的紅字。
attempt_completion 語義過載 :phase 中 = 「結束階段、task 繼續」,phase 外 = 「完成 task」。同一個 key 兩個意圖,模型容易誤用(以為收尾其實只是繼續)。
命名不誠實 :叫「inline subtask」但沒有任何 subtask 機制。
2. 提案:對稱 condense 的 inline phase
核心思想:入場和離場各做一次摘要,summary 當狀態通道 ——handoff contract 跟真實子任務同構(init prompt + 乾淨起點),物理承載仍是同一條對話流。
2.1 入場(現行 auto-flatten 觸發點,depth limit)
new_task → childDepth > maxNestingDepth → flatten
├─ guard: phase 未進行中(現有 marker check)
├─ ① CONDENSE:summarizeConversation() 把「至今全部」折成 summary S0
│ → 舊訊息 tag condenseParent、建立 summary message
│ → effective context = system + S0 + staged init prompt
│ (= inline phase 跟真實子任務一樣,從乾淨的摘要+初始化提示開始)
├─ marker: task.inlinePhase = { prompt, todos }
├─ banner(黃色 info):「內聯階段開始(上下文已摘要)」+ staged prompt 可見
└─ tool_result:[inline phase] context condensed. Staged instructions: <prompt>.
2.2 離場:新工具 attempt_inline_completion({ result })
獨立成工具,不重用 attempt_completion key:
情境
attempt_completion
attempt_inline_completion
phase 中
❌ 嚴格報錯:「內聯階段進行中,請改用 attempt_inline_completion」
✅ 結束階段、摘要、task 繼續
phase 外
✅ 正常完成 task(含委派路由)
❌ 報錯:「目前沒有進行中的內聯階段」
attempt_inline_completion({ result })
├─ guard: phase 必須進行中
├─ ② CONDENSE:summarizeConversation() —— 語義天然吻合:它摘要「自上次 summary 以來的訊息」,
│ 恰好 = 本階段產生的全部工作(含 result),零新機制
│ → effective context = system + S0 + S1(S1 含 result)
├─ 清 marker
├─ banner(綠色 ✓):「內聯階段完成」+ summary snippet
└─ tool_result:[inline phase completed] <summary>。父對話繼續。
2.3 為什麼幾乎免費(對接現有 condense 機制)
summarizeConversation(src/core/condense/index.ts)本來就是「摘要自上次 summary 以來的訊息」——入場做一次、離場再做一次,第二次恰好只覆蓋 phase 期間的工作。
nested-condense 已驗證可疊加 (nested-condense.spec.ts):多次 phase = 多層 summary;rewind/delete 的 condenseParent 清理邏輯全部現成。
raw messages 不刪除,只 tag + 過濾——rewind 可還原。「clean」是視角上的乾淨,不是銷毀。
3. Context view(模型在每個時刻看到什麼)
根任務工作 R...(raw messages 累積中)
│
├─[inline #1 入場] condense(R) → S0
│ 模型看到: system + S0 + P1(staged prompt) ← 乾淨起點,跟子任務同構
│ phase 1 工作 M1...(raw,即時可見)
├─[inline #1 離場 attempt_inline_completion] condense(M1) → S1
│ 模型看到: system + S0 + S1 ← M1 的 raw 全部隱藏
│
├─[inline #2 入場] S1 之後沒有新訊息 → 跳過 condense(no-op guard),只 stage P2
│ 模型看到: system + S0 + S1 + P2 ← 記得 #1 的「結果」(S1),不記得過程(raw)
│ phase 2 工作 M2...
├─[inline #2 離場] condense(M2) → S2
│ 模型看到: system + S0 + S1 + S2
語義總結:inline = 一條共享對話流 + 每個 phase 一個 summary 封裝。 main task context 永遠在(以 S0 形式);每個 inline 離場後變成自己的 Si。執行期間沒有物理隔離(那是 inline 的本質),但起點是乾淨的。
邊界情況
入場 condense no-op guard :連續兩個 phase、中間無新訊息時,summarizeConversation 回 condensed_recently——入場邏輯要當成「跳過、只 stage」而非錯誤。
summary 可再折疊 :phase 很多時 S0+S1+... 本身可被下一次 condense 折成 meta-summary(多層疊加已驗證),context 永遠有界,不隨 phase 數線性膨脹。
abort/resume :marker 非持久化(issue [ENHANCEMENT] Task Tree 統一子任務管理:詳細設計同 PR 拆分計劃(upstream #856) #9 決定);resume 後 summary 仍在、task 從 condensed context 繼續。需明確寫入設計文件。
phase 中 new_task :維持現行 reject-nested guard,但 banner 降級為安靜 info(見 §4)。
4. 順帶修復的 UX / 模型行為問題
重試迴圈 :phase 進行中時,environment_details Task Context block 追加:
Inline phase in progress: <prompt>
Do NOT call new_task or start another phase; finish with attempt_inline_completion.
每個 request 重建 → 模型永遠知道狀態,不再依賴埋在 history 裡的 tool_result。
紅色 banner 降級 :「巢狀子任務被拒絕」改為 info 樣式 + 白話文案(「已達巢狀上限,內聯階段進行中;再建子任務會被忽略」)——這是預期 guard,不是錯誤。
attempt_completion 卸載過載語義 :phase 中嚴格報錯並指向 attempt_inline_completion,一個工具一個意圖。
命名 sweep :inlineSubtask → inlinePhase;banner「內聯階段開始/完成」;zh-TW 字串、settings deep-link 文字一併更新。
5. 對 auto-workflow 的價值
6. 待決定
成本 :每個 phase 兩次 summarization API call。phase 是低頻事件(depth limit 才觸發),傾向直接做;若要省可加 condense: true 參數讓淺層跳過。
入場是否也要顯式工具 (如 start_inline_phase):建議本期只做 auto-flatten 觸發 + condense 語義,顯式工具留後續 PR——一次改一個面。
abort/resume 的 marker 行為 寫入 issue [ENHANCEMENT] Task Tree 統一子任務管理:詳細設計同 PR 拆分計劃(upstream #856) #9 設計文件。
7. PR 拆分建議
PR
內容
PR-1
入場 condense + marker payload 擴充({prompt, todos} → 加 entryCondenseId)+ banner 文案更新
PR-2
attempt_inline_completion 工具(離場 condense + guard + banner);phase 中 attempt_completion 改嚴格報錯
PR-3
命名/i18n sweep(inlineSubtask → inlinePhase、zh-TW、settings deep-link)+ environment_details「phase 進行中」提示 + 紅 banner 降級 info
每個 PR 獨立可測:PR-1/2 各帶 focused spec(condense mock + marker 狀態機),PR-3 純文案 + environment_details spec。
[Design] Inline phase 重新設計:對稱 condense(入場摘要 +
attempt_inline_completion離場摘要)1. 現狀與問題
目前
inlineSubtask(auto-flatten,depth limit 觸發)只做四件事:NewTaskTool.ts:126{message, todos}NewTaskTool.ts:111new_task→reject-nested(紅 banner)AttemptCompletionTool.ts:85-89attempt_completion→ 只清 marker、task 繼續Task.ts:2332沒有:獨立 Task instance、獨立 context/history、獨立 todo list、completion routing。本質是一個 phase flag + prompt directive,不是 subtask。
實際測試觀察到的問題
list_files/update_todo_list等雜訊留在對話裡,長 run 不斷膨脹(condense 只按 token threshold 觸發,不按邏輯邊界)。environment_details的 Task Context block 只有Nesting depth / Parent task,不告知模型 phase 進行中。唯一防線是反應式的 reject tool_result;弱模型可能new_task → reject → new_task → reject循環,每次多一個 API round-trip + 紅 banner。attempt_completion語義過載:phase 中 = 「結束階段、task 繼續」,phase 外 = 「完成 task」。同一個 key 兩個意圖,模型容易誤用(以為收尾其實只是繼續)。2. 提案:對稱 condense 的 inline phase
核心思想:入場和離場各做一次摘要,summary 當狀態通道——handoff contract 跟真實子任務同構(init prompt + 乾淨起點),物理承載仍是同一條對話流。
2.1 入場(現行 auto-flatten 觸發點,depth limit)
2.2 離場:新工具
attempt_inline_completion({ result })獨立成工具,不重用
attempt_completionkey:attempt_completionattempt_inline_completion2.3 為什麼幾乎免費(對接現有 condense 機制)
summarizeConversation(src/core/condense/index.ts)本來就是「摘要自上次 summary 以來的訊息」——入場做一次、離場再做一次,第二次恰好只覆蓋 phase 期間的工作。nested-condense.spec.ts):多次 phase = 多層 summary;rewind/delete 的condenseParent清理邏輯全部現成。3. Context view(模型在每個時刻看到什麼)
語義總結:inline = 一條共享對話流 + 每個 phase 一個 summary 封裝。 main task context 永遠在(以 S0 形式);每個 inline 離場後變成自己的 Si。執行期間沒有物理隔離(那是 inline 的本質),但起點是乾淨的。
邊界情況
summarizeConversation回condensed_recently——入場邏輯要當成「跳過、只 stage」而非錯誤。new_task:維持現行reject-nestedguard,但 banner 降級為安靜 info(見 §4)。4. 順帶修復的 UX / 模型行為問題
environment_detailsTask Context block 追加:attempt_completion卸載過載語義:phase 中嚴格報錯並指向attempt_inline_completion,一個工具一個意圖。inlineSubtask→inlinePhase;banner「內聯階段開始/完成」;zh-TW 字串、settings deep-link 文字一併更新。5. 對 auto-workflow 的價值
6. 待決定
condense: true參數讓淺層跳過。start_inline_phase):建議本期只做 auto-flatten 觸發 + condense 語義,顯式工具留後續 PR——一次改一個面。7. PR 拆分建議
{prompt, todos}→ 加entryCondenseId)+ banner 文案更新attempt_inline_completion工具(離場 condense + guard + banner);phase 中attempt_completion改嚴格報錯inlineSubtask→inlinePhase、zh-TW、settings deep-link)+ environment_details「phase 進行中」提示 + 紅 banner 降級 info每個 PR 獨立可測:PR-1/2 各帶 focused spec(condense mock + marker 狀態機),PR-3 純文案 + environment_details spec。