# 工作階段與分頁 (https://oh-my-webbridge.github.io/zh-mo/sessions/)

> **技術預覽**
>
> omw 目前是技術預覽版，正在快速迭代。**之後的版本一定會有破壞相容性的變更。**

{/* Generated from sessions.zh-tw.mdx by scripts/i18n.mjs. Edit the zh-TW page instead. */}

工作階段是 oh-my-webbridge 的工作單位。每個指令都會指定一個工作階段，daemon 再把指令送往該工作階段持有的分頁。工作階段開啓的分頁會放進一個分頁羣組，羣組標題為工作階段名稱，或 Agent 傳入的標題。因此任務的頁面會聚在一起，並與你自己使用的頁面分開。

<Demo
  name="activity-read"
  alt="工作階段示範在它開啓的分頁中閲讀文章：頁面一節一節捲動，角落的標籤顯示工作階段名稱。"
/>

## 每項任務一個工作階段 [#one-session-per-task]

為每項任務取一個專屬的工作階段名稱，並在該任務的所有操作中沿用。同時執行的任務使用不同的名稱。每個工作階段各自保有自己的分頁、分頁羣組、目前分頁、預設集與框架選擇。瀏覽器會同時執行來自不同工作階段的指令。

```sh
omw call research navigate '{"url":"https://example.com/docs","group_title":"Research"}'
omw call billing navigate '{"url":"https://example.com/pricing","group_title":"Billing"}'
```

工作階段從它的第一個指令開始。名稱長度為 1 到 96 個字元，可用字母（含 CJK）、數字、`_`、`.` 或 `-`。

## 工作階段固定在同一個瀏覽器 [#a-session-stays-in-one-browser]

工作階段的第一個指令決定它所在的瀏覽器：由 `browser` 指定的瀏覽器、唯一已連線的瀏覽器，或兩個瀏覽器都已連線時的 Chrome。該工作階段之後的指令都送往同一處，即使另一個瀏覽器之後才連線也一樣。`close_session` 會移除這個綁定。要求使用另一個瀏覽器的指令會以 `session_browser` 失敗。

## 指令依抵達順序執行 [#commands-run-in-arrival-order]

每個工作階段有一個佇列。同一工作階段的指令一次執行一個，順序與 daemon 收到的順序相同，所以接在快照之後的點擊，會作用在該快照所描述的頁面上。工作階段之間不共用佇列，某個工作階段中回應緩慢的頁面不會拖住其他工作階段。

`dialog` 與 `close_session` 在工作階段佇列之外回應，因此即使分頁的指令仍在等待，它們也能送達該分頁。一個工作階段最多可同時有 32 個指令在執行或等待。

## 新分頁在背景開啓 [#new-tabs-open-in-the-background]

工作階段沒有目前分頁，或指令設定了 `newTab` 時，`navigate` 會開啓新分頁。分頁在背景開啓，並加入該工作階段的分頁羣組：

```json
{
  "session": "research",
  "action": "navigate",
  "args": { "url": "https://example.com/docs", "newTab": true, "group_title": "Research" }
}
```

- `group_title` 設定羣組的標題。開啓分頁的導覽可以變更標題；否則維持目前的標題。預設為工作階段名稱。
- 羣組建立時是摺疊的，所以任務分頁不會讓分頁列變寬。展開羣組即可查看頁面。
- 之後不帶 `newTab` 的 `navigate` 會重用目前分頁。一個工作階段最多持有 32 個分頁，任務分頁與借用的分頁合計。
- `list_tabs` 只回傳該工作階段的分頁，內容包括 URL、標題、作用中旗標、羣組標題，以及該分頁是否為借用。

## 借用你的分頁 [#borrowing-one-of-your-tabs]

帶有 `active: true` 的 `find_tab` 會認領最後取得焦點的視窗中的作用中分頁。URL 必須完全相符，或主機名稱相符：

```sh
omw call research find_tab '{"url":"example.com","active":true}'
```

不帶 `active: true` 時，`find_tab` 只在工作階段已持有的分頁中尋找。借用的分頁會保持開啓，`close_tab` 會以 `borrowed_tab` 拒絕關閉它。工作階段使用該分頁，並在結束時釋放它。一個分頁同一時間只屬於一個工作階段，其他工作階段要求該分頁時會收到 `tab_busy`。預設集只套用在工作階段自己開啓的分頁。任務需要你已開啓的頁面時才借用分頁；否則請開啓任務分頁。

## 結束工作階段 [#ending-a-session]

`close_session` 會取消工作階段仍在執行或等待的指令，關閉工作階段開啓的分頁，並釋放借用的分頁，這些分頁會保持開啓。它會移除工作階段的瀏覽器綁定，並清除工作階段在借用分頁上記錄的內容：框架選擇、網路項目、主控台輸出與 `@e` 參照。你自己關閉分頁時，該分頁會從工作階段中移除；工作階段只會由 `close_session` 結束。工作階段的目前分頁以 `close_tab` 以外的方式關閉時，工作階段就沒有目前分頁：沒有 `tabId` 的頁面動作會以 `no_tab` 失敗，指定已關閉分頁的指令會以 `tab_missing` 失敗。`close_tab` 之後，工作階段改在它最後開啓的分頁繼續，沒有的話則是它最後借用的分頁。

## 限制 [#limits]

| 限制               | 值                                                        |
| ------------------ | --------------------------------------------------------- |
| 工作階段           | 每個瀏覽器 128 個                                         |
| 每個工作階段的分頁 | 32 個，任務分頁與借用的分頁合計                           |
| 同時執行的指令     | 每個瀏覽器 128 個；`close_session` 與 `dialog` 另有 16 個 |
| 每個工作階段的指令 | 32 個執行中或等待中                                       |
| 工作階段名稱       | 1 到 96 個字母（含 CJK）、數字、`_`、`.` 或 `-`           |
| `timeoutMs`        | 1 到 120000，預設 30000                                   |

達到限制時，指令會以 `busy` 與 HTTP 429 失敗，而不是等待。請降低並行數量，或關閉已完成的工作階段。

## 逾時與結果不確定 [#timeouts-and-uncertain-results]

`timeoutMs` 涵蓋整個請求，包括在工作階段佇列中等待的時間。時間用完、`close_session` 取消了指令，或指令執行到一半時瀏覽器中斷連線，呼叫會回傳 `outcome_unknown`，訊息會指出原因。此時動作可能已經送達頁面：點擊可能已經發生，表單可能已經送出。條件未成立的 `wait` 則會在期限前稍早以 `wait_timeout` 失敗，它不會變更頁面。

<Callout type="warn" title="收到 outcome_unknown 後重試">
  重新使用指令之前，請先觀察頁面。`snapshot`、`read_page`、分頁 URL、`get`
  與網路記錄會顯示頁面做了什麼。只有在狀態顯示動作沒有發生時，才再次送出指令；付款、發布或提交，絕不可自動重送。
</Callout>

## 登入狀態來自你的設定檔 [#logins-come-from-your-profile]

任務分頁與借用的分頁都在你的瀏覽器設定檔中執行，使用其中的 cookie、工作階段與登入狀態。工作階段與分頁羣組是用來整理分頁，不是用來區分帳號：每個工作階段看到的登入狀態都相同，為某項任務清除 cookie 或網站儲存空間，等於為整個設定檔清除。下一項任務需要從未登入開始時，請先登出該網站。
