所有頁面
本頁內容

config.json

config.json 是中繼自己的設定檔:它的連接埠、誰可以連到它、存取 token、決定回合何時算是卡住的計時器,以及選用的 tunnel 和預覽通道。oar setup 會建立這個檔案。setup 沒有詢問的項目,都要你手動編輯。

你在網頁介面中設定的大部分內容都不在這個檔案裡。見網頁介面與環境中的設定。

檔案在哪裡 #

安裝方式 路徑
macOS、Linux 和 WSL 上的全域安裝 ~/.oar/config.json
Windows 上的全域安裝 %APPDATA%\oar\config.json
設定了 OAR_STATE_ROOT 的全域安裝 該資料夾中的 config.json
Git 檢出 檢出目錄中的 server/config.json

OAR_STATE_ROOT 會搬移全域安裝的整個狀態資料夾(設定檔、資料和記錄);見 OAR 把檔案放在哪裡。

COPILOT_WEB_RELAY_CONFIG 可以讓中繼使用某一個檔案,不論它放在哪裡,但只適用於不透過 oar 自己的啟動器來啟動中繼的情況:node server/server.js,或 oar copilot(檔案存在時)。oar setup、oar start、oar restart 和服務一律使用該安裝自己的 config.json,不管這個變數怎麼寫。在沒有 server/config.json 的檢出目錄中,oar copilot 會改在 ~/.config/copilot-remote(Windows 上是 %LOCALAPPDATA%\copilot-remote)建立它的檔案。見環境變數。

中繼會讓這個檔案只有擁有者能讀取(macOS 和 Linux 上的模式為 0600),因為檔案中以明文存放存取 token。請像對待密碼一樣對待它的副本。

由誰寫入 #

  • oar setup 會寫入 token、localhostOnly 和 port,其他每個 key 都維持原樣。它建立的檔案,或缺少這些 key 的檔案,還會加上 pollIntervalMs、processingTimeoutMs(600000)和 conversationSessionMode。見 oar setup 和首次執行。
  • 中繼在你從 Settings(設定)安裝或更新供應商 CLI 時會寫入 cliBinaries。它只會改動這個 key。如果它無法把檔案讀成 JSON,就會拒絕寫入,只在執行中的處理程序內保留這個綁定。
  • 中繼在啟動時若找不到檔案,會建立一個,內容為空的 authToken、連接埠 3333、localhostOnly: true、pollIntervalMs 和 conversationSessionMode。它也會移除舊版本留下的 features key(見已淘汰、被忽略與內部使用的 key)。
  • 你,用任何文字編輯器。

手動編輯 #

這個檔案是一個 JSON 物件。你省略的 key 會採用預設值,而像 previews 這樣的巢狀區塊會整個一起讀取。編輯後請重新啟動中繼:中繼只在啟動時讀取一次這個檔案。你儲存檔案時,執行中的中繼所持有的設定都不會改變。用 oar restart(全域安裝)重新啟動,或在對話的 ⋯ 選單中用 🌄 Restart web relay(重新啟動網頁中繼)。

  • 不認得的 key 會被忽略並保留。setup 和中繼自己的寫入都會把它留在原處。
  • 無效的 JSON 不會讓中繼停止。中繼會記錄 Failed to read config.json, using defaults.,並以預設值執行:連接埠 3333、僅限本機,以及每次啟動都會重新產生並印在記錄中的隨機 token。在你修好檔案之前,你儲存的 token 都無法使用。第二個讀取者——選擇資料目錄的那一個——會退回預設資料夾。中繼不會動到損壞的檔案。
  • 錯誤的值會逐個 key 處理。下方的預設值,就是計時器或上限缺少或無法使用時中繼採用的值。tunnel 和預覽通道會保持關閉並記錄原因;中繼本身會繼續執行。
  • 命令列優先於檔案,僅限該次執行:node server/server.js 上的 --token <value> 和 --port <number>(oar copilot 也會傳入;oar start 不會)會覆寫 authToken 和 port,而且絕不會存入檔案。不是 1 到 65535 之間數字的 --port 會被忽略並發出警告。

不要對不是有效 JSON 的檔案執行 oar setup

oar setup 會把無法解析的檔案視為不存在。接著它會以新的 token 寫一個新的 config.json 覆蓋舊檔,舊檔中其他每個 key 都會遺失。請先修好 JSON。手動編輯檔案前,先保留一份副本。

網路與存取 #

