AIObox × AkiMCP
Một cửa sổ được gọi tên ra sao
Handle, chatId và targetId: cách AI trong nhiều cửa sổ gọi nhau qua AkiMCP, vẽ đủ mọi nhánh.
Nhiều AI chạy song song trong nhiều cửa sổ, trên nhiều provider. Muốn chúng phối hợp, mỗi cửa sổ cần một cái tên bền. Tên đó không được đổi khi chat đổi, tab đổi hay Chrome khởi động lại.
Cửa sổ được gọi bằng handle P#·W#. chatId chỉ là chat đang mở trong cửa sổ đó. targetId chỉ là tab Chrome của lần chạy này. AkiMCP là bên duy nhất dịch tên ra tab thật.
1. Các tầng
Người dùng và AI nói bằng handle. AIObox giữ sổ tên, AkiMCP tra sổ rồi chạm vào đúng tab.
- AIObox desktop (Rust core) mở và quản lý Chrome, đặt handle vào tiêu đề trang, ghi sổ tên.
~/.aki/aiobox/cdp/windows.json: sổ tên (profiles → windows → tabs, kèmretired[]). AIObox ghi atomic, AkiMCP đọc.windows.refresh: AkiMCP ghi một dòng id để xin đọc lại; AIObox trả lời trong ≤1 s.handles.json: bộ đếm W, chỉ AIObox đọc ghi.
2. Ba loại id
Mỗi id có một vai. Nhầm vai là gửi nhầm chat. Các id dưới đây là ví dụ giả.
- Handle, tên bền (
P2·W1). Là gì: P = số profile, W = số cửa sổ theo bộ đếm của profile. Sống: không bao giờ cấp lại; giữ qua restart AIObox và qua session restore. Dùng: gọi cửa sổ trong mọi op (window=). - chatId, chat hiện tại (
1a2b3c4d…9f0e). Là gì: chat đang mở. Notion?t=, ChatGPT/Grok/c/, Claude/chat/, Gemini/app/. Sống: đổi khi mở chat mới, đổi workspace hoặc handoff. Dùng:from=(chính mình),expect=(chắc đúng chat). - targetId, tab Chrome (
0D1E2F3A…). Là gì: tab CDP của lần chạy Chrome này. Sống: một lần chạy. Dùng: nội bộ, AkiMCP gửi CDP vào tab này.
Ví dụ: P2·W1 chuyển sang workspace mới để có thêm quota. chatId đổi, handle vẫn là P2·W1, nên mọi cửa sổ khác vẫn gọi đúng.
3. Một cửa sổ biết gì
Không đọc file, không đoán theo tiêu đề: cửa sổ hỏi AkiMCP.
- Chính mình:
op=whoamitrả handle, chatId,workspace({ id, label, status }) vàusage(session,weekly%,readAt). Mọi cửa sổ: cùng các trường đó trongop=state. - Chưa biết:
usagehoặcworkspacelànull,usageWhynói lý do. Không bao giờ suy từ tiêu đề. - Đi đâu:
op=stateworkspaces, theo profileId:label,status,session,weeklycủa từng workspace. - Quota: đọc
usagetrongop=whoami; từ 82% giữ state; tới 87% AIObox tự chuyển chat. - Chat cutoff, kiểu đọc, busy:
op=state. - Lượt automation:
aki__aiobox op=runsliệt kê các lượt automation của AIObox (đọc usage,connect-akimcp) kèm kết quả; lọc theoautomation,since,last.
aki__aiobox op=whoami
quote="20+ ký tự của tin người dùng"
→ you: {
handle: "P2·W1", chatId: "1a2b3c4d…9f0e",
workspace: { id, label: "Team", status: null },
usage: { session: 41, weekly: 63, readAt }
}
4. Một lệnh window=X đi qua những đâu
X có thể là handle, chatId hay targetId. Mỗi bước chỉ có một lối ra đúng; các lối khác dừng lại kèm mã lỗi.
lệnh vàođúng đườngchờ, xếp hàng hoặc reconnectdừng, báo lỗi
Từng bước, kèm lệnh thật
- Tra sổ.
windows.jsontìm X theo handle, chatId hoặc targetId. Tab có tiêu đề mang handle khác:stale_map. - Chưa thấy thì xin refresh. Ghi
windows.refresh, chờanswered/generationmới (≤5 s), tra lại. Không ai giữ X:no_window. - Handle đã nghỉ thì theo người kế. Đi theo
retired[]tới cửa sổ còn mở. Kết quả ghiresolvedFrom. Handle đang sống luôn thắng. Vòng A→B→A:retired_loop. - Kiểm
expect. Cửa sổ phải còn mở đúng chat mong đợi. Khác:wrong_window. - Không gửi cho chính mình.
fromtrùng đích:self_target. - Không đụng nháp. Nháp trong ô soạn của đích không bao giờ bị đụng. Send v2 (
capabilities.send2) xếp hàng tin:queued: truekèmposition. Send v1 từ chối mãdraft; thử lại ngay trong lượt bằngwait=<s>. - Gửi theo kiểu đọc của provider.
live/queued: gửi ngay, kể cả giữa lượt.blocked:wait=rồi gửi; thiếu nó thì đích báobusy. - Đọc lại mới tính là tới.
op=read last=2thấy tin thì mới báo “đã tới”.
aki__aiobox_write op=send
window=P2·W2
from=1a2b3c4d…9f0e
text="[P2·W1 → P2·W2] …"
→ sent, delivered, midAnswer
aki__aiobox op=read
window=P2·W2 last=2
→ thấy tin → “đã tới”
5. Mỗi provider nhận tin một kiểu
Không chặn gửi chung một luật. Bên gửi biết đích đọc tin ra sao.
| Provider | Kiểu đọc | Gửi lúc đang trả lời | AI đích thấy tin |
|---|---|---|---|
| Notion, ChatGPT, Grok | live | Được | Ngay, giữa lượt |
| Claude | queued | Được | Sau khi hết lượt |
| Gemini | blocked | Không | Khi hết busy (bên gửi wait=) |
Riêng Notion: một profile là một tài khoản có nhiều workspace, quota tính theo workspace. Từ 82% giữ state; tới 87% AIObox tự chuyển chat.
Chọn tài khoản và workspace Notion
Chat cutoff ("Resting")
Chat cutoff, trong AIObox hiện là "Resting", là trạng thái bình thường và tạm thời: một tài khoản hoặc workspace nghỉ ngắn, không nhận chat AI mới (hết quota, 2 lượt trả lời liền bị Interrupted, hoặc nhà cung cấp tạm dừng lượt dùng). Nó tự hết lúc until, hoặc khi lượt dùng có lại; trong lúc đó AIObox mở việc chat AI mới trên tài khoản khác. Vào workspace, reconnect AkiMCP, đọc usage và quản trị tài khoản vẫn làm bình thường. op=profiles cho thấy canTakeChat và chatPause.
Báo AIObox điều bạn thấy: aki__aiobox_write op=pause_chat reason=<chat hiện gì>, kèm:
- Trả lời bị Interrupted trên ≥2 cửa sổ cùng tài khoản:
account=<label> profile=<profileId> hours=4. - Hết quota hoặc thông báo tạm dừng trên 1 workspace:
workspace=<label>. Tài khoản cũng nghỉ khi chuyện này lặp trên ≥2 workspace của nó. op=resume_chatkết thúc một mục.
Rồi AIObox chuyển ngay mọi cửa sổ ở đó sang tài khoản khác.
6. Handoff không làm mất tên
Hai kiểu handoff. Cả hai đều kết thúc ở cùng một bất biến: ai gọi tên cũ vẫn tới đúng người đang giữ vai.
Sang cửa sổ khác: P8·W13 → P4·W10
place_like window=P4·W10 like=P8·W13: cửa sổ mới vào đúng chỗ cửa sổ cũ.close_window window=P8·W13 successor=P4·W10: AIObox ghiretired {P8·W13 → P4·W10}. Không cósuccessorthì không ghi gì. Từ chối khi cửa sổ đang trả lời hoặc có nháp; cửa sổ chết (không ô soạn, không đang trả lời) vẫn đóng được.- Ai gọi
P8·W13sẽ tớiP4·W10, kết quả córesolvedFrom.
Cùng cửa sổ: P2·W1, chatId 5e6f7a8b… → 1a2b3c4d…
usagetrongop=whoamitới 82%: giữ state; tới 87% AIObox tự chuyển chat.op=readthấy chat trống thìop=send window=<targetId của mình>không kèmfrom: vai và chatId cũ.- Kế nhiệm xác nhận chatId trong
op=state. Handle giữ nguyên; không có gì để place hay close.
7. Năm luật bất biến
- Gọi nhau bằng handle. chatId không bao giờ là khoá theo dõi.
- Handle đang sống luôn thắng cạnh
retiredcũ; cạnh tạo vòng bị từ chối. - AI chỉ đi qua op của AkiMCP: không script, không CDP thô, không đóng tab bằng devtools.
- AkiMCP chỉ ghi hai thứ vào thư mục của AIObox:
windows.refreshvà các file yêu cầu trongrequests/.flags.jsonchỉ được đọc. - Chưa
op=readthấy tin thì chưa coi là “đã tới”. Nháp của người khác không bao giờ bị đụng.