背景執行 + Process 工具

OpenClaw 透過 exec 工具執行 shell 指令,並在記憶體中維護長時間運行的任務。process 工具負責管理這些背景工作階段。

exec 工具

主要參數:

  • command(必填)
  • yieldMs(預設 10000):超過此延遲後自動轉為背景執行
  • background(布林):立即背景執行
  • timeout(秒,預設 1800):超時後終止程序
  • elevated(布林):在啟用/允許提權模式時,於主機上執行
  • 需要真正的 TTY?設定 pty: true
  • workdirenv

行為特性:

  • 前景執行時直接回傳輸出結果。
  • 轉為背景執行(不論是明確指定或超時觸發)後,工具會回傳 status: "running" + sessionId,以及尾部的一小段輸出。
  • 輸出內容會保留在記憶體中,直到該工作階段被輪詢或清除。
  • 如果 process 工具被禁用,exec 會以同步方式執行,並忽略 yieldMs/background
  • 產生的 exec 指令會收到 OPENCLAW_SHELL=exec 環境變數,方便 shell/profile 規則做對應判斷。

子程序橋接

在 exec/process 工具之外產生長時間運行的子程序時(例如 CLI 重啟或 gateway 輔助程式),應掛上子程序橋接輔助器,確保終止信號能正確傳遞,並在結束或錯誤時卸載監聽器。這能避免在 systemd 上產生孤立程序,並讓各平台的關閉行為保持一致。

環境變數覆寫:

  • PI_BASH_YIELD_MS:預設 yield 時間(毫秒)
  • PI_BASH_MAX_OUTPUT_CHARS:記憶體中輸出上限(字元數)
  • OPENCLAW_BASH_PENDING_MAX_OUTPUT_CHARS:每個串流的待處理 stdout/stderr 上限(字元數)
  • PI_BASH_JOB_TTL_MS:已完成工作階段的存活時間(毫秒,範圍 1 分鐘至 3 小時)

設定檔(推薦方式):

  • tools.exec.backgroundMs(預設 10000)
  • tools.exec.timeoutSec(預設 1800)
  • tools.exec.cleanupMs(預設 1800000)
  • tools.exec.notifyOnExit(預設 true):背景 exec 結束時排入系統事件並觸發心跳
  • tools.exec.notifyOnExitEmptySuccess(預設 false):設為 true 時,即使背景執行成功但沒有輸出,也會排入完成事件

process 工具

可用操作:

  • list:列出執行中 + 已完成的工作階段
  • poll:取得工作階段的新輸出(同時回報退出狀態)
  • log:讀取彙整輸出(支援 offset + limit
  • write:傳送 stdin(data,可選 eof
  • kill:終止背景工作階段
  • clear:從記憶體移除已完成的工作階段
  • remove:執行中則終止,已完成則清除

注意事項:

  • 只有背景執行的工作階段會被列出並保留在記憶體中。
  • 程序重啟後工作階段會遺失(不寫入磁碟)。
  • 工作階段日誌只有在你執行 process poll/log 且工具結果被記錄時,才會存到對話紀錄中。
  • process 的範圍限定在單一 agent,只看得到該 agent 啟動的工作階段。
  • process list 包含推導出的 name(指令動詞 + 目標),方便快速瀏覽。
  • process log 使用行數為基礎的 offset/limit
  • offsetlimit 都未指定時,會回傳最後 200 行並附帶分頁提示。
  • 當指定了 offset 但省略 limit 時,會從 offset 一路回傳到結尾(不限制 200 行)。

範例

執行長時間任務,稍後再輪詢:

{ "tool": "exec", "command": "sleep 5 && echo done", "yieldMs": 1000 }
{ "tool": "process", "action": "poll", "sessionId": "<id>" }

直接在背景啟動:

{ "tool": "exec", "command": "npm run build", "background": true }

傳送 stdin:

{ "tool": "process", "action": "write", "sessionId": "<id>", "data": "y\n" }