Key 類型 預設值 作用
authToken 字串 無:每次啟動產生隨機 token 每個瀏覽器、worker 和 API 用戶端登入時使用的 token。如果是空的,中繼每次啟動都會產生一個隨機 token,印在記錄中,且不會儲存。oar setup 會寫入一個固定的 token。
port 數字 3333 HTTP 和 WebSocket 連接埠,1 到 65535 之間的整數。
localhostOnly 布林值 true true 會把中繼綁定到 127.0.0.1,只有本機能連到它。其他任何值,包括 false、null、1 和 "yes",都會綁定到所有介面(0.0.0.0),讓你的區域網路能連到它。只有 true 和文字 "true"(不分大小寫)算是開啟;只有在缺少這個 key 時才套用預設值。它不影響下方的 tunnel。
remotePath 字串 "" 路徑前綴,用於反向 proxy 在子路徑下提供中繼時,例如 /oar。開頭會補上斜線,結尾的斜線會被移除。中繼會從傳入的請求中拿掉這個前綴,並把它放進登入 cookie 的路徑、socket 路徑,以及檔案和分享連結的位址中。
trustProxy Express 的 trust proxy 值 "loopback" 哪些 proxy 可以設定中繼所採信的 X-Forwarded-* 標頭。用戶端位址(速率限制、登入鎖定、分享存取紀錄)以及新分享連結的主機和協定都是透過它讀取,所以直接連線的用戶端無法偽造。預設值適合同一台機器上的 proxy 或 tunnel。當另一台主機上的 proxy 轉送到中繼時,請使用跳數(1)、位址或子網路("10.0.0.0/8"),或它們的清單(反向 proxy)。
allowedOrigins 字串陣列 [] 0.9.11 新增 除了中繼自己的來源之外,即時 Socket.IO 連線另外接受的瀏覽器來源(協定、主機,以及非預設的連接埠,例如 "https://relay.example.com")。proxy 會改寫 Host 標頭時需要設定。見反向 proxy。
publicHostnames 字串陣列 [] 連到中繼本身的主機名稱。預覽通道會拒絕位於其中之一(以及 localhost 和 127.0.0.1)的 previews.publicBaseUrl,這樣被預覽的應用程式永遠不會和中繼共用登入 cookie。
tunnelMarkerHeaders 字串陣列 [] tunnel 邊緣節點加到流量上的額外標頭名稱。帶有 cf-ray 或其中任一標頭的請求無法到達 session worker 路徑(你自己的 agent 的 worker 所使用的 socket,它們只在本機上執行)。cf-ray 一律在清單上。也可以用逗號分隔的字串。環境變數 COPILOT_TUNNEL_MARKER_HEADERS(以逗號分隔)中的名稱會加到這些名稱上;這裡的空清單並不會關閉它們。
pushVapidSubject 字串 mailto:copilot-remote@example.com 中繼在 Web Push 請求中傳給推播服務的聯絡位址(通知)。請設定成你自己的 mailto: 位址。
sharedPresenceMaxPerConversation 數字 200 一個分享對話連結最多計入的即時觀看者數。至少為 1。達到上限時,閒置最久的觀看者會被移除以騰出空間。
sharedPresenceMaxGlobal 數字 5000 總共最多計入的即時分享連結觀看者數,規則相同。絕不會低於每個對話的上限。

關於第一次連線、token 和區域網路存取,見首次執行。

回合與計時器 #

Key 類型 預設值 作用
processingTimeoutMs 數字,毫秒 600000 回合可以多久沒有收到 worker 的任何活動跡象,之後中繼就會把它放回佇列。這不是回合長度的上限。0 或更小的值會使用預設值。見回合卡住時。
maxRequeueRetries 數字 5 一則訊息最多可以嘗試幾次,之後就永久失敗。至少為 1。見重新排入佇列。
contextIndicatorMode "default" 或 "bar" "default" 輸入區如何以沿著上緣的一條線顯示上下文的填滿程度。default 是一條全寬的線,顏色隨上下文填滿從綠色變成紅色。bar 是同一條線,從左邊延伸到已使用的上下文比例。其他任何值(不分大小寫)都視為 default。

回合最長時間、背景任務逾時和停滯監看不在這裡:見回合卡住時。

重新啟動與關閉 #

這些 key 決定中繼計畫性重新啟動(🌄 Restart web relay)的行為。見重新啟動與繼續。每個計時器都以毫秒為單位;0 或更小的值,或不是數字的值,會使用預設值。

