概述
在 SessionOrchestrator 的所有 5 種 Session 類型流程中,於 setSessionModel() 之後加入 setSessionMode() 調用,使 OpenCode 在 YOLO 模式下切換至 yolo Agent。
父議題:#264
依賴:#268(需要 AgentConnector.setSessionMode() 和 getSessionModeOverride() 已實作)
背景
SessionOrchestrator 是所有 Session 類型的入口點。每種 Session 類型都有獨立的方法來建立 Agent 連線、設定模型、發送 prompt。目前的流程為:
const connector = this.createConnector({ agentConfig, ... });
await connector.connect();
const sessionId = await connector.createSession(mcpServers);
await connector.setSessionModel(sessionId, model);
// ← 此處需新增 setSessionMode()
const response = await connector.prompt(sessionId, assembledContext);
需要在 setSessionModel() 之後、prompt() 之前插入 Mode 切換邏輯。
實作步驟
步驟 1:在 5 種 Session 流程中加入 Mode 切換
SessionOrchestrator 有 5 個方法需要修改,每個方法在 setSessionModel() 之後加入:
// Import the new function
import { getSessionModeOverride } from "@acp/agent-factory.ts";
// After setSessionModel(), add mode override:
const modeOverride = getSessionModeOverride(agentType, yolo);
if (modeOverride) {
await connector.setSessionMode(sessionId, modeOverride);
}
以下是 5 個需要修改的方法及其位置(行號為參考,實際可能因程式碼變更而偏移):
1. processMessage()(一般訊息)
// 尋找 connector.setSessionModel() 呼叫處
await connector.setSessionModel(sessionId, model);
// 在其後加入:
const modeOverride = getSessionModeOverride(agentType, yoloDecision.enabled);
if (modeOverride) {
await connector.setSessionMode(sessionId, modeOverride);
}
注意:此方法中的 YOLO 狀態來自 yoloDecision.enabled(逐頻道 YOLO 判定結果)。
2. processSpontaneousPost()(自發性發文)
await connector.setSessionModel(sessionId, model);
const modeOverride = getSessionModeOverride(agentType, this.yolo);
if (modeOverride) {
await connector.setSessionMode(sessionId, modeOverride);
}
注意:自發性發文使用全域 this.yolo,因為沒有特定頻道觸發。
3. processChannelLurkMessage()(頻道潛伏回覆)
await connector.setSessionModel(sessionId, model);
const modeOverride = getSessionModeOverride(agentType, yoloDecision.enabled);
if (modeOverride) {
await connector.setSessionMode(sessionId, modeOverride);
}
注意:此方法有頻道設定,因此使用 yoloDecision.enabled。
4. processSelfResearch()(自我研究)
await connector.setSessionModel(sessionId, model);
const modeOverride = getSessionModeOverride(agentType, this.yolo);
if (modeOverride) {
await connector.setSessionMode(sessionId, modeOverride);
}
注意:自我研究使用全域 this.yolo。
5. processMemoryMaintenance()(記憶維護)
await connector.setSessionModel(sessionId, model);
const modeOverride = getSessionModeOverride(agentType, this.yolo);
if (modeOverride) {
await connector.setSessionMode(sessionId, modeOverride);
}
注意:記憶維護使用全域 this.yolo。
步驟 2:確認 Import 語句
在 src/core/session-orchestrator.ts 的 import 區塊中,確認已 import getSessionModeOverride:
import {
createAgentConfig,
getDefaultAgentType,
getRetryPromptStrategy,
getSessionModeOverride, // ← 新增
} from "@acp/agent-factory.ts";
步驟 3:考量錯誤處理
setSessionMode() 可能在以下情況失敗:
- Agent 不支援 Mode 切換
- 指定的 Mode ID 不存在
建議處理方式:讓錯誤自然向上傳播。如果 Mode 切換失敗,Session 應該失敗(因為在錯誤的權限模式下執行 Agent 可能產生非預期結果)。這與 setSessionModel() 失敗的處理一致。
測試策略
tests/core/session-orchestrator.test.ts
新增以下測試案例(建議使用 sanitizeResources: false, sanitizeOps: false):
Deno.test({
name: "SessionOrchestrator - processMessage - calls setSessionMode for opencode yolo",
sanitizeResources: false,
sanitizeOps: false,
fn: async () => {
// 1. 設定 agentType = "opencode", yolo = true
// 2. Mock connector,驗證 setSessionMode 被呼叫
// 3. 斷言 setSessionMode("yolo") 被呼叫且在 setSessionModel 之後
},
});
Deno.test({
name: "SessionOrchestrator - processMessage - does not call setSessionMode for copilot yolo",
sanitizeResources: false,
sanitizeOps: false,
fn: async () => {
// 1. 設定 agentType = "copilot", yolo = true
// 2. Mock connector,驗證 setSessionMode 未被呼叫
},
});
Deno.test({
name: "SessionOrchestrator - processMessage - does not call setSessionMode for opencode non-yolo",
sanitizeResources: false,
sanitizeOps: false,
fn: async () => {
// 1. 設定 agentType = "opencode", yolo = false
// 2. Mock connector,驗證 setSessionMode 未被呼叫
},
});
// 類似的測試應覆蓋其他 4 種 Session 類型
測試覆蓋重點
| 場景 |
預期行為 |
| OpenCode + YOLO |
呼叫 setSessionMode("yolo") |
| OpenCode + 非 YOLO |
不呼叫 setSessionMode() |
| Copilot + YOLO |
不呼叫 setSessionMode() |
| Gemini + YOLO |
不呼叫 setSessionMode() |
| 5 種 Session 類型各自測試 |
確保無遺漏 |
相關檔案
| 檔案 |
修改類型 |
src/core/session-orchestrator.ts |
在 5 處加入 setSessionMode() 調用 + import |
tests/core/session-orchestrator.test.ts |
新增測試案例 |
注意事項
- 請仔細識別各方法中的 YOLO 狀態來源(
yoloDecision.enabled vs this.yolo),使用錯誤的來源會導致權限邏輯不一致
setSessionMode() 應在 setSessionModel() 之後、prompt() 之前呼叫
- 若未來新增第 6 種 Session 類型,也需要加入相同的 Mode 切換邏輯
概述
在
SessionOrchestrator的所有 5 種 Session 類型流程中,於setSessionModel()之後加入setSessionMode()調用,使 OpenCode 在 YOLO 模式下切換至yoloAgent。父議題:#264
依賴:#268(需要
AgentConnector.setSessionMode()和getSessionModeOverride()已實作)背景
SessionOrchestrator是所有 Session 類型的入口點。每種 Session 類型都有獨立的方法來建立 Agent 連線、設定模型、發送 prompt。目前的流程為:需要在
setSessionModel()之後、prompt()之前插入 Mode 切換邏輯。實作步驟
步驟 1:在 5 種 Session 流程中加入 Mode 切換
SessionOrchestrator有 5 個方法需要修改,每個方法在setSessionModel()之後加入:以下是 5 個需要修改的方法及其位置(行號為參考,實際可能因程式碼變更而偏移):
1.
processMessage()(一般訊息)注意:此方法中的 YOLO 狀態來自
yoloDecision.enabled(逐頻道 YOLO 判定結果)。2.
processSpontaneousPost()(自發性發文)注意:自發性發文使用全域
this.yolo,因為沒有特定頻道觸發。3.
processChannelLurkMessage()(頻道潛伏回覆)注意:此方法有頻道設定,因此使用
yoloDecision.enabled。4.
processSelfResearch()(自我研究)注意:自我研究使用全域
this.yolo。5.
processMemoryMaintenance()(記憶維護)注意:記憶維護使用全域
this.yolo。步驟 2:確認 Import 語句
在
src/core/session-orchestrator.ts的 import 區塊中,確認已 importgetSessionModeOverride:步驟 3:考量錯誤處理
setSessionMode()可能在以下情況失敗:建議處理方式:讓錯誤自然向上傳播。如果 Mode 切換失敗,Session 應該失敗(因為在錯誤的權限模式下執行 Agent 可能產生非預期結果)。這與
setSessionModel()失敗的處理一致。測試策略
tests/core/session-orchestrator.test.ts新增以下測試案例(建議使用
sanitizeResources: false, sanitizeOps: false):測試覆蓋重點
setSessionMode("yolo")setSessionMode()setSessionMode()setSessionMode()相關檔案
src/core/session-orchestrator.tssetSessionMode()調用 + importtests/core/session-orchestrator.test.ts注意事項
yoloDecision.enabledvsthis.yolo),使用錯誤的來源會導致權限邏輯不一致setSessionMode()應在setSessionModel()之後、prompt()之前呼叫