Key 類型 預設值 作用
restartShutdownTimeoutMs 數字,毫秒 45000 重新啟動要等待執行中的回合結束多久,之後就以 shutdown-timeout 失敗放棄。
restartGracefulTimeoutMs 數字,毫秒 8000 中繼等待正常停止多久,之後就強制重新啟動。
restartSpawnTimeoutMs 數字,毫秒 18000 一次嘗試等待重新啟動或繼續階段多久,之後就算失敗(spawn-timeout)。
restartRebindTimeoutMs 數字,毫秒 20000 一次嘗試在重新啟動後等待 session 重新綁定多久(rebind-timeout)。
restartReadyCooldownMs 數字,毫秒 1000 重新啟動回報就緒後,佇列會繼續暫停多久。
restartMaxAttempts 數字 3 重新啟動在定案前可以嘗試幾次。至少為 1。
restartRetryBackoffMs 數字陣列,毫秒 [1000, 3000, 7000] 第 2、3 次及之後嘗試前的等待時間。嘗試次數多於項目數時,會重複使用最後一個項目。不是正數的項目會被捨棄;結果為空時使用預設值。

記憶體 0.9.19 新增 #

Key 類型 預設值 作用
heapLimitMb 數字,MB RAM 的 60%,2,048 到 8,192 中繼的堆積上限,為至少 512 的整數。啟動中繼的每種方式都會讀取它:oar start、systemd 服務、Windows 自動啟動和 CLI 擴充功能。從下次啟動起生效。不是整數或小於 512 的值會被忽略,並在記錄中留下一行;超過機器 RAM 或容器記憶體限制的值會被降到該大小。NODE_OPTIONS 中的 --max-old-space-size,或啟動 server.js 的 node 指令列上的該參數,優先於它。見中繼記憶體耗盡。

Workspace 與資料 #

Key 類型 預設值 作用
workspaceRootAllowList 字串陣列 未設定 對話可以在其中開始的絕對資料夾,以及其中的所有內容。未設定或為空時,允許任何現有的資料夾。不是現有資料夾的項目會被記錄並排除。設定了環境變數 COPILOT_WORKSPACE_ROOT_ALLOW_LIST 時,以它為準。見限制對話可以在哪裡開始。
dataDir 字串 伺服器旁的 data/ 資料庫和中繼鎖定檔所在的位置,以及 0.9.17 新增 deepseek-claude,即 DeepSeek 對話的 Claude Code 狀態。相對路徑從存放 config.json 的資料夾算起。上傳的檔案會跟著它放進其中的 uploads/;只有使用伺服器旁預設 data/、且沒有 COPILOT_WEB_RELAY_DATA_DIR 的中繼,才會把它們放在伺服器旁的 uploads/。設定了 COPILOT_WEB_RELAY_DATA_DIR 時,以它為準。oar start、oar restart 和 Linux systemd 服務一律會設定它(設為 ~/.oar/data、%APPDATA%\oar\data 或你自己的值),所以對以這些方式啟動的中繼,這個 key 沒有作用。它是給直接啟動的檢出目錄用的。Windows 開機啟動器只固定設定檔,不固定這個變數。

供應商 CLI #

Key 類型 預設值 作用
cliBinaries 物件 由中繼寫入 各供應商 CLI 的路徑,依供應商區分:claude 和 grok。從 Settings 安裝並解析出路徑時,中繼會寫入它,並在下次啟動時使用,以便再次找到同一個程式。你也可以手動設定路徑。不是可執行檔的項目會被記錄並忽略。其他名稱,包括 copilot,都不會使用。
sdkPath 字串 自動偵測 Copilot SDK 的 index.js 路徑。只有 sdkPath 和 cliPath 都設定時,才會略過搜尋已安裝的 Copilot CLI。單獨設定時,它也會告訴中繼去它旁邊尋找擴充功能引擎的啟動檔。
cliPath 字串 自動偵測 Copilot CLI 的 runtime 進入點(app.js)路徑。與 sdkPath 搭配使用。中繼也會把它交給自己啟動的 Copilot worker 當作 CLI 程式,除非環境中已經指定了一個。
sdkVersion 字串 找到的最新版本 精確的版本,例如 1.0.63。搜尋已安裝的 Copilot CLI 時就只接受該版本。sdkPath 和 cliPath 都設定時會被忽略。

這些 key 在中繼自己和已安裝的 Copilot CLI 溝通時才有作用,例如匯入現有的 Copilot session 和列出模型。搜尋會查看 Copilot CLI 的套件快取(COPILOT_PKG_DIR 會加入一個優先搜尋的資料夾)。見 GitHub Copilot。

預覽 #

previews 區塊會啟用預覽通道:使用自己的連接埠和主機名稱的第二個監聽器,用來發布本機的 dev server 和資料夾。設定、主機名稱和前端 proxy 寫在 preview 工具的頁面上。

Key 類型 預設值 作用
previews.enabled 布林值 false 啟用通道。只有 true 算數。
previews.port 數字 中繼的 port + 1 預覽監聽器的連接埠。至少為 1024,且不能是中繼的連接埠;0 會在每次啟動時挑一個空閒的連接埠。
previews.bindHost 字串 127.0.0.1 監聽器綁定的位址。不是迴路位址的位址需要 previews.allowPublicBind。
previews.allowPublicBind 布林值 false 允許不是迴路位址的 previews.bindHost。這時每個預覽都能不經前端 proxy 從網路上連到。
previews.publicBaseUrl 字串 無 通道的公開 http(s) 位址。預覽開啟時為必填。它的主機名稱必須與中繼的不同(見 publicHostnames)。結尾的斜線會被移除。
previews.allowedTargetHosts 字串陣列 [] 除了本機之外,連接埠預覽可以指向的主機,例如容器或 VM 的位址。
previews.maxLive 數字 8 整個中繼同時最多的預覽數。不是正整數的值會使用 8。

預覽開啟時,如果其中一條規則不成立,中繼會記錄 PREVIEW LANE disabled 和原因,讓通道保持關閉,並繼續執行。

下列環境變數會覆寫對應的 key:COPILOT_PREVIEWS_ENABLED(1、true、0、false)、COPILOT_PREVIEWS_PORT、COPILOT_PREVIEWS_BIND_HOST、COPILOT_PREVIEWS_PUBLIC_BASE_URL 和 COPILOT_PREVIEWS_ALLOWED_TARGET_HOSTS(以逗號分隔)。

Tunnel #

有兩種 tunnel 可以從你的網路外部連到中繼。它們彼此獨立,可以同時執行。兩者預設都是關閉的,而缺少必要值的受管理 tunnel 會保持關閉並記錄原因。

sshTunnel #

連到你自己伺服器的反向 SSH tunnel。見 SSH tunnel。

Key 類型 預設值 作用
sshTunnel.mode "disabled" 或 "managed" "disabled" managed 會讓中繼執行並重新啟動 tunnel。
sshTunnel.required 布林值 false 受管理的 tunnel 未連線時,包括第一次連線之前和缺少必要值時,中繼會暫停從佇列中取出訊息。
sshTunnel.user 字串 無 伺服器上的 SSH 使用者。受管理時為必填。
sshTunnel.host 字串 無 伺服器的主機名稱或位址。受管理時為必填。
sshTunnel.remotePort 數字 無 在伺服器上開啟的連接埠(1 到 65535)。受管理時為必填。
sshTunnel.remoteBind "loopback" 或 "public" "loopback" 遠端連接埠是只在伺服器本身開放,還是在它的所有介面上開放。與 localhostOnly 無關。
sshTunnel.command 字串 ssh SSH 程式。請使用 PATH 上的名稱或絕對路徑:相對路徑會從中繼的程式資料夾算起。
sshTunnel.identityFile 字串 無 要使用的私密金鑰;~ 會被展開。沒有設定時,SSH 會使用它的 agent 或預設金鑰。
sshTunnel.autoReclaimPort 布林值 true 遠端連接埠已被占用時,在伺服器上執行清理後再試一次。只有 false 會關閉它。
sshTunnel.reclaimStaleSshSessions 布林值 false 作為清理的一部分,也結束你自己在伺服器上沒有執行任何東西的 SSH session。
sshTunnel.remoteCleanupCommand 字串 內建 在伺服器上執行、用來取代內建清理指令的自訂清理指令。

cloudflaredTunnel #

執行 Cloudflare 的 cloudflared,需要你自己安裝;OAR 不附帶。見 Cloudflare Tunnel。

Key 類型 預設值 作用
cloudflaredTunnel.mode "disabled" 或 "managed" "disabled" managed 會讓中繼執行 cloudflared。COPILOT_CLOUDFLARED_MODE 會覆寫它。
cloudflaredTunnel.required 布林值 false 受管理的 tunnel 未連線時,包括缺少必要值時,中繼會暫停從佇列中取出訊息。
cloudflaredTunnel.token 字串 無 你自己的 Cloudflare tunnel 的 token。受管理時為必填。COPILOT_CLOUDFLARED_TOKEN 會覆寫它。
cloudflaredTunnel.binary 字串 cloudflared 程式,可以是絕對路徑,或在 PATH 上查找的名稱。COPILOT_CLOUDFLARED_BINARY 會覆寫它。
cloudflaredTunnel.extraArgs 字串陣列 [] 加在 cloudflared tunnel run --token <token> 後面的參數。

網頁介面與環境中的設定 #

網頁介面中的設定不在這個檔案裡。供應商開關和金鑰、模型清單、回合最長時間、背景任務逾時和功能旗標都存放在中繼的資料庫中,位於資料目錄內。這個檔案存放的是中繼在資料庫開啟之前就需要的東西(資料目錄、連接埠、token),以及關於這台機器的資訊(CLI 路徑、tunnel)。介面寫進這個檔案的唯一項目是 cliBinaries。0.9.17 新增 DeepSeek 在這裡也沒有 key:它的 API 金鑰、基礎 URL 和預算都是從 Settings → Providers → DeepSeek(設定 → 供應商 → DeepSeek)存進資料庫。

環境變數。完整清單在環境變數頁面。某個 key 有對應的變數時,變數優先於檔案:COPILOT_WEB_RELAY_DATA_DIR(dataDir)、COPILOT_WORKSPACE_ROOT_ALLOW_LIST、COPILOT_CLOUDFLARED_* 和 COPILOT_PREVIEWS_*(列在各自的章節中)。COPILOT_TUNNEL_MARKER_HEADERS 是例外:它的名稱會加到 tunnelMarkerHeaders 上。--token 和 --port 選項在該次執行中優先於兩者。COPILOT_WEB_RELAY_CONFIG 本身在檔案在哪裡中說明。

範例 #

所有值都是虛構的。請刪除你沒有用到的區塊。

{
  "authToken": "0f3c1a9e-example-token-do-not-copy",
  "port": 3333,
  "localhostOnly": false,
  "remotePath": "",
  "trustProxy": "loopback",
  "allowedOrigins": [],
  "publicHostnames": ["relay.example.com"],
  "tunnelMarkerHeaders": ["x-edge-request-id"],
  "processingTimeoutMs": 600000,
  "maxRequeueRetries": 5,
  "contextIndicatorMode": "bar",
  "workspaceRootAllowList": ["/home/dev/projects", "/srv/sites"],
  "dataDir": "data",
  "cliBinaries": {
    "claude": "/home/dev/.local/bin/claude",
    "grok": "/home/dev/.grok/bin/grok"
  },
  "restartShutdownTimeoutMs": 45000,
  "restartGracefulTimeoutMs": 8000,
  "restartSpawnTimeoutMs": 18000,
  "restartRebindTimeoutMs": 20000,
  "restartReadyCooldownMs": 1000,
  "restartMaxAttempts": 3,
  "restartRetryBackoffMs": [1000, 3000, 7000],
  "previews": {
    "enabled": true,
    "port": 3334,
    "bindHost": "127.0.0.1",
    "allowPublicBind": false,
    "publicBaseUrl": "https://preview.example.com",
    "allowedTargetHosts": [],
    "maxLive": 8
  },
  "sshTunnel": {
    "mode": "managed",
    "required": false,
    "user": "ubuntu",
    "host": "vps.example.com",
    "remotePort": 4444,
    "remoteBind": "loopback",
    "identityFile": "~/.ssh/id_ed25519"
  },
  "cloudflaredTunnel": {
    "mode": "disabled",
    "token": "",
    "binary": "cloudflared",
    "extraArgs": []
  }
}

已淘汰、被忽略與內部使用的 key #

如果你在檔案中看到其中任何一個,可以保留,也可以刪除:

Key 說明
features 已停用。功能旗標現在存放在中繼的資料庫中,見 Settings → Features(設定 → 功能)。啟動時,中繼會把在這裡找到的值複製到資料庫,除非資料庫中已經存有值,然後從檔案中移除這個 key。
sshTunnel.enabled、cloudflaredTunnel.enabled mode 的舊形式。true 表示 managed,而且只有在 mode 既不是 disabled 也不是 managed 時才會讀取。
pollIntervalMs 會寫入新檔案,但中繼不會讀取。它沒有作用。
conversationSessionMode isolated 或 shared。會寫入新檔案。中繼會把這個值存在每筆 session 紀錄上,並在狀態中回報,但 OAR 中沒有任何東西會因這兩個值而有不同行為。對你來說它沒有作用。
cliPort、model 只有一種需要你手動啟動的獨立模式會使用(給開發者的應急途徑;沒有任何 oar 指令會啟動它)。你用 oar start 啟動的中繼會忽略 model。它讀取 cliPort 只為了一件事:預覽通道絕不會挑選那個連接埠。
host 只有連到中繼的程式(session worker 和 Copilot 擴充功能)會讀取,用來組出它們使用的位址;中繼自己的監聽器會忽略它(見 localhostOnly)。請省略它。