Codex App Server
Codex App Server
Codex app-server là giao diện mà Codex sử dụng để vận hành các ứng dụng khách giàu tính năng (ví dụ: tiện ích mở rộng Codex cho VS Code). Hãy sử dụng giao diện này khi bạn muốn tích hợp sâu vào sản phẩm của mình, bao gồm xác thực, lịch sử hội thoại, phê duyệt và các sự kiện tác nhân được truyền trực tiếp. Phần triển khai app-server có mã nguồn mở trong kho lưu trữ Codex trên GitHub (openai/codex/codex-rs/app-server). Xem trang Mã nguồn mở để biết danh sách đầy đủ các thành phần Codex có mã nguồn mở.
Kết nối giao diện đầu cuối của CLI
Chế độ giao diện đầu cuối từ xa cho phép bạn chạy app-server trên một máy và kết nối giao diện đầu cuối Codex CLI từ một máy khác. Khởi động trình lắng nghe WebSocket:
codex app-server --listen ws://127.0.0.1:4500Sau đó, kết nối giao diện đầu cuối:
codex --remote ws://127.0.0.1:4500Đối với kết nối không cục bộ, hãy cấu hình xác thực WebSocket và đặt kết nối phía sau TLS. Lưu bearer token trong một biến môi trường và truyền tên biến thay vì đưa token vào dòng lệnh:
export CODEX_REMOTE_TOKEN="$(cat "$HOME/.codex/app-server-token")"
codex --remote wss://remote-host:4500 \
--remote-auth-token-env CODEX_REMOTE_TOKENTùy chọn --remote chấp nhận các điểm cuối ws://, wss://, unix:// và
unix://PATH. Chỉ sử dụng WebSocket thuần cho localhost hoặc kết nối
được chuyển tiếp cổng qua SSH.
Kết nối máy chủ Code Mode từ xa
Theo mặc định, app-server khởi động một máy chủ Code Mode cục bộ. Để sử dụng máy chủ từ xa thay thế, hãy truyền URL WebSocket bảo mật của máy chủ đó:
codex app-server --code-mode-host wss://code-mode.example.com/host--code-mode-host kiểm soát kết nối đi từ app-server đến máy chủ Code
Mode. Tùy chọn này không thay đổi --listen, vốn kiểm soát cách ứng dụng khách kết nối với
app-server. Mọi luồng trong cùng một tiến trình app-server đều dùng chung kết nối
máy chủ Code Mode đã chọn.
Sử dụng wss:// cho máy chủ từ xa. Chỉ sử dụng ws:// cho localhost hoặc
kết nối được chuyển tiếp qua SSH. Lệnh app-server và phương thức truyền tải WebSocket
đang ở trạng thái thử nghiệm và không được hỗ trợ cho khối lượng công việc production.
Giao thức
Tương tự MCP, codex app-server hỗ trợ giao tiếp hai chiều bằng thông điệp JSON-RPC 2.0 (tiêu đề "jsonrpc":"2.0" được lược bỏ khi truyền trên đường truyền).
Các phương thức truyền tải được hỗ trợ:
stdio(--listen stdio://, mặc định): JSON phân tách bằng dòng mới (JSONL).websocket(--listen ws://IP:PORT, đang thử nghiệm và không được hỗ trợ): mỗi khung văn bản WebSocket chứa một thông điệp JSON-RPC.- Unix socket (
--listen unix://hoặc--listen unix://PATH): các kết nối WebSocket qua socket điều khiển app-server mặc định của Codex hoặc một đường dẫn Unix socket tùy chỉnh, sử dụng quy trình bắt tay HTTP Upgrade tiêu chuẩn. off(--listen off): không công khai phương thức truyền tải cục bộ.
Khi bạn chạy với --listen ws://IP:PORT, cùng trình lắng nghe đó cũng phục vụ các
phép kiểm tra tình trạng HTTP cơ bản:
GET /readyztrả về200 OKsau khi trình lắng nghe chấp nhận kết nối mới.GET /healthztrả về200 OKkhi yêu cầu không chứa tiêu đềOrigin.- Các yêu cầu có tiêu đề
Originbị từ chối với403 Forbidden.
Phương thức truyền tải WebSocket đang ở trạng thái thử nghiệm và không được hỗ trợ. Các trình lắng nghe cục bộ như
ws://127.0.0.1:PORT phù hợp với quy trình làm việc trên localhost và chuyển tiếp cổng qua SSH.
Trong giai đoạn triển khai, các trình lắng nghe WebSocket không thuộc loopback hiện cho phép kết nối
không xác thực theo mặc định, vì vậy hãy cấu hình xác thực WebSocket trước khi
công khai từ xa.
Các cờ xác thực WebSocket được hỗ trợ:
--ws-auth capability-token --ws-token-file /absolute/path--ws-auth capability-token --ws-token-sha256 HEX--ws-auth signed-bearer-token --ws-shared-secret-file /absolute/path
Đối với bearer token đã ký, bạn cũng có thể đặt --ws-issuer, --ws-audience và
--ws-max-clock-skew-seconds. Ứng dụng khách cung cấp thông tin xác thực dưới dạng
Authorization: Bearer <token> trong quá trình bắt tay WebSocket, còn app-server
thực thi xác thực trước initialize JSON-RPC.
Ưu tiên --ws-token-file thay vì truyền bearer token thô trên dòng lệnh. Chỉ sử dụng
--ws-token-sha256 khi ứng dụng khách lưu token thô có entropy cao trong một
kho bí mật cục bộ riêng biệt; giá trị băm chỉ là dữ liệu xác minh và ứng dụng khách vẫn cần
token gốc.
Trong chế độ WebSocket, app-server sử dụng các hàng đợi có giới hạn. Khi luồng yêu cầu đầu vào đã đầy,
máy chủ từ chối yêu cầu mới với mã lỗi JSON-RPC -32001 và thông báo
"Server overloaded; retry later." Ứng dụng khách nên thử lại với độ trễ
tăng theo cấp số nhân và có thêm độ lệch ngẫu nhiên.
Lược đồ thông điệp
Yêu cầu bao gồm method, params và id:
{ "method": "thread/start", "id": 10, "params": { "model": "gpt-5.6-terra" } }Phản hồi lặp lại id cùng với result hoặc error:
{ "id": 10, "result": { "thread": { "id": "thr_123" } } }{ "id": 10, "error": { "code": 123, "message": "Something went wrong" } }Thông báo lược bỏ id và chỉ sử dụng method cùng params:
{ "method": "turn/started", "params": { "turn": { "id": "turn_456" } } }Bạn có thể tạo lược đồ TypeScript hoặc một gói JSON Schema từ CLI. Mỗi đầu ra dành riêng cho phiên bản Codex mà bạn đã chạy, vì vậy các thành phần được tạo sẽ khớp chính xác với phiên bản đó:
codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemasBắt đầu
- Khởi động máy chủ bằng
codex app-server(phương thức truyền tải stdio mặc định),codex app-server --listen ws://127.0.0.1:4500(TCP WebSocket) hoặccodex app-server --listen unix://(Unix socket mặc định). - Kết nối ứng dụng khách qua phương thức truyền tải đã chọn, sau đó gửi
initializerồi đến thông báoinitialized. - Bắt đầu một luồng và một lượt, sau đó tiếp tục đọc thông báo từ luồng dữ liệu truyền tải đang hoạt động.
Ví dụ (Node.js / TypeScript):
const proc = spawn("codex", ["app-server"], {
stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });
const send = (message: unknown) => {
proc.stdin.write(`${JSON.stringify(message)}\n`);
};
let threadId: string | null = null;
rl.on("line", (line) => {
const msg = JSON.parse(line) as any;
console.log("server:", msg);
if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
threadId = msg.result.thread.id;
send({
method: "turn/start",
id: 2,
params: {
threadId,
input: [{ type: "text", text: "Summarize this repo." }],
},
});
}
});
send({
method: "initialize",
id: 0,
params: {
clientInfo: {
name: "my_product",
title: "My Product",
version: "0.1.0",
},
},
});
send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: { model: "gpt-5.6-terra" } });Các thành phần cốt lõi
- Luồng: Cuộc hội thoại giữa người dùng và tác nhân Codex. Luồng chứa các lượt.
- Lượt: Một yêu cầu của người dùng và phần công việc tiếp theo của tác nhân. Lượt chứa các mục và truyền trực tiếp các bản cập nhật tăng dần.
- Mục: Một đơn vị đầu vào hoặc đầu ra (thông điệp của người dùng, thông điệp của tác nhân, lần chạy lệnh, thay đổi tệp, lệnh gọi công cụ và nhiều nội dung khác).
Sử dụng API luồng để tạo, liệt kê hoặc lưu trữ hội thoại. Điều khiển hội thoại bằng API lượt và truyền trực tiếp tiến độ qua thông báo lượt.
Tổng quan về vòng đời
- Khởi tạo một lần cho mỗi kết nối: Ngay sau khi mở kết nối truyền tải, hãy gửi yêu cầu
initializekèm siêu dữ liệu ứng dụng khách, rồi phátinitialized. Máy chủ từ chối mọi yêu cầu trên kết nối đó trước khi hoàn tất quy trình bắt tay này. - Bắt đầu (hoặc tiếp tục) một luồng: Gọi
thread/startcho hội thoại mới,thread/resumeđể tiếp tục hội thoại hiện có hoặcthread/forkđể phân nhánh lịch sử thành một mã luồng mới. - Bắt đầu một lượt: Gọi
turn/startvớithreadIdđích và đầu vào của người dùng. Các trường tùy chọn ghi đè mô hình, personality,cwd, chính sách môi trường cô lập và những thiết lập khác. - Điều hướng một lượt đang hoạt động: Gọi
turn/steerđể nối thêm đầu vào của người dùng vào lượt hiện đang xử lý mà không tạo lượt mới. - Truyền trực tiếp sự kiện: Sau
turn/start, tiếp tục đọc thông báo trên stdout:thread/archived,thread/unarchived,item/started,item/completed,item/agentMessage/delta, tiến độ công cụ và các bản cập nhật khác. - Kết thúc lượt: Máy chủ phát
turn/completedvới trạng thái cuối cùng khi mô hình hoàn tất hoặc sau khi hủy bằngturn/interrupt.
Khởi tạo
Ứng dụng khách phải gửi duy nhất một yêu cầu initialize cho mỗi kết nối truyền tải trước khi gọi bất kỳ phương thức nào khác trên kết nối đó, sau đó xác nhận bằng thông báo initialized. Các yêu cầu được gửi trước khi khởi tạo sẽ nhận lỗi Not initialized, còn việc gọi lại initialize trên cùng kết nối sẽ trả về Already initialized.
Máy chủ trả về chuỗi tác nhân người dùng mà nó sẽ cung cấp cho các dịch vụ thượng nguồn, cùng các giá trị platformFamily và platformOs mô tả đích thời gian chạy. Đặt clientInfo để nhận diện phần tích hợp của bạn.
initialize.params.capabilities cũng hỗ trợ các khả năng ứng dụng khách sau:
optOutNotificationMethods- tên chính xác của các phương thức thông báo cần chặn trên kết nối này. Việc đối sánh là chính xác (không có ký tự đại diện hoặc tiền tố); các tên không xác định được chấp nhận và bỏ qua.requestAttestation- chọn tham gia yêu cầuattestation/generatedo máy chủ khởi tạo. Các máy chủ desktop cung cấp chứng thực thượng nguồn sẽ phản hồi bằng một giá trị{ "token": "..." }không trong suốt.mcpServerOpenaiFormElicitation- cho phép các máy chủ MCP hạ nguồn gửi biến thể dạng mở rộng của OpenAI chomcpServer/elicitation/request.
Quan trọng: Hãy dùng clientInfo.name để định danh ứng dụng khách của bạn với OpenAI Compliance Logs Platform. Nếu bạn đang phát triển một tích hợp Codex mới dành cho mục đích sử dụng trong doanh nghiệp, vui lòng liên hệ với OpenAI để tích hợp đó được thêm vào danh sách các ứng dụng khách đã biết. Để biết thêm thông tin, hãy xem tài liệu tham khảo về nhật ký Codex.
Ví dụ (từ tiện ích mở rộng Codex cho VS Code):
{
"method": "initialize",
"id": 0,
"params": {
"clientInfo": {
"name": "codex_vscode",
"title": "Codex VS Code Extension",
"version": "0.1.0"
}
}
}Ví dụ với tùy chọn không nhận thông báo:
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true,
"optOutNotificationMethods": ["thread/started", "item/agentMessage/delta"]
}
}
}Chọn tham gia API thử nghiệm
Một số phương thức và trường của app-server được chủ ý kiểm soát bằng khả năng experimentalApi.
- Lược bỏ
capabilities(hoặc đặtexperimentalApithànhfalse) để tiếp tục sử dụng bề mặt API ổn định; máy chủ sẽ từ chối các phương thức/trường thử nghiệm. - Đặt
capabilities.experimentalApithànhtrueđể bật các phương thức và trường thử nghiệm.
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true
}
}
}Nếu ứng dụng khách gửi một phương thức hoặc trường thử nghiệm mà chưa chọn tham gia, app-server sẽ từ chối với:
<descriptor> requires experimentalApi capability
Tổng quan về API
thread/start- tạo một luồng mới; phát rathread/startedvà tự động đăng ký cho bạn nhận các sự kiện lượt/mục của luồng đó.thread/resume- mở lại một luồng hiện có theo id để các lệnh gọiturn/startsau đó nối thêm nội dung vào luồng.thread/fork- phân nhánh một luồng thành một id luồng mới bằng cách sao chép lịch sử đã lưu trữ. TruyềnlastTurnIdđể sao chép lịch sử đến hết lượt đó và bỏ qua các lượt sau, hoặcephemeral: trueđể tạo một nhánh trong bộ nhớ. Phát rathread/startedcho luồng mới; các luồng được trả về bao gồmforkedFromIdkhi có.thread/read- đọc một luồng đã lưu trữ theo id mà không tiếp tục luồng đó; đặtincludeTurnsđể trả về toàn bộ lịch sử lượt. Các đối tượngthreadđược trả về bao gồmstatuscủa thời gian chạy.thread/list- duyệt theo trang các nhật ký luồng đã lưu trữ; hỗ trợ phân trang dựa trên con trỏ cùng vớimodelProviders,sourceKinds,archived,isPinned,cwd,useStateDbOnly,searchTermvà các bộ lọc thử nghiệmparentThreadIdhoặcancestorThreadId. Các đối tượngthreadđược trả về bao gồmstatuscủa thời gian chạy.thread/turns/list- tính năng thử nghiệm; duyệt theo trang lịch sử lượt của một luồng đã lưu trữ mà không tiếp tục luồng đó.itemsViewkiểm soát việc các mục trong lượt bị bỏ qua, được tóm tắt hay được tải đầy đủ.thread/items/list- tính năng thử nghiệm; duyệt theo trang các mục luồng đã lưu bền vững, có thể tùy chọn giới hạn ở mộtturnId. Kho lưu trữ luồng đang hoạt động phải hỗ trợ phân trang mục.thread/loaded/list- liệt kê các id luồng hiện đang được tải trong bộ nhớ.thread/name/set- đặt hoặc cập nhật tên hiển thị cho người dùng của một luồng đã tải hoặc một rollout đã lưu bền vững; phát rathread/name/updated.thread/goal/set- đặt mục tiêu cho một luồng; phát rathread/goal/updated.thread/goal/get- đọc mục tiêu hiện tại của một luồng.thread/goal/clear- xóa mục tiêu của một luồng; phát rathread/goal/cleared.thread/metadata/update- vá siêu dữ liệu của luồng lưu trữ dựa trên SQLite, bao gồmgitInfovàisPinnedđã được lưu bền vững.thread/archive- di chuyển tệp nhật ký của một luồng vào thư mục lưu trữ và cố gắng lưu trữ nhật ký của các luồng hậu duệ đã được tạo mà chưa được lưu trữ; trả về{}khi thành công và phát rathread/archivedcho mỗi luồng được lưu trữ.thread/delete- xóa vĩnh viễn một luồng đang hoạt động hoặc đã lưu trữ được lưu bền vững cùng mọi luồng hậu duệ đã được tạo; trả về{}khi thành công và phát rathread/deletedcho mỗi luồng bị xóa.thread/unsubscribe- hủy đăng ký nhận các sự kiện lượt/mục của luồng đối với kết nối này. Nếu đây là bên đăng ký cuối cùng, máy chủ sẽ dỡ luồng sau khoảng thời gian chờ không hoạt động khi không có bên đăng ký và phát rathread/closed.thread/unarchive- khôi phục rollout của một luồng đã lưu trữ trở lại thư mục phiên đang hoạt động; trả vềthreadđã khôi phục và phát rathread/unarchived.thread/status/changed- thông báo được phát ra khistatusthời gian chạy của một luồng đã tải thay đổi.thread/compact/start- kích hoạt việc nén lịch sử hội thoại cho một luồng; trả về{}ngay lập tức trong khi tiến trình được truyền trực tiếp qua các thông báoturn/*vàitem/*.thread/shellCommand- chạy một lệnh shell do người dùng khởi tạo trên một luồng. Lệnh này chạy bên ngoài môi trường cô lập với toàn quyền truy cập và không kế thừa chính sách môi trường cô lập của luồng.thread/backgroundTerminals/clean- dừng tất cả terminal nền đang chạy của một luồng (tính năng thử nghiệm; yêu cầucapabilities.experimentalApi).thread/backgroundTerminals/list- liệt kê các terminal nền đang chạy của một luồng đã tải (tính năng thử nghiệm; yêu cầucapabilities.experimentalApi).thread/backgroundTerminals/terminate- chấm dứt một terminal nền đang chạy theoprocessIdcủa app-server (tính năng thử nghiệm; yêu cầucapabilities.experimentalApi).thread/rollback- không còn được khuyến nghị; loại bỏ N lượt cuối khỏi ngữ cảnh trong bộ nhớ và lưu bền vững một dấu mốc hoàn tác; trả vềthreadđã cập nhật.turn/start- thêm đầu vào của người dùng hoặc đầu ra công cụ độc lập vào một luồng và bắt đầu quá trình tạo nội dung của Codex; phản hồi bằngturnban đầu và truyền trực tiếp các sự kiện. Đối vớicollaborationMode,settings.developer_instructions: nullcó nghĩa là "sử dụng hướng dẫn tích hợp sẵn cho chế độ đã chọn".thread/inject_items- nối thêm các mục Responses API thô vào lịch sử hiển thị cho mô hình của một luồng đã tải mà không bắt đầu lượt người dùng.turn/steer- nối thêm đầu vào của người dùng vào lượt đang xử lý của một luồng; trả vềturnIdđã được chấp nhận.turn/interrupt- yêu cầu hủy một lượt đang xử lý; khi thành công sẽ có{}và lượt kết thúc vớistatus: "interrupted".review/start- khởi chạy trình đánh giá Codex cho một luồng; phát ra các mụcenteredReviewModevàexitedReviewMode.command/exec- chạy một lệnh duy nhất trong môi trường cô lập của máy chủ mà không bắt đầu luồng/lượt.command/exec/write- ghi các bytestdinvào một phiêncommand/execđang chạy hoặc đóngstdin.command/exec/resize- thay đổi kích thước một phiêncommand/execđang chạy có PTY hỗ trợ.command/exec/terminate- dừng một phiêncommand/execđang chạy.command/exec/outputDelta(thông báo) - được phát ra cho các khối stdout/stderr được mã hóa base64 từ một phiêncommand/exectruyền trực tiếp.process/spawn- bắt đầu một phiên tiến trình tường minh bên ngoài môi trường cô lập của Codex (tính năng thử nghiệm; yêu cầucapabilities.experimentalApi).process/writeStdin- ghi các byte stdin vào một phiênprocess/spawnđang chạy hoặc đóng stdin (tính năng thử nghiệm).process/resizePty- thay đổi kích thước một phiên tiến trình đang chạy có PTY hỗ trợ (tính năng thử nghiệm).process/kill- chấm dứt một phiên tiến trình đang chạy (tính năng thử nghiệm).process/outputDeltavàprocess/exited(thông báo) - được phát ra cho đầu ra tiến trình truyền trực tiếp và trạng thái thoát của tiến trình (tính năng thử nghiệm).model/list- liệt kê các mô hình có sẵn (đặtincludeHidden: trueđể bao gồm các mục cóhidden: true), cùng các tùy chọn mức độ suy luận,upgradetùy chọn vàinputModalities.modelProvider/capabilities/read- đọc các giới hạn khả năng của nhà cung cấp cho các tổ hợp mô hình/nhà cung cấp.experimentalFeature/list- liệt kê các cờ tính năng cùng siêu dữ liệu giai đoạn vòng đời và phân trang bằng con trỏ.experimentalFeature/enablement/set- vá các thiết lập thời gian chạy trong bộ nhớ cho những khóa tính năng được hỗ trợ nhưappsvàplugins.environment/info- tính năng thử nghiệm; kết nối với một môi trường thực thi đã cấu hình và trả về shell cùng thư mục làm việc mặc định của môi trường đó.permissionProfile/list- liệt kê các hồ sơ quyền beta và cho biết các yêu cầu có hiệu lực có cho phép chúng hay không, kèm phân trang bằng con trỏ.collaborationMode/list- liệt kê các cấu hình đặt trước cho chế độ cộng tác (tính năng thử nghiệm, không phân trang).skills/list- liệt kê các kỹ năng cho một hoặc nhiều giá trịcwd(hỗ trợforceReloadvàperCwdExtraUserRootstùy chọn).skills/extraRoots/set- thay thế các thư mục gốc bổ sung ở cấp tiến trình dùng để khám phá các kỹ năng độc lập mà không lưu bền vững chúng.skills/changed(thông báo) - được phát ra khi các tệp kỹ năng cục bộ đang được theo dõi thay đổi.hooks/list- liệt kê các hook vòng đời đã phát hiện cho một hoặc nhiều giá trịcwd.marketplace/add- thêm một marketplace plugin từ xa và lưu bền vững marketplace đó vào cấu hình marketplace của người dùng.marketplace/remove- xóa một marketplace đã cấu hình và thư mục gốc marketplace đã cài đặt của nó nếu có.marketplace/upgrade- làm mới một marketplace Git đã cấu hình hoặc tất cả marketplace Git đã cấu hình khi bạn bỏ qua tên marketplace.plugin/list- đang được phát triển; liệt kê các marketplace plugin đã phát hiện và trạng thái plugin, bao gồm siêu dữ liệu về chính sách cài đặt/xác thực, lỗi tải marketplace, id plugin nổi bật và siêu dữ liệu nguồn plugin cục bộ, Git, sổ đăng ký gói hoặc từ xa. Phần tóm tắt có thể bao gồmversiontừ xa,localVersioncục bộ, biểu tượng sáng/tối có cấu trúc vàinstallPolicySource, có thể lànull,WORKSPACE_SETTINGhoặcIMPLICIT_CANONICAL_APPcho các hàng từ xa hiện tại. Chưa gọi phương thức này từ các ứng dụng khách production.plugin/read- đang được phát triển; đọc một plugin theo đường dẫn marketplace hoặc theo tên marketplace từ xa và tên plugin, bao gồm các kỹ năng đi kèm, ứng dụng, tên máy chủ MCP vàshareUrlcủa plugin từ xa khi danh mục từ xa cung cấp giá trị này. Chưa gọi phương thức này từ các ứng dụng khách production.plugin/install- đang được phát triển; cài đặt một plugin từ đường dẫn marketplace hoặc tên marketplace từ xa. Chưa gọi phương thức này từ các ứng dụng khách production.plugin/uninstall- đang được phát triển; gỡ cài đặt một plugin đã cài đặt. Chưa gọi phương thức này từ các ứng dụng khách production.plugin/skill/read- đọc Markdown kỹ năng của plugin từ xa theo yêu cầu bằng marketplace từ xa, id plugin và tên kỹ năng.app/installed- đọc trạng thái thời gian chạy của ứng dụng đã cài đặt, bao gồm trạng thái được bật và có thể gọi có hiệu lực của từng ứng dụng.app/list- liệt kê các ứng dụng (trình kết nối) có sẵn kèm phân trang và siêu dữ liệu về khả năng truy cập/trạng thái bật.app/read- tìm nạp siêu dữ liệu và phần tóm tắt công cụ tùy chọn chỉ dùng để hiển thị cho các id ứng dụng cụ thể.skills/config/write- bật hoặc tắt các kỹ năng theo đường dẫn.mcpServer/oauth/login- bắt đầu đăng nhập OAuth cho một máy chủ MCP đã cấu hình; trả về URL ủy quyền và phát ramcpServer/oauthLogin/completedkhi hoàn tất.tool/requestUserInput- nhắc người dùng bằng 1–3 câu hỏi ngắn cho một lệnh gọi công cụ (tính năng thử nghiệm); các câu hỏi có thể đặtisOthercho tùy chọn nhập tự do.mcpServer/elicitation/request(yêu cầu máy chủ) - yêu cầu ứng dụng khách lấy dữ liệu biểu mẫu có cấu trúc hoặc xác nhận một luồng URL do máy chủ MCP yêu cầu.item/permissions/requestApproval(yêu cầu máy chủ) - yêu cầu ứng dụng khách cấp một tập con các quyền mạng hoặc hệ thống tệp do công cụrequest_permissionstích hợp sẵn yêu cầu.config/mcpServer/reload- tải lại cấu hình máy chủ MCP từ ổ đĩa và đưa yêu cầu làm mới vào hàng đợi cho các luồng đã tải.mcpServerStatus/list- liệt kê các máy chủ, công cụ, tài nguyên và trạng thái xác thực MCP (phân trang bằng con trỏ + giới hạn). Dùngdetail: "full"để nhận đầy đủ dữ liệu hoặcdetail: "toolsAndAuthOnly"để bỏ qua tài nguyên.mcpServer/resource/read- đọc một tài nguyên MCP duy nhất thông qua một máy chủ MCP đã khởi tạo.mcpServer/tool/call- gọi một công cụ trên máy chủ MCP đã cấu hình của một luồng.mcpServer/startupStatus/updated(thông báo) - được phát ra khi trạng thái khởi động của một máy chủ MCP đã cấu hình thay đổi đối với một luồng đã tải.windowsSandbox/setupStart- bắt đầu thiết lập môi trường cô lập Windows cho chế độelevatedhoặcunelevated; trả về nhanh chóng rồi phát rawindowsSandbox/setupCompletedsau đó.feedback/upload- gửi báo cáo phản hồi (phân loại + lý do/nhật ký tùy chọn + id cuộc hội thoại, cùng các tệp đính kèmextraLogFilestùy chọn).config/read- tìm nạp cấu hình có hiệu lực trên ổ đĩa sau khi phân giải các lớp cấu hình.externalAgentConfig/detect- phát hiện các thành phần tạo tác của tác nhân bên ngoài có thể được di chuyển bằngincludeHomevàcwdstùy chọn; mỗi mục được phát hiện bao gồmcwd(nullcho thư mục home).externalAgentConfig/import- áp dụng các mục di chuyển tác nhân bên ngoài đã chọn bằng cách truyền cácmigrationItemstường minh cùngcwd(nullcho thư mục home). Các loại mục được hỗ trợ gồm cấu hình, kỹ năng,AGENTS.md, plugin, cấu hình máy chủ MCP, tác nhân phụ, hook, lệnh và phiên; các lượt nhập không rỗng phát raexternalAgentConfig/import/progressvàexternalAgentConfig/import/completedkhi công việc hoàn tất. Việc nhập plugin và phiên có thể hoàn tất bất đồng bộ.config/value/write- ghi một khóa/giá trị cấu hình duy nhất vàoconfig.tomlcủa người dùng trên ổ đĩa.config/batchWrite- áp dụng nguyên tử các chỉnh sửa cấu hình vàoconfig.tomlcủa người dùng trên ổ đĩa.configRequirements/read- tìm nạp các yêu cầu từrequirements.tomlvà/hoặc MDM, bao gồm cấu hình được quản lý chính xác, danh sách cho phép,featureRequirementsđược ghim và yêu cầu mạng (hoặcnullnếu bạn chưa thiết lập yêu cầu nào).fs/readFile,fs/writeFile,fs/createDirectory,fs/getMetadata,fs/readDirectory,fs/remove,fs/copy,fs/watch,fs/unwatchvàfs/changed(thông báo) - thao tác trên các đường dẫn hệ thống tệp tuyệt đối thông qua API hệ thống tệp app-server v2.
Bản tóm tắt plugin bao gồm một union source. Plugin cục bộ trả về
{ "type": "local", "path": ... }, các mục chợ dựa trên Git trả về
{ "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... },
các mục kho gói trả về
{ "type": "npm", "package": ..., "version": ..., "registry": ... } và
các mục danh mục từ xa trả về { "type": "remote" }. Đối với các mục danh mục chỉ có từ xa,
PluginMarketplaceEntry.path có thể là null; hãy truyền
remoteMarketplaceName thay vì marketplacePath khi đọc hoặc cài đặt
các plugin đó.
Mô hình
Liệt kê mô hình (model/list)
Gọi model/list để khám phá các mô hình có sẵn và khả năng của chúng trước khi hiển thị bộ chọn mô hình hoặc personality.
{ "method": "model/list", "id": 6, "params": { "limit": 20, "includeHidden": false } }
{ "id": 6, "result": {
"data": [{
"id": "gpt-5.6-sol",
"model": "gpt-5.6-sol",
"displayName": "GPT-5.6-Sol",
"hidden": false,
"defaultReasoningEffort": "low",
"supportedReasoningEfforts": [{
"reasoningEffort": "low",
"description": "Fast responses with lighter reasoning"
}],
"inputModalities": ["text", "image"],
"supportsPersonality": true,
"isDefault": true
}],
"nextCursor": null
} }Mỗi mục mô hình có thể bao gồm:
supportedReasoningEfforts- các tùy chọn effort được mô hình hỗ trợ.defaultReasoningEffort- effort mặc định được đề xuất cho ứng dụng khách.upgrade- mã mô hình nâng cấp được đề xuất tùy chọn cho lời nhắc di chuyển trong ứng dụng khách.upgradeInfo- siêu dữ liệu nâng cấp tùy chọn cho lời nhắc di chuyển trong ứng dụng khách.hidden- mô hình có bị ẩn khỏi danh sách bộ chọn mặc định hay không.inputModalities- các loại đầu vào được mô hình hỗ trợ (ví dụ:text,image).supportsPersonality- mô hình có hỗ trợ hướng dẫn dành riêng cho personality như/personalityhay không.isDefault- mô hình có phải lựa chọn mặc định được đề xuất hay không.
Theo mặc định, model/list chỉ trả về các mô hình hiển thị trong bộ chọn. Đặt includeHidden: true nếu bạn cần danh sách đầy đủ và muốn lọc ở phía ứng dụng khách bằng hidden.
Khi thiếu inputModalities (trong các danh mục mô hình cũ), hãy coi giá trị này là ["text", "image"] để đảm bảo khả năng tương thích ngược.
Liệt kê các tính năng thử nghiệm (experimentalFeature/list)
Sử dụng điểm cuối này để khám phá các cờ tính năng cùng siêu dữ liệu và giai đoạn vòng đời:
{ "method": "experimentalFeature/list", "id": 7, "params": { "limit": 20 } }
{ "id": 7, "result": {
"data": [{
"name": "unified_exec",
"stage": "beta",
"displayName": "Unified exec",
"description": "Use the unified PTY-backed execution tool.",
"announcement": "Beta rollout for improved command execution reliability.",
"enabled": false,
"defaultEnabled": false
}],
"nextCursor": null
} }stage có thể là beta, underDevelopment, stable, deprecated hoặc removed. Đối với các cờ không phải beta, displayName, description và announcement có thể là null.
Kiểm tra môi trường thực thi (thử nghiệm)
Sử dụng environment/info để kiểm tra một môi trường từ xa đã cấu hình trước khi
bắt đầu làm việc tại đó. Phương thức này yêu cầu capabilities.experimentalApi = true.
{ "method": "environment/info", "id": 8, "params": { "environmentId": "devbox" } }
{ "id": 8, "result": {
"shell": { "name": "zsh", "path": "/bin/zsh" },
"cwd": "file:///workspace/project"
} }cwd có thể là null. Khi có, đây là URI file: chuẩn sử dụng
cú pháp đường dẫn gốc của môi trường. Mã môi trường không xác định và lỗi kết nối hoặc
giao thức sẽ trả về lỗi yêu cầu.
Luồng
thread/readđọc một luồng đã lưu mà không đăng ký nhận sự kiện; đặtincludeTurnsđể bao gồm các lượt.thread/turns/listđang thử nghiệm và duyệt theo trang qua lịch sử lượt của một luồng đã lưu mà không tiếp tục luồng đó. Sử dụngitemsViewđể chọn lược bỏ, tóm tắt hoặc tải đầy đủ các mục của lượt.thread/items/listđang thử nghiệm và duyệt theo trang qua các mục luồng được lưu bền vững, có thể giới hạn ở một lượt.thread/listhỗ trợ phân trang bằng con trỏ cùngmodelProviders,sourceKinds,archived,isPinned,cwd,useStateDbOnly,searchTermvà bộ lọc thử nghiệmparentThreadIdhoặcancestorThreadId.thread/loaded/listtrả về mã của các luồng hiện đang ở trong bộ nhớ.thread/archivedi chuyển nhật ký JSONL được lưu bền vững của luồng vào thư mục lưu trữ và cố gắng lưu trữ nhật ký của các luồng con được tạo mà chưa được lưu trữ.thread/deletexóa vĩnh viễn một luồng đang hoạt động hoặc đã lưu trữ được lưu bền vững cùng các luồng con được tạo của nó.thread/metadata/updatevá siêu dữ liệu luồng đã lưu, bao gồmgitInfovàisPinnedđược lưu bền vững.thread/unsubscribehủy đăng ký kết nối hiện tại khỏi một luồng đã tải và có thể kích hoạtthread/closedsau một khoảng gia hạn không hoạt động.thread/unarchivekhôi phục rollout của luồng đã lưu trữ về thư mục phiên đang hoạt động.thread/compact/startkích hoạt việc nén và trả về{}ngay lập tức.thread/rollbackkhông còn dùng. Phương thức này loại bỏ N lượt cuối khỏi ngữ cảnh trong bộ nhớ và ghi một dấu mốc hoàn tác vào nhật ký JSONL được lưu bền vững của luồng.thread/inject_itemsnối thêm các mục Responses API thô vào lịch sử hiển thị với mô hình của một luồng đã tải mà không bắt đầu lượt người dùng.
Bắt đầu hoặc tiếp tục một luồng
Bắt đầu một luồng mới khi bạn cần một cuộc hội thoại Codex mới.
{ "method": "thread/start", "id": 10, "params": {
"model": "gpt-5.6-terra",
"cwd": "/Users/me/project",
"approvalPolicy": "never",
"sandbox": "workspaceWrite",
"personality": "friendly",
"serviceName": "my_app_server_client"
} }
{ "id": 10, "result": {
"thread": {
"id": "thr_123",
"sessionId": "thr_123",
"preview": "",
"ephemeral": false,
"modelProvider": "openai",
"createdAt": 1730910000
}
} }
{ "method": "thread/started", "params": { "thread": { "id": "thr_123" } } }serviceName là tùy chọn. Hãy đặt trường này khi bạn muốn app-server gắn thẻ các chỉ số cấp luồng bằng tên dịch vụ của phần tích hợp.
thread/start, thread/resume và thread/fork trả về
instructionSources, một mảng đường dẫn tệp hướng dẫn đã tải. Mỗi đường dẫn sử dụng
cú pháp tuyệt đối gốc của môi trường nguồn, kể cả đối với môi trường
từ xa.
Ứng dụng khách thử nghiệm có thể đặt historyMode trên thread/start thành "legacy"
(mặc định) hoặc "paginated". Việc tạo luồng có phân trang chưa được hỗ trợ
và trả về lỗi JSON-RPC -32601. App-server có thể liệt kê và đọc bản tóm tắt của
các bản ghi phân trang hiện có, nhưng thao tác đọc toàn bộ lịch sử, phân trang lượt và tiếp tục
sẽ từ chối an toàn cho đến khi lịch sử phân trang được hỗ trợ.
Ứng dụng khách beta chọn tham gia capabilities.experimentalApi có thể truyền mã
hồ sơ quyền có tên trong permissions thay cho trường sandbox cũ.
Không gửi đồng thời permissions và sandbox. Sử dụng
permissionProfile/list với cwd của dự án để khám phá các hồ sơ có sẵn
và xem các yêu cầu được quản lý có cho phép từng hồ sơ hay không.
thread.sessionId nhận diện thư mục gốc của cây phiên trực tiếp hiện tại. Các luồng gốc
sử dụng chính mã luồng của chúng làm mã phiên; các luồng phân nhánh giữ mã phiên
của luồng gốc mà chúng bắt nguồn. Ứng dụng khách nên đọc mã phiên từ
thread.sessionId thay vì suy ra từ mã luồng.
Để tiếp tục một phiên đã lưu, hãy gọi thread/resume với thread.id mà bạn đã ghi lại trước đó. Cấu trúc phản hồi khớp với thread/start. Bạn cũng có thể truyền các giá trị ghi đè cấu hình tương tự được thread/start hỗ trợ, chẳng hạn personality:
{ "method": "thread/resume", "id": 11, "params": {
"threadId": "thr_123",
"personality": "friendly"
} }
{ "id": 11, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false } } }Việc tiếp tục một luồng không tự cập nhật thread.updatedAt (hoặc thời gian sửa đổi của tệp rollout). Dấu thời gian được cập nhật khi bạn bắt đầu một lượt.
Nếu bạn đánh dấu một máy chủ MCP đang bật là required trong cấu hình và máy chủ đó không khởi tạo được, thread/start và thread/resume sẽ thất bại thay vì tiếp tục mà không có máy chủ đó.
dynamicTools trên thread/start là một trường thử nghiệm (yêu cầu capabilities.experimentalApi = true). Codex lưu bền vững các công cụ động này trong siêu dữ liệu rollout của luồng và khôi phục chúng khi gọi thread/resume nếu bạn không cung cấp công cụ động mới.
Nếu bạn tiếp tục bằng một mô hình khác với mô hình đã ghi trong rollout, Codex sẽ phát cảnh báo và áp dụng một hướng dẫn chuyển mô hình dùng một lần ở lượt tiếp theo.
Quản lý mục tiêu của luồng
Sử dụng thread/goal/set, thread/goal/get và thread/goal/clear để quản lý
cùng trạng thái mục tiêu được lưu bền vững mà /goal hiển thị trong TUI.
{ "method": "thread/goal/set", "id": 13, "params": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000
} }
{ "id": 13, "result": { "goal": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
} } }
{ "method": "thread/goal/updated", "params": {
"threadId": "thr_123",
"goal": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
}
} }Mục tiêu phải không rỗng và dài tối đa 4.000 ký tự. Việc cung cấp một
mục tiêu mới sẽ thay thế mục tiêu hiện tại và đặt lại số liệu sử dụng. Việc cung cấp
mục tiêu hiện tại chưa ở trạng thái kết thúc hoặc lược bỏ objective sẽ cập nhật trạng thái hay ngân sách token
mà vẫn giữ nguyên lịch sử sử dụng.
Để phân nhánh từ một phiên đã lưu, hãy gọi thread/fork với thread.id. Thao tác này tạo một mã luồng mới và phát thông báo thread/started cho luồng đó. Truyền
lastTurnId để sao chép lịch sử đến hết lượt đó và lược bỏ các
lượt sau:
{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123", "lastTurnId": "turn_456" } }
{ "id": 12, "result": { "thread": { "id": "thr_456", "sessionId": "thr_123", "forkedFromId": "thr_123" } } }
{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }App-server từ chối lastTurnId đang xử lý. Nếu bạn lược bỏ trường này khi
luồng nguồn đang ở giữa một lượt, nhánh sẽ ghi lại dấu mốc gián đoạn thay vì
giữ lại một lượt chưa hoàn chỉnh không được đánh dấu.
Truyền ephemeral: true để tạo một nhánh trong bộ nhớ mà không thêm vào danh sách
luồng đã lưu:
{
"method": "thread/fork",
"id": 13,
"params": {
"threadId": "thr_123",
"ephemeral": true
}
}
{
"id": 13,
"result": {
"thread": {
"id": "thr_789",
"sessionId": "thr_789",
"forkedFromId": "thr_123",
"ephemeral": true
}
}
}Các nhánh tạm thời của luồng phân trang cũng yêu cầu excludeTurns: true. Trường đó
đang thử nghiệm và yêu cầu capabilities.experimentalApi = true.
Khi đã đặt tiêu đề hiển thị cho người dùng của luồng, app-server sẽ điền thread.name vào các phản hồi thread/list, thread/read, thread/resume, thread/unarchive và thread/rollback. thread/start và thread/fork có thể lược bỏ name (hoặc trả về null) cho đến khi tiêu đề được đặt sau đó.
Đọc một luồng đã lưu (mà không tiếp tục)
Sử dụng thread/read khi bạn muốn lấy dữ liệu luồng đã lưu nhưng không muốn tiếp tục luồng hoặc đăng ký nhận sự kiện của luồng.
includeTurns- khi làtrue, phản hồi bao gồm các lượt của luồng; khi làfalsehoặc bị lược bỏ, bạn chỉ nhận được bản tóm tắt luồng.- Các đối tượng
threadđược trả về bao gồmstatusthời gian chạy (notLoaded,idle,systemErrorhoặcactivevớiactiveFlags).
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123", "includeTurns": true } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }Không giống thread/resume, thread/read không tải luồng vào bộ nhớ hoặc phát thread/started.
Liệt kê các lượt của luồng
thread/turns/list đang thử nghiệm. Sử dụng phương thức này để duyệt theo trang qua lịch sử lượt của một luồng đã lưu mà không tiếp tục luồng. Theo mặc định, kết quả được sắp xếp từ mới nhất đến cũ nhất để ứng dụng khách có thể truy xuất các lượt cũ hơn bằng nextCursor. Phản hồi cũng bao gồm backwardsCursor; truyền giá trị này làm cursor cùng sortDirection: "asc" để truy xuất các lượt mới hơn mục đầu tiên của trang trước.
itemsView kiểm soát lượng dữ liệu mục của lượt được bao gồm trong phản hồi:
notLoadedlược bỏ các mục.summarytrả về dữ liệu mục đã tóm tắt và là giá trị mặc định khi bị lược bỏ.fulltrả về đầy đủ dữ liệu mục.
{ "method": "thread/turns/list", "id": 20, "params": {
"threadId": "thr_123",
"limit": 50,
"sortDirection": "desc",
"itemsView": "summary"
} }
{ "id": 20, "result": {
"data": [],
"nextCursor": "older-turns-cursor-or-null",
"backwardsCursor": "newer-turns-cursor-or-null"
} }thread/items/list cũng đang thử nghiệm. Phương thức này duyệt theo trang qua các mục được lưu bền vững mà không
tiếp tục luồng. Truyền turnId để giới hạn kết quả ở một lượt hoặc lược bỏ trường này
để duyệt các mục trên toàn luồng. Kho luồng đang hoạt động phải hỗ trợ
phân trang mục; nếu không, máy chủ sẽ trả về lỗi phương thức không được hỗ trợ.
Liệt kê luồng (có phân trang và bộ lọc)
thread/list cho phép bạn hiển thị giao diện lịch sử. Theo mặc định, kết quả được sắp xếp từ mới nhất đến cũ nhất theo createdAt. Các bộ lọc được áp dụng trước khi phân trang. Truyền tổ hợp bất kỳ của:
cursor- chuỗi không trong suốt từ phản hồi trước; lược bỏ cho trang đầu tiên.limit- máy chủ mặc định dùng kích thước trang hợp lý nếu không đặt.sortKey-created_at(mặc định),updated_athoặcrecency_at.sortDirection-desc(mặc định) hoặcasc.modelProviders- giới hạn kết quả ở các nhà cung cấp cụ thể; không đặt, null hoặc mảng rỗng sẽ bao gồm mọi nhà cung cấp.sourceKinds- giới hạn kết quả ở các nguồn luồng cụ thể. Khi bị lược bỏ hoặc là[], máy chủ mặc định chỉ dùng các nguồn tương tác:clivàvscode.archived- khi làtrue, chỉ liệt kê các luồng đã lưu trữ. Khi làfalsehoặc bị lược bỏ, liệt kê các luồng chưa lưu trữ (mặc định).isPinned- khi được cung cấp, chỉ trả về các luồng có trạng thái ghim được lưu bền vững khớp với giá trị. Lược bỏ trường này để trả về cả luồng đã ghim và chưa ghim.cwd- giới hạn kết quả ở các luồng có thư mục làm việc hiện tại của phiên khớp chính xác với đường dẫn này hoặc một trong các đường dẫn trong mảng. Đường dẫn tương đối được phân giải từ thư mục làm việc của tiến trình app-server.useStateDbOnly- khi làtrue, trả về kết quả cơ sở dữ liệu trạng thái mà không quét nhật ký luồng JSONL để sửa chữa siêu dữ liệu. Lược bỏ hoặc truyềnfalseđể sử dụng hành vi quét và sửa chữa mặc định.searchTerm- giới hạn kết quả ở các luồng có tiêu đề được trích xuất chứa đoạn văn bản phân biệt chữ hoa chữ thường này.parentThreadId- giới hạn kết quả ở các luồng con trực tiếp của luồng cha đã cho. Bộ lọc này đang thử nghiệm và yêu cầucapabilities.experimentalApi = true.ancestorThreadId- giới hạn kết quả ở các luồng con được tạo từ luồng đã cho ở bất kỳ độ sâu nào. Bộ lọc này đang thử nghiệm và yêu cầucapabilities.experimentalApi = true; không kết hợp vớiparentThreadId.
sourceKinds chấp nhận các giá trị sau:
clivscodeexecappServersubAgentsubAgentReviewsubAgentCompactsubAgentThreadSpawnsubAgentOtherunknown
Ví dụ:
{ "method": "thread/list", "id": 20, "params": {
"cursor": null,
"limit": 25,
"sortKey": "created_at"
} }
{ "id": 20, "result": {
"data": [
{ "id": "thr_a", "preview": "Create a TUI", "ephemeral": false, "isPinned": true, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
{ "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "isPinned": false, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
],
"nextCursor": "opaque-token-or-null"
} }Khi nextCursor là null, bạn đã đến trang cuối cùng.
Cập nhật siêu dữ liệu luồng đã lưu
Sử dụng thread/metadata/update để vá siêu dữ liệu luồng đã lưu mà không tiếp tục
luồng. Đặt isPinned để ghim hoặc bỏ ghim luồng, hoặc cập nhật gitInfo để thay đổi
siêu dữ liệu Git được lưu bền vững. Các trường bị lược bỏ sẽ không thay đổi; null rõ ràng sẽ xóa một
giá trị siêu dữ liệu Git đã lưu.
{ "method": "thread/metadata/update", "id": 21, "params": {
"threadId": "thr_123",
"isPinned": true,
"gitInfo": { "branch": "feature/sidebar-pr" }
} }
{ "id": 21, "result": {
"thread": {
"id": "thr_123",
"isPinned": true,
"gitInfo": { "sha": null, "branch": "feature/sidebar-pr", "originUrl": null }
}
} }Theo dõi thay đổi trạng thái luồng
thread/status/changed được phát mỗi khi trạng thái thời gian chạy của một luồng đã tải thay đổi. Payload bao gồm threadId và status mới.
{
"method": "thread/status/changed",
"params": {
"threadId": "thr_123",
"status": { "type": "active", "activeFlags": ["waitingOnApproval"] }
}
}Liệt kê các luồng đã tải
thread/loaded/list trả về mã của các luồng hiện đang được tải trong bộ nhớ.
{ "method": "thread/loaded/list", "id": 21 }
{ "id": 21, "result": { "data": ["thr_123", "thr_456"] } }Hủy đăng ký khỏi một luồng đã tải
thread/unsubscribe xóa đăng ký của kết nối hiện tại khỏi một luồng. Trạng thái phản hồi là một trong các giá trị:
unsubscribedkhi kết nối đã đăng ký và hiện đã được xóa.notSubscribedkhi kết nối chưa đăng ký luồng đó.notLoadedkhi luồng chưa được tải.
Nếu đây là người đăng ký cuối cùng, máy chủ sẽ giữ luồng được tải cho đến khi luồng không có người đăng ký và không có hoạt động trong 30 phút. Khi khoảng gia hạn hết hạn, app-server dỡ luồng và phát một chuyển đổi thread/status/changed sang notLoaded cùng thread/closed.
{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }
{ "id": 22, "result": { "status": "unsubscribed" } }Nếu luồng hết hạn sau đó:
{ "method": "thread/status/changed", "params": {
"threadId": "thr_123",
"status": { "type": "notLoaded" }
} }
{ "method": "thread/closed", "params": { "threadId": "thr_123" } }Lưu trữ một luồng
Sử dụng thread/archive để di chuyển nhật ký luồng được lưu bền vững (được lưu dưới dạng tệp JSONL trên đĩa) vào thư mục phiên đã lưu trữ. Việc lưu trữ một luồng cũng cố gắng lưu trữ các luồng con được tạo mà chưa được lưu trữ.
{ "method": "thread/archive", "id": 22, "params": { "threadId": "thr_b" } }
{ "id": 22, "result": {} }
{ "method": "thread/archived", "params": { "threadId": "thr_b" } }
{ "method": "thread/archived", "params": { "threadId": "thr_child" } }Các luồng đã lưu trữ sẽ không xuất hiện trong các lần gọi thread/list sau này trừ khi bạn truyền archived: true. Máy chủ phát một thông báo thread/archived cho mỗi luồng mà nó thực sự lưu trữ; nếu không thể lưu trữ một luồng con được tạo, yêu cầu vẫn có thể thành công mà không có thông báo đã lưu trữ cho luồng con đó.
Xóa một luồng
Sử dụng thread/delete để xóa vĩnh viễn một luồng đang hoạt động hoặc đã lưu trữ
được duy trì, cùng các luồng hậu duệ do luồng đó tạo ra. Máy chủ xóa các tệp rollout hiện có và
siêu dữ liệu liên quan trước khi trả về trạng thái thành công; các tệp rollout bị thiếu được xem là
đã bị xóa. Không thể xóa các luồng gốc tạm thời.
{ "method": "thread/delete", "id": 23, "params": { "threadId": "thr_b" } }
{ "id": 23, "result": {} }
{ "method": "thread/deleted", "params": { "threadId": "thr_b" } }
{ "method": "thread/deleted", "params": { "threadId": "thr_child" } }Hủy lưu trữ một luồng
Sử dụng thread/unarchive để chuyển rollout của một luồng đã lưu trữ trở lại thư mục phiên đang hoạt động.
{ "method": "thread/unarchive", "id": 24, "params": { "threadId": "thr_b" } }
{ "id": 24, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes" } } }
{ "method": "thread/unarchived", "params": { "threadId": "thr_b" } }Kích hoạt việc thu gọn luồng
Sử dụng thread/compact/start để kích hoạt thủ công việc thu gọn lịch sử cho một luồng. Yêu cầu trả về ngay lập tức với {}.
App-server phát tiến trình dưới dạng các thông báo turn/* và item/* tiêu chuẩn trên cùng threadId, bao gồm vòng đời của một mục contextCompaction (item/started rồi đến item/completed).
{ "method": "thread/compact/start", "id": 25, "params": { "threadId": "thr_b" } }
{ "id": 25, "result": {} }Chạy lệnh shell trong một luồng
Sử dụng thread/shellCommand cho các lệnh shell do người dùng khởi chạy và thuộc về một luồng. Yêu cầu trả về ngay lập tức với {}, trong khi tiến trình được truyền trực tuyến qua các thông báo turn/* và item/* tiêu chuẩn.
API này chạy bên ngoài môi trường cô lập với toàn quyền truy cập và không kế thừa chính sách môi trường cô lập của luồng. Client chỉ nên cung cấp API này cho các lệnh được người dùng chủ động khởi chạy một cách rõ ràng.
Nếu luồng đã có một lượt đang hoạt động, lệnh sẽ chạy dưới dạng tác vụ phụ trợ trong lượt đó và đầu ra đã định dạng của lệnh sẽ được chèn vào luồng thông báo của lượt. Nếu luồng đang rảnh, app-server sẽ bắt đầu một lượt độc lập cho lệnh shell.
Đặt timeoutMs để giới hạn thời gian thực thi theo mili giây. Nếu bỏ qua hoặc truyền
null, hệ thống sẽ dùng giá trị mặc định là một giờ. 0 yêu cầu hết thời gian chờ ngay lập tức; các giá trị âm
sẽ bị từ chối. Thời gian chờ không làm trì hoãn phản hồi xác nhận RPC tức thời.
{ "method": "thread/shellCommand", "id": 26, "params": { "threadId": "thr_b", "command": "git status --short", "timeoutMs": 10000 } }
{ "id": 26, "result": {} }Dọn dẹp các terminal chạy nền
Sử dụng thread/backgroundTerminals/clean để dừng tất cả terminal chạy nền đang hoạt động được liên kết với một luồng. Phương thức này đang ở giai đoạn thử nghiệm và yêu cầu capabilities.experimentalApi = true.
{ "method": "thread/backgroundTerminals/clean", "id": 27, "params": { "threadId": "thr_b" } }
{ "id": 27, "result": {} }Sử dụng thread/backgroundTerminals/list để kiểm tra các terminal chạy nền đang hoạt động
của một luồng đã tải. Yêu cầu hỗ trợ phân trang tiêu chuẩn bằng cursor và limit,
còn processId được trả về là mã tiến trình của app-server. Phương thức này
đang ở giai đoạn thử nghiệm và yêu cầu capabilities.experimentalApi = true:
{ "method": "thread/backgroundTerminals/list", "id": 28, "params": { "threadId": "thr_b" } }
{ "id": 28, "result": { "data": [
{
"itemId": "item_456",
"processId": "42",
"command": "python3 -m http.server",
"cwd": "/workspace",
"osPid": null,
"cpuPercent": null,
"rssKb": null
}
], "nextCursor": null } }Sử dụng thread/backgroundTerminals/terminate với processId đó để dừng một
terminal chạy nền. Phương thức này đang ở giai đoạn thử nghiệm và yêu cầu
capabilities.experimentalApi = true:
{ "method": "thread/backgroundTerminals/terminate", "id": 29, "params": { "threadId": "thr_b", "processId": "42" } }
{ "id": 29, "result": { "terminated": true } }Hoàn tác các lượt gần đây
thread/rollback không còn được khuyến nghị và sẽ bị loại bỏ. Phương thức này xóa các
mục numTurns cuối cùng khỏi ngữ cảnh trong bộ nhớ và ghi lại một dấu mốc hoàn tác trong
nhật ký rollout. thread được trả về bao gồm turns đã được điền sau khi
hoàn tác.
{ "method": "thread/rollback", "id": 30, "params": { "threadId": "thr_b", "numTurns": 1 } }
{ "id": 30, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes", "ephemeral": false } } }Lượt
Trường input chấp nhận một danh sách các mục:
{ "type": "text", "text": "Explain this diff" }{ "type": "image", "url": "https://.../design.png" }{ "type": "localImage", "path": "/tmp/screenshot.png" }
Bạn có thể ghi đè các cài đặt cấu hình theo từng lượt (mô hình, mức độ nỗ lực, tính cách, cwd, chính sách môi trường cô lập, bản tóm tắt). Khi được chỉ định, các cài đặt này trở thành giá trị mặc định cho những lượt sau trong cùng luồng. outputSchema chỉ áp dụng cho lượt hiện tại. Đối với sandboxPolicy.type = "externalSandbox", hãy đặt networkAccess thành restricted hoặc enabled; đối với workspaceWrite, networkAccess vẫn là một giá trị boolean.
Đối với turn/start.collaborationMode, settings.developer_instructions: null có nghĩa là "sử dụng hướng dẫn tích hợp sẵn cho chế độ đã chọn", chứ không phải xóa hướng dẫn của chế độ.
Quyền đọc trong môi trường cô lập (ReadOnlyAccess)
sandboxPolicy hỗ trợ các biện pháp kiểm soát quyền đọc rõ ràng:
readOnly:accesstùy chọn (mặc định là{ "type": "fullAccess" }hoặc các thư mục gốc bị giới hạn).workspaceWrite:readOnlyAccesstùy chọn (mặc định là{ "type": "fullAccess" }hoặc các thư mục gốc bị giới hạn).
Cấu trúc quyền đọc bị giới hạn:
{
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
}Trên macOS, includePlatformDefaults: true nối thêm một chính sách Seatbelt mặc định của nền tảng đã được tuyển chọn cho các phiên bị giới hạn quyền đọc. Điều này cải thiện khả năng tương thích của công cụ mà không cho phép rộng rãi toàn bộ /System.
Ví dụ:
{ "type": "readOnly", "access": { "type": "fullAccess" } }{
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"readOnlyAccess": {
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
},
"networkAccess": false
}Bắt đầu một lượt
{ "method": "turn/start", "id": 30, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Run tests" } ],
"cwd": "/Users/me/project",
"approvalPolicy": "unlessTrusted",
"sandboxPolicy": {
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"networkAccess": true
},
"model": "gpt-5.6-terra",
"effort": "medium",
"summary": "concise",
"personality": "friendly",
"outputSchema": {
"type": "object",
"properties": { "answer": { "type": "string" } },
"required": ["answer"],
"additionalProperties": false
}
} }
{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }Để bắt đầu một lượt bằng đầu ra từ công cụ mà ứng dụng khách của bạn đã chạy, hãy truyền toolOutput
với một name không rỗng, một namespace tùy chọn và một chuỗi output hoặc
mảng các mục nội dung. Đặt input thành một mảng rỗng; bạn không thể kết hợp
toolOutput với đầu vào người dùng không rỗng.
{
"method": "turn/start",
"id": 31,
"params": {
"threadId": "thr_123",
"input": [],
"toolOutput": {
"name": "run_tests",
"namespace": null,
"output": "All 42 tests passed."
}
}
}Đầu ra vẫn là đầu ra công cụ trong cuộc hội thoại và xuất hiện dưới dạng một mục
functionCallOutput trong các thông báo và lịch sử đã lưu bền vững. Nếu một lượt thông thường
đang hoạt động, Codex sẽ đưa đầu ra vào hàng đợi của lượt đó.
Chèn các mục vào một luồng
Sử dụng thread/inject_items để nối các mục Responses API đã tạo sẵn vào lịch sử lời nhắc của một luồng đã tải mà không bắt đầu lượt người dùng. Các mục này được lưu vào rollout và đưa vào các yêu cầu mô hình tiếp theo.
{ "method": "thread/inject_items", "id": 31, "params": {
"threadId": "thr_123",
"items": [
{
"type": "message",
"role": "assistant",
"content": [{ "type": "output_text", "text": "Previously computed context." }]
}
]
} }
{ "id": 31, "result": {} }Điều hướng một lượt đang hoạt động
Sử dụng turn/steer để nối thêm dữ liệu đầu vào của người dùng vào lượt đang được xử lý.
- Bao gồm
expectedTurnId; giá trị này phải khớp với mã lượt đang hoạt động. - Yêu cầu sẽ thất bại nếu luồng không có lượt nào đang hoạt động.
turn/steerkhông phát thông báoturn/startedmới.turn/steerkhông chấp nhận các giá trị ghi đè ở cấp lượt (model,cwd,sandboxPolicyhoặcoutputSchema).
{ "method": "turn/steer", "id": 32, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Actually focus on failing tests first." } ],
"expectedTurnId": "turn_456"
} }
{ "id": 32, "result": { "turnId": "turn_456" } }Bắt đầu một lượt (gọi một skill)
Gọi một skill một cách rõ ràng bằng cách đưa $<skill-name> vào dữ liệu đầu vào dạng văn bản và thêm một mục đầu vào skill đi kèm.
{ "method": "turn/start", "id": 33, "params": {
"threadId": "thr_123",
"input": [
{ "type": "text", "text": "$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage." },
{ "type": "skill", "name": "skill-creator", "path": "/Users/me/.codex/skills/skill-creator/SKILL.md" }
]
} }
{ "id": 33, "result": { "turn": { "id": "turn_457", "status": "inProgress", "items": [], "error": null } } }Ngắt một lượt
{ "method": "turn/interrupt", "id": 31, "params": { "threadId": "thr_123", "turnId": "turn_456" } }
{ "id": 31, "result": {} }Khi thành công, lượt kết thúc với status: "interrupted".
Đánh giá
review/start chạy trình đánh giá Codex cho một luồng và truyền trực tuyến các mục đánh giá. Các mục tiêu bao gồm:
uncommittedChangesbaseBranch(so sánh phần khác biệt với một nhánh)commit(đánh giá một commit cụ thể)custom(hướng dẫn dạng tự do)
Sử dụng delivery: "inline" (mặc định) để chạy đánh giá trên luồng hiện có hoặc delivery: "detached" để phân nhánh thành một luồng đánh giá mới.
Ví dụ về yêu cầu/phản hồi:
{ "method": "review/start", "id": 40, "params": {
"threadId": "thr_123",
"delivery": "inline",
"target": { "type": "commit", "sha": "1234567deadbeef", "title": "Polish tui colors" }
} }
{ "id": 40, "result": {
"turn": {
"id": "turn_900",
"status": "inProgress",
"items": [
{ "type": "userMessage", "id": "turn_900", "content": [ { "type": "text", "text": "Review commit 1234567: Polish tui colors" } ] }
],
"error": null
},
"reviewThreadId": "thr_123"
} }Đối với đánh giá tách rời, hãy sử dụng "delivery": "detached". Phản hồi có cùng cấu trúc, nhưng reviewThreadId sẽ là mã của luồng đánh giá mới (khác với threadId ban đầu). Máy chủ cũng phát thông báo thread/started cho luồng mới đó trước khi truyền trực tuyến lượt đánh giá.
Codex truyền trực tuyến thông báo turn/started thông thường, sau đó là item/started với một mục enteredReviewMode:
{
"method": "item/started",
"params": {
"item": {
"type": "enteredReviewMode",
"id": "turn_900",
"review": "current changes"
}
}
}Khi trình đánh giá hoàn tất, máy chủ phát item/started và item/completed chứa một mục exitedReviewMode với nội dung đánh giá cuối cùng:
{
"method": "item/completed",
"params": {
"item": {
"type": "exitedReviewMode",
"id": "turn_900",
"review": "Looks solid overall..."
}
}
}Sử dụng thông báo này để hiển thị đầu ra của trình đánh giá trong client của bạn.
Thực thi tiến trình
process/* là một API kiểm soát tiến trình rõ ràng đang ở giai đoạn thử nghiệm. API này yêu cầu
capabilities.experimentalApi = true và chạy bên ngoài môi trường cô lập của Codex. Chỉ sử dụng API này
khi client của bạn chủ động cung cấp quyền kiểm soát tiến trình cục bộ mà không có
môi trường cô lập.
Khởi động một tiến trình bằng process/spawn và cung cấp một processHandle, sau đó sử dụng
handle đó cho các yêu cầu stdin, thay đổi kích thước và kết thúc. Đầu ra được truyền trực tuyến qua
các thông báo process/outputDelta, còn trạng thái hoàn tất được truyền trực tuyến qua
process/exited.
{ "method": "process/spawn", "id": 48, "params": {
"command": ["python3", "-m", "pytest", "-q"],
"processHandle": "pytest-1",
"cwd": "/Users/me/project",
"tty": true
} }
{ "id": 48, "result": {} }
{ "method": "process/outputDelta", "params": {
"processHandle": "pytest-1",
"stream": "stdout",
"deltaBase64": "Li4u"
} }
{ "method": "process/exited", "params": {
"processHandle": "pytest-1",
"exitCode": 0
} }Sử dụng process/writeStdin với deltaBase64, closeStdin hoặc cả hai để gửi
dữ liệu đầu vào. Sử dụng process/resizePty cho các sự kiện thay đổi kích thước PTY và process/kill để
kết thúc một tiến trình đang chạy.
Thực thi lệnh
command/exec chạy một lệnh duy nhất (mảng argv) trong môi trường cô lập của máy chủ mà không tạo luồng.
{ "method": "command/exec", "id": 50, "params": {
"command": ["ls", "-la"],
"cwd": "/Users/me/project",
"sandboxPolicy": { "type": "workspaceWrite" },
"timeoutMs": 10000
} }
{ "id": 50, "result": { "exitCode": 0, "stdout": "...", "stderr": "" } }Sử dụng sandboxPolicy.type = "externalSandbox" nếu bạn đã đặt tiến trình máy chủ trong môi trường cô lập và muốn Codex bỏ qua việc tự thực thi cơ chế cô lập. Đối với môi trường cô lập bên ngoài, hãy đặt networkAccess thành restricted (mặc định) hoặc enabled. Đối với readOnly và workspaceWrite, hãy sử dụng cùng cấu trúc access / readOnlyAccess tùy chọn như ở trên.
Lưu ý:
- Máy chủ từ chối các mảng
commandtrống. sandboxPolicychấp nhận cùng cấu trúc màturn/startsử dụng (ví dụ:dangerFullAccess,readOnly,workspaceWrite,externalSandbox).- Khi bị bỏ qua,
timeoutMsquay về giá trị mặc định của máy chủ. - Đặt
tty: truecho các phiên dựa trên PTY và sử dụngprocessIdkhi bạn dự định tiếp tục vớicommand/exec/write,command/exec/resizehoặccommand/exec/terminate. - Đặt
streamStdoutStderr: trueđể nhận các thông báocommand/exec/outputDeltatrong khi lệnh đang chạy.
Đọc các yêu cầu quản trị (configRequirements/read)
Sử dụng configRequirements/read để kiểm tra các yêu cầu quản trị có hiệu lực được tải từ requirements.toml và/hoặc MDM.
{ "method": "configRequirements/read", "id": 52, "params": {} }
{ "id": 52, "result": {
"requirements": {
"allowedApprovalPolicies": ["onRequest", "unlessTrusted"],
"allowedSandboxModes": ["readOnly", "workspaceWrite"],
"featureRequirements": {
"personality": true,
"unified_exec": false
},
"network": {
"enabled": true,
"allowedDomains": ["api.openai.com"],
"allowUnixSockets": ["/tmp/example.sock"],
"dangerouslyAllowAllUnixSockets": false
}
}
} }result.requirements là null khi không có yêu cầu nào được cấu hình. Xem tài liệu về requirements.toml để biết chi tiết về các khóa và giá trị được hỗ trợ.
Thiết lập môi trường cô lập Windows (windowsSandbox/setupStart)
Các client Windows tùy chỉnh có thể kích hoạt thiết lập môi trường cô lập theo cách bất đồng bộ thay vì chặn trong quá trình kiểm tra lúc khởi động.
{ "method": "windowsSandbox/setupStart", "id": 53, "params": { "mode": "elevated" } }
{ "id": 53, "result": { "started": true } }App-server bắt đầu thiết lập trong nền và sau đó phát thông báo hoàn tất:
{
"method": "windowsSandbox/setupCompleted",
"params": { "mode": "elevated", "success": true, "error": null }
}Các chế độ:
elevated- chạy quy trình thiết lập môi trường cô lập Windows với quyền nâng cao.unelevated- chạy quy trình thiết lập/kiểm tra trước kiểu cũ.
Hệ thống tệp
Các API hệ thống tệp v2 hoạt động trên đường dẫn tuyệt đối. Sử dụng fs/watch khi client cần vô hiệu hóa trạng thái UI sau khi một tệp hoặc thư mục thay đổi.
{ "method": "fs/watch", "id": 54, "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
"path": "/Users/me/project/.git/HEAD"
} }
{ "id": 54, "result": { "path": "/Users/me/project/.git/HEAD" } }
{ "method": "fs/changed", "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
"changedPaths": ["/Users/me/project/.git/HEAD"]
} }
{ "method": "fs/unwatch", "id": 55, "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1"
} }
{ "id": 55, "result": {} }Việc theo dõi một tệp sẽ phát fs/changed cho đường dẫn tệp đó, bao gồm các cập nhật được chuyển đến qua thao tác thay thế hoặc đổi tên.
Sự kiện
Thông báo sự kiện là luồng do máy chủ khởi tạo dành cho vòng đời của luồng, vòng đời của lượt và các mục bên trong. Sau khi bắt đầu hoặc tiếp tục một luồng, hãy tiếp tục đọc luồng truyền tải đang hoạt động để nhận các thông báo thread/started, thread/archived, thread/unarchived, thread/closed, thread/status/changed, turn/*, item/* và serverRequest/resolved.
Từ chối nhận thông báo
Client có thể chặn các thông báo cụ thể theo từng kết nối bằng cách gửi tên phương thức chính xác trong initialize.params.capabilities.optOutNotificationMethods.
- Chỉ khớp chính xác:
item/agentMessage/deltachỉ chặn phương thức đó. - Tên phương thức không xác định sẽ bị bỏ qua.
- Áp dụng cho các thông báo
thread/*,turn/*,item/*hiện tại và các thông báo v2 liên quan. - Không áp dụng cho yêu cầu, phản hồi hoặc lỗi.
Sự kiện tìm kiếm tệp gần đúng (thử nghiệm)
API phiên tìm kiếm tệp gần đúng phát thông báo cho từng truy vấn:
fuzzyFileSearch/sessionUpdated-{ sessionId, query, files }với các kết quả khớp hiện tại cho truy vấn đang hoạt động.fuzzyFileSearch/sessionCompleted-{ sessionId }sau khi hoàn tất lập chỉ mục và đối sánh cho truy vấn đó.
Sự kiện cảnh báo
configWarning-{ summary, details?, path?, range? }cho các sự cố cấu hình hoặc khởi tạo có thể khôi phục.warning-{ threadId?, message }cho các cảnh báo thời gian chạy không nghiêm trọng.
Sự kiện thiết lập môi trường cô lập Windows
windowsSandbox/setupCompleted-{ mode, success, error }được phát sau khi một yêu cầuwindowsSandbox/setupStarthoàn tất.
Sự kiện lượt
turn/started-{ turn }với mã lượt,itemstrống vàstatus: "inProgress".turn/completed-{ turn }, trong đóturn.statuslàcompleted,interruptedhoặcfailed; trường hợp thất bại có{ error: { message, codexErrorInfo?, additionalDetails? } }.turn/diff/updated-{ threadId, turnId, diff }với bản diff hợp nhất tổng hợp mới nhất trên mọi thay đổi tệp trong lượt.turn/plan/updated-{ turnId, explanation?, plan }bất cứ khi nào tác nhân chia sẻ hoặc thay đổi kế hoạch; mỗi mụcplanlà{ step, status }vớistatusnằm trongpending,inProgresshoặccompleted.hook/startedvàhook/completed-{ threadId, turnId?, run }khi một hook vòng đời đồng bộ bắt đầu và khi có bản tóm tắt lần chạy cuối cùng. Các thông báo này không được phát cho hook bất đồng bộ.model/safetyBuffering/updated-{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }khi một phản hồi đi vào bộ đệm an toàn tạm thời.model/rerouted-{ threadId, turnId, fromModel, toModel, reason }khi dịch vụ định tuyến một yêu cầu sang mô hình khác.model/verification-{ threadId, turnId, verifications }khi dịch vụ yêu cầu xác minh tài khoản bổ sung.thread/tokenUsage/updated- cập nhật mức sử dụng cho luồng đang hoạt động.
turn/diff/updated và turn/plan/updated hiện bao gồm các mảng items trống ngay cả khi các sự kiện mục được truyền trực tuyến. Hãy sử dụng thông báo item/* làm nguồn thông tin chính xác cho các mục của lượt.
Mục
ThreadItem là hợp kiểu có thẻ được mang trong phản hồi của lượt và thông báo item/*. Các loại mục phổ biến bao gồm:
userMessage-{id, content}, trong đócontentlà danh sách đầu vào của người dùng (text,imagehoặclocalImage).functionCallOutput-{id, name, namespace, output}dành cho đầu ra công cụ độc lập được cung cấp quaturn/start.toolOutput.namespacecó thể lànull.agentMessage-{id, text, phase?}chứa câu trả lời đã tích lũy của tác nhân. Khi có,phasesử dụng các giá trị truyền trên dây của Responses API (commentary,final_answer).plan-{id, text}chứa văn bản kế hoạch được đề xuất trong chế độ lập kế hoạch. Hãy coi mụcplancuối cùng từitem/completedlà nguồn có thẩm quyền.reasoning-{id, summary, content}, trong đósummarychứa các bản tóm tắt suy luận được truyền trực tiếp vàcontentchứa các khối suy luận thô.commandExecution-{id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.fileChange-{id, changes, status}mô tả các chỉnh sửa được đề xuất;changesliệt kê{path, kind, diff}.mcpToolCall-{id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Đối với các ứng dụng MCP đáng tin cậy,appContextcó thể bao gồmconnectorId,linkId,resourceUri,appName,templateIdvàactionNameổn định của trình kết nối. Các mục cũ đã lưu bền vững có thể không có siêu dữ liệu mới hơn. Hãy dùngappContext.resourceUrithay chomcpAppResourceUricấp cao nhất đã không còn được khuyến nghị.dynamicToolCall-{id, tool, arguments, status, contentItems?, success?, durationMs?}dành cho các lệnh gọi công cụ động do ứng dụng khách thực thi.collabToolCall-{id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.webSearch-{id, query, action?}dành cho các yêu cầu tìm kiếm web do tác nhân đưa ra.imageView-{id, path}được phát ra khi tác nhân gọi công cụ xem ảnh.enteredReviewMode-{id, review}được gửi khi trình đánh giá bắt đầu.exitedReviewMode-{id, review}được phát ra khi trình đánh giá hoàn tất.contextCompaction-{id}được phát ra khi Codex nén lịch sử hội thoại.
Đối với webSearch.action, hành động type có thể là search (query?, queries?), openPage (url?) hoặc findInPage (url?, pattern?).
App server không còn khuyến nghị thông báo thread/compacted kiểu cũ; hãy sử dụng mục contextCompaction thay thế.
Tất cả các mục đều phát hai sự kiện vòng đời dùng chung:
item/started- phát toàn bộitemkhi một đơn vị công việc mới bắt đầu;item.idkhớp vớiitemIdmà các delta sử dụng.item/completed- gửiitemcuối cùng khi công việc hoàn tất; hãy xem đây là trạng thái có thẩm quyền.
Delta của mục
item/agentMessage/delta- nối thêm văn bản được truyền trực tuyến cho thông báo của tác nhân.item/plan/delta- truyền trực tuyến nội dung kế hoạch được đề xuất. Mụcplancuối cùng có thể không hoàn toàn giống các delta được nối lại.item/reasoning/summaryTextDelta- truyền trực tuyến các bản tóm tắt suy luận dễ đọc;summaryIndextăng lên khi một phần tóm tắt mới mở ra.item/reasoning/summaryPartAdded- đánh dấu ranh giới giữa các phần tóm tắt suy luận.item/reasoning/textDelta- truyền trực tuyến văn bản suy luận thô (khi mô hình hỗ trợ).item/commandExecution/outputDelta- truyền trực tuyến stdout/stderr cho một lệnh; nối các delta theo thứ tự.item/fileChange/outputDelta- thông báo tương thích đã lỗi thời dành cho đầu ra văn bảnapply_patchkiểu cũ. Các phiên bản app-server hiện tại không còn phát thông báo này; hãy sử dụng các mụcfileChangevàturn/diff/updatedthay thế.
Lỗi
Nếu một lượt thất bại, máy chủ phát sự kiện error với { error: { message, codexErrorInfo?, additionalDetails? } } rồi kết thúc lượt bằng status: "failed". Khi có trạng thái HTTP từ thượng nguồn, trạng thái đó xuất hiện trong codexErrorInfo.httpStatusCode.
Các giá trị codexErrorInfo phổ biến bao gồm:
ContextWindowExceededUsageLimitExceededHttpConnectionFailed(lỗi thượng nguồn 4xx/5xx)ResponseStreamConnectionFailedResponseStreamDisconnectedResponseTooManyFailedAttemptsBadRequest,Unauthorized,SandboxError,InternalServerError,Other
Khi có trạng thái HTTP từ thượng nguồn, máy chủ chuyển tiếp trạng thái đó trong httpStatusCode trên biến thể codexErrorInfo tương ứng.
Phê duyệt
Tùy thuộc vào cài đặt Codex của người dùng, việc thực thi lệnh và thay đổi tệp có thể cần được phê duyệt. App-server gửi một yêu cầu JSON-RPC do máy chủ khởi tạo đến client, và client phản hồi bằng payload quyết định.
Quyết định thực thi lệnh:
accept,acceptForSession,decline,cancelhoặc{ "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.Quyết định thay đổi tệp:
accept,acceptForSession,decline,cancel.Các yêu cầu bao gồm
threadIdvàturnId- sử dụng chúng để giới hạn trạng thái UI trong cuộc hội thoại đang hoạt động.Máy chủ tiếp tục hoặc từ chối công việc và kết thúc mục bằng
item/completed.
Phê duyệt thực thi lệnh
Thứ tự thông báo:
item/startedhiển thị mụccommandExecutionđang chờ vớicommand,cwdvà các trường khác.item/commandExecution/requestApprovalbao gồmitemId,threadId,turnId,reasontùy chọn,commandtùy chọn,cwdtùy chọn,commandActionstùy chọn,proposedExecpolicyAmendmenttùy chọn,networkApprovalContexttùy chọn vàavailableDecisionstùy chọn. Khiinitialize.params.capabilities.experimentalApi = true, payload cũng có thể bao gồmadditionalPermissionsthử nghiệm, mô tả quyền truy cập môi trường cô lập được yêu cầu theo từng lệnh. Mọi đường dẫn hệ thống tệp bên trongadditionalPermissionsđều là đường dẫn tuyệt đối khi truyền qua dây.- Client phản hồi bằng một trong các quyết định phê duyệt thực thi lệnh nêu trên.
serverRequest/resolvedxác nhận rằng yêu cầu đang chờ đã được phản hồi hoặc xóa.item/completedtrả về mụccommandExecutioncuối cùng vớistatus: completed | failed | declined.
Khi có networkApprovalContext, lời nhắc dành cho quyền truy cập mạng được quản lý (không phải phê duyệt lệnh shell nói chung). Lược đồ v2 hiện tại cung cấp host và protocol đích; client nên hiển thị lời nhắc dành riêng cho mạng và không dựa vào việc command là bản xem trước lệnh shell có ý nghĩa đối với người dùng.
Codex nhóm các lời nhắc phê duyệt mạng đồng thời theo đích (host, giao thức và cổng). Vì vậy, app-server có thể gửi một lời nhắc để bỏ chặn nhiều yêu cầu đang xếp hàng đến cùng một đích, trong khi các cổng khác nhau trên cùng một máy chủ được xử lý riêng biệt.
Phê duyệt thay đổi tệp
Thứ tự thông báo:
item/startedphát một mụcfileChangevới cácchangesvàstatus: "inProgress"được đề xuất.item/fileChange/requestApprovalbao gồmitemId,threadId,turnId,reasontùy chọn vàgrantRoottùy chọn.- Client phản hồi bằng một trong các quyết định phê duyệt thay đổi tệp nêu trên.
serverRequest/resolvedxác nhận rằng yêu cầu đang chờ đã được phản hồi hoặc xóa.item/completedtrả về mụcfileChangecuối cùng vớistatus: completed | failed | declined.
tool/requestUserInput
Khi client phản hồi item/tool/requestUserInput, app-server phát serverRequest/resolved với { threadId, requestId }. Nếu yêu cầu đang chờ bị xóa do lượt bắt đầu, lượt hoàn tất hoặc lượt bị ngắt trước khi client phản hồi, máy chủ phát cùng thông báo đó cho quá trình dọn dẹp.
Tham số yêu cầu bao gồm autoResolutionMs dưới dạng thời gian chờ tính bằng mili giây nguyên hoặc
null. Khi có, client phía máy chủ có thể tự động xử lý lời nhắc sau
khoảng thời gian đó nếu người dùng không phản hồi.
Yêu cầu quyền
Công cụ request_permissions tích hợp sẵn gửi
item/permissions/requestApproval cùng với threadId, turnId, itemId,
environmentId, cwd, reason tùy chọn và các quyền mạng hoặc hệ thống tệp
được yêu cầu. Phản hồi bằng permissions chỉ chứa tập quyền con được cấp.
Đặt scope thành "session" để duy trì quyền cấp cho các lượt sau trong cùng
phiên; bỏ qua hoặc sử dụng "turn" để chỉ cấp quyền trong phạm vi lượt. Những quyền
không được yêu cầu sẽ bị bỏ qua.
Yêu cầu thu thập thông tin từ máy chủ MCP
Một máy chủ MCP có thể ngắt một lượt bằng mcpServer/elicitation/request. Yêu cầu
bao gồm threadId, turnId tùy chọn, serverName và một trong
các cấu trúc yêu cầu sau:
mode: "form"hoặcmode: "openai/form", vớimessagevàrequestedSchema.mode: "url", vớimessage,urlvàelicitationId.
Phản hồi bằng action: "accept" và content được yêu cầu, hoặc bằng
action: "decline" hay "cancel" cùng với content: null. Sau đó, app-server phát
serverRequest/resolved. Để nhận biến thể openai/form, hãy đăng ký bằng
initialize.params.capabilities.mcpServerOpenaiFormElicitation.
Lệnh gọi công cụ động (thử nghiệm)
dynamicTools trên thread/start cùng quy trình yêu cầu hoặc phản hồi item/tool/call tương ứng là các API thử nghiệm.
Tên công cụ động và tên namespace phải tuân theo các ràng buộc đặt tên của Responses API. Tránh các tên namespace dành riêng mà công cụ Codex tích hợp sẵn sử dụng.
Khi một công cụ động được gọi trong một lượt, app-server phát:
item/startedvớiitem.type = "dynamicToolCall",status = "inProgress", cùng vớitoolvàarguments.item/tool/calldưới dạng yêu cầu từ máy chủ đến client.- Payload phản hồi của client với các mục nội dung được trả về.
item/completedvớiitem.type = "dynamicToolCall",statuscuối cùng và mọi giá trịcontentItemshoặcsuccessđược trả về.
Phê duyệt lệnh gọi công cụ MCP (ứng dụng)
Các lệnh gọi công cụ của ứng dụng (trình kết nối) cũng có thể cần được phê duyệt. Khi lệnh gọi công cụ ứng dụng có tác dụng phụ, máy chủ có thể yêu cầu phê duyệt bằng tool/requestUserInput và các tùy chọn như Chấp nhận, Từ chối và Hủy. Chú thích công cụ mang tính phá hủy luôn kích hoạt phê duyệt ngay cả khi công cụ cũng công bố các gợi ý ít đặc quyền hơn. Nếu người dùng từ chối hoặc hủy, mục mcpToolCall liên quan sẽ hoàn tất với lỗi thay vì chạy công cụ.
Skill
Gọi một skill bằng cách đưa $<skill-name> vào dữ liệu đầu vào dạng văn bản của người dùng. Thêm một mục đầu vào skill (khuyến nghị) để máy chủ chèn đầy đủ hướng dẫn của skill thay vì dựa vào mô hình để phân giải tên.
{
"method": "turn/start",
"id": 101,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$skill-creator Add a new skill for triaging flaky CI."
},
{
"type": "skill",
"name": "skill-creator",
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md"
}
]
}
}Nếu bạn bỏ qua mục skill, mô hình vẫn sẽ phân tích dấu $<skill-name> và cố gắng định vị skill, điều này có thể làm tăng độ trễ.
Ví dụ:
$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage.Sử dụng skills/list để tìm nạp các skill hiện có (có thể giới hạn bằng cwds, với forceReload). Bạn cũng có thể bao gồm perCwdExtraUserRoots để quét thêm các đường dẫn tuyệt đối dưới dạng phạm vi user cho các giá trị cwd cụ thể. App-server bỏ qua những mục có cwd không xuất hiện trong cwds. skills/list có thể tái sử dụng kết quả được lưu vào bộ nhớ đệm theo từng cwd; đặt forceReload: true để làm mới từ ổ đĩa. Khi có, máy chủ đọc interface và dependencies từ SKILL.json.
{ "method": "skills/list", "id": 25, "params": {
"cwds": ["/Users/me/project", "/Users/me/other-project"],
"forceReload": true,
"perCwdExtraUserRoots": [
{
"cwd": "/Users/me/project",
"extraUserRoots": ["/Users/me/shared-skills"]
}
]
} }
{ "id": 25, "result": {
"data": [{
"cwd": "/Users/me/project",
"skills": [
{
"name": "skill-creator",
"description": "Create or update a Codex skill",
"enabled": true,
"interface": {
"displayName": "Skill Creator",
"shortDescription": "Create or update a Codex skill"
},
"dependencies": {
"tools": [
{
"type": "env_var",
"value": "GITHUB_TOKEN",
"description": "GitHub API token"
},
{
"type": "mcp",
"value": "github",
"transport": "streamable_http",
"url": "https://example.com/mcp"
}
]
}
}
],
"errors": []
}]
} }Máy chủ cũng phát thông báo skills/changed khi các tệp skill cục bộ đang được theo dõi thay đổi. Hãy xem đây là tín hiệu vô hiệu hóa và chạy lại skills/list với các tham số hiện tại khi cần.
Để bật hoặc tắt một skill theo đường dẫn:
{
"method": "skills/config/write",
"id": 26,
"params": {
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md",
"enabled": false
}
}Ứng dụng (trình kết nối)
Sử dụng app/installed để đọc ảnh chụp nhanh thời gian chạy mới nhất đã được commit của ứng dụng đã cài đặt.
Mỗi kết quả bao gồm id, runtimeName (hoặc null), trạng thái
enabled có hiệu lực và trạng thái callable của ứng dụng. Một ứng dụng chỉ có thể được gọi khi cấu hình
có hiệu lực bật ứng dụng đó và ít nhất một công cụ mà mô hình nhìn thấy tuân thủ
các chính sách ứng dụng và công cụ.
{
"method": "app/installed",
"id": 49,
"params": {
"threadId": "thread-1",
"forceRefresh": false
}
}
{
"id": 49,
"result": {
"apps": [
{
"id": "demo-app",
"runtimeName": "Demo App",
"enabled": true,
"callable": true
}
]
}
}Bỏ qua threadId để sử dụng cấu hình toàn cục thay cho cấu hình của luồng đã tải.
Đặt forceRefresh: true để làm mới ảnh chụp nhanh thời gian chạy của trình kết nối
trước khi đọc. Khi chính sách toàn cục hoặc không gian làm việc chặn quyền truy cập ứng dụng,
một ứng dụng được quan sát vẫn có thể xuất hiện với enabled và callable được đặt thành false.
Sử dụng app/list để tìm nạp các ứng dụng hiện có. Trong CLI/TUI, /apps là bộ chọn dành cho người dùng; trong các client tùy chỉnh, hãy gọi trực tiếp app/list. Mỗi mục bao gồm cả isAccessible (người dùng có thể sử dụng) và isEnabled (được bật trong config.toml), nhờ đó client có thể phân biệt trạng thái cài đặt/truy cập với trạng thái được bật cục bộ. Các mục ứng dụng cũng có thể bao gồm các trường branding, appMetadata và labels tùy chọn.
{ "method": "app/list", "id": 50, "params": {
"cursor": null,
"limit": 50,
"threadId": "thread-1",
"forceRefetch": false
} }
{ "id": 50, "result": {
"data": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"logoUrl": "https://example.com/demo-app.png",
"logoUrlDark": null,
"distributionChannel": null,
"branding": null,
"appMetadata": null,
"labels": null,
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
"isAccessible": true,
"isEnabled": true
}
],
"nextCursor": null
} }Nếu bạn cung cấp threadId, cơ chế kiểm soát tính năng ứng dụng (features.apps) sẽ sử dụng ảnh chụp nhanh cấu hình của luồng đó. Khi bị bỏ qua, app-server sử dụng cấu hình toàn cục mới nhất.
app/list trả về sau khi cả ứng dụng có thể truy cập và ứng dụng trong danh mục đã tải xong. Đặt forceRefetch: true để bỏ qua bộ nhớ đệm ứng dụng và tìm nạp dữ liệu mới. Các mục trong bộ nhớ đệm chỉ được thay thế khi quá trình làm mới thành công.
Máy chủ cũng phát thông báo app/list/updated mỗi khi một trong hai nguồn (ứng dụng có thể truy cập hoặc ứng dụng trong danh mục) hoàn tất tải. Mỗi thông báo bao gồm danh sách ứng dụng hợp nhất mới nhất.
{
"method": "app/list/updated",
"params": {
"data": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"logoUrl": "https://example.com/demo-app.png",
"logoUrlDark": null,
"distributionChannel": null,
"branding": null,
"appMetadata": null,
"labels": null,
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
"isAccessible": true,
"isEnabled": true
}
]
}
}Sử dụng app/read khi bạn đã biết mã ứng dụng và cần siêu dữ liệu ứng dụng thay
vì trạng thái thời gian chạy đã cài đặt. Truyền tối đa 100 appIds. Máy chủ chỉ giữ
lần xuất hiện đầu tiên của mỗi mã bị lặp và duy trì thứ tự đó trong cả
apps lẫn missingAppIds. Các ứng dụng không xác định hoặc không thể truy cập được trả về trong
missingAppIds mà không làm toàn bộ yêu cầu thất bại.
{
"method": "app/read",
"id": 52,
"params": {
"appIds": ["demo-app", "missing-app"],
"includeTools": true
}
}
{
"id": 52,
"result": {
"apps": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"iconUrl": null,
"iconUrlDark": null,
"distributionChannel": null,
"installUrl": null,
"pluginDisplayNames": [],
"toolSummaries": [
{
"name": "search",
"title": "Search",
"description": "Search the app.",
"isEnabled": true,
"disabledReason": null,
"isReadOnly": true
}
]
}
],
"missingAppIds": ["missing-app"]
}
}Đặt includeTools: true để yêu cầu các bản tóm tắt công cụ công khai chỉ dùng để hiển thị. Phản hồi
siêu dữ liệu không bao gồm trạng thái thời gian chạy của ứng dụng đã cài đặt và không cấp quyền cho
lệnh gọi công cụ; hãy sử dụng app/installed để kiểm tra trạng thái enabled và callable
có hiệu lực.
Gọi một ứng dụng bằng cách chèn $<app-slug> vào dữ liệu đầu vào dạng văn bản và thêm một mục đầu vào mention với đường dẫn app://<id> (khuyến nghị).
{
"method": "turn/start",
"id": 51,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$demo-app Pull the latest updates from the team."
},
{
"type": "mention",
"name": "Demo App",
"path": "app://demo-app"
}
]
}
}Ví dụ RPC cấu hình cho cài đặt ứng dụng
Sử dụng config/read, config/value/write và config/batchWrite để kiểm tra hoặc cập nhật các tùy chọn kiểm soát ứng dụng trong config.toml.
Đọc cấu trúc cấu hình ứng dụng có hiệu lực (bao gồm _default và các giá trị ghi đè theo từng công cụ):
{ "method": "config/read", "id": 60, "params": { "includeLayers": false } }
{ "id": 60, "result": {
"config": {
"apps": {
"_default": {
"enabled": true,
"destructive_enabled": true,
"open_world_enabled": true,
"approvals_reviewer": "user",
"default_tools_approval_mode": "auto"
},
"google_drive": {
"enabled": true,
"destructive_enabled": false,
"approvals_reviewer": "auto_review",
"default_tools_approval_mode": "prompt",
"tools": {
"files/delete": { "enabled": false, "approval_mode": "approve" }
}
}
}
}
} }apps._default.approvals_reviewer đặt trình đánh giá cho tất cả ứng dụng, trừ khi một
giá trị theo từng ứng dụng ghi đè lên nó. Khi cả hai đều bị bỏ qua, ứng dụng kế thừa
giá trị approvals_reviewer cấp cao nhất. apps._default.default_tools_approval_mode
đặt chế độ phê duyệt dự phòng cho các công cụ không có giá trị ghi đè theo ứng dụng hoặc theo công cụ.
Các yêu cầu về chế độ phê duyệt được quản lý ghi đè cài đặt chế độ phê duyệt của công cụ.
Cập nhật một cài đặt ứng dụng riêng lẻ:
{
"method": "config/value/write",
"id": 61,
"params": {
"keyPath": "apps.google_drive.default_tools_approval_mode",
"value": "prompt",
"mergeStrategy": "replace"
}
}Áp dụng nguyên tử nhiều chỉnh sửa ứng dụng:
{
"method": "config/batchWrite",
"id": 62,
"params": {
"edits": [
{
"keyPath": "apps._default.destructive_enabled",
"value": false,
"mergeStrategy": "upsert"
},
{
"keyPath": "apps.google_drive.tools.files/delete.approval_mode",
"value": "approve",
"mergeStrategy": "upsert"
}
]
}
}Phát hiện và nhập cấu hình tác nhân bên ngoài
Sử dụng externalAgentConfig/detect để khám phá các thành phần của tác nhân bên ngoài có thể di chuyển, sau đó chuyển các mục đã chọn đến externalAgentConfig/import.
Ví dụ phát hiện:
{ "method": "externalAgentConfig/detect", "id": 63, "params": {
"includeHome": true,
"cwds": ["/Users/me/project"]
} }
{ "id": 63, "result": {
"items": [
{
"itemType": "AGENTS_MD",
"description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
"cwd": "/Users/me/project"
},
{
"itemType": "SKILLS",
"description": "Copy skill folders from /Users/me/.claude/skills to /Users/me/.agents/skills.",
"cwd": null
}
]
} }Ví dụ nhập:
{ "method": "externalAgentConfig/import", "id": 64, "params": {
"migrationItems": [
{
"itemType": "AGENTS_MD",
"description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
"cwd": "/Users/me/project"
}
],
"source": "claude-code"
} }
{ "id": 64, "result": { "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868" } }Tham số nhập source cấp cao nhất tùy chọn dùng để gắn nhãn sản phẩm đã
tạo ra các mục di chuyển được chọn.
Máy chủ phát externalAgentConfig/import/progress khi từng loại mục hoàn tất,
và externalAgentConfig/import/completed sau khi tất cả quá trình nhập đồng bộ và chạy nền
hoàn tất. Các thông báo này bao gồm cùng importId từ
phản hồi và itemTypeResults với successes cùng failures theo từng loại.
Thông báo hoàn tất có thể đến ngay sau phản hồi hoặc sau khi các quá trình nhập từ xa chạy nền
hoàn tất.
{ "method": "externalAgentConfig/import/progress", "params": {
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"itemTypeResults": [
{
"itemType": "AGENTS_MD",
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
]
} }
{ "method": "externalAgentConfig/import/completed", "params": {
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"itemTypeResults": [
{
"itemType": "AGENTS_MD",
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
]
} }Đọc các lần nhập đã hoàn tất trước đó:
{ "method": "externalAgentConfig/import/readHistories", "id": 65 }
{ "id": 65, "result": { "data": [
{
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"completedAtMs": 1781784000000,
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
] } }Các giá trị itemType được hỗ trợ là AGENTS_MD, CONFIG, SKILLS, PLUGINS,
MCP_SERVER_CONFIG, SUBAGENTS, HOOKS, COMMANDS và SESSIONS. Đối với
các mục PLUGINS, details.plugins liệt kê từng marketplaceName và
pluginNames mà Codex có thể cố gắng di chuyển. Việc phát hiện chỉ trả về các mục vẫn còn
việc cần làm. Ví dụ: Codex bỏ qua quá trình di chuyển AGENTS khi AGENTS.md
đã tồn tại và không trống, còn quá trình nhập skill không ghi đè các
thư mục skill hiện có.
Khi phát hiện plugin từ .claude/settings.json, Codex đọc các
nguồn marketplace đã cấu hình từ extraKnownMarketplaces. Nếu enabledPlugins chứa
các plugin từ claude-plugins-official nhưng thiếu nguồn marketplace,
Codex suy ra anthropics/claude-plugins-official làm nguồn.
Điểm cuối xác thực
Bề mặt tài khoản/xác thực JSON-RPC cung cấp các phương thức yêu cầu/phản hồi cùng các thông báo do máy chủ khởi tạo (không có id). Sử dụng chúng để xác định trạng thái xác thực, bắt đầu hoặc hủy đăng nhập, đăng xuất, kiểm tra giới hạn tốc độ của ChatGPT và thông báo cho chủ sở hữu không gian làm việc về tín dụng đã cạn hoặc giới hạn mức sử dụng.
Chế độ xác thực
Codex hỗ trợ các chế độ xác thực sau. account/updated.authMode hiển thị chế độ đang hoạt động và bao gồm planType ChatGPT hiện tại khi có. account/read cũng báo cáo chi tiết về tài khoản và gói.
- API key (
apikey) - bên gọi cung cấp một OpenAI API key bằngtype: "apiKey"và Codex lưu khóa đó cho các yêu cầu API. - Do ChatGPT quản lý (
chatgpt) - Codex quản lý quy trình OAuth của ChatGPT, duy trì token và tự động làm mới chúng. Bắt đầu bằngtype: "chatgpt"cho quy trình trên trình duyệt hoặctype: "chatgptDeviceCode"cho quy trình mã thiết bị. - Token ChatGPT bên ngoài (
chatgptAuthTokens) - đang ở giai đoạn thử nghiệm và dành cho các ứng dụng máy chủ đã quản lý vòng đời xác thực ChatGPT của người dùng. Ứng dụng máy chủ cung cấp trực tiếpaccessToken,chatgptAccountIdvàchatgptPlanTypetùy chọn, đồng thời phải làm mới token khi được yêu cầu. - Amazon Bedrock -
account/readbáo cáo các tài khoản Bedrock dưới dạngtype: "amazonBedrock"và cho biết thông tin xác thực đến từ Bedrock API key do Codex quản lý (credentialSource: "codexManaged") hay chuỗi thông tin xác thực AWS bên ngoài (credentialSource: "awsManaged").account/updated.authModesử dụngbedrockApiKeycho các Bedrock API key do Codex quản lý.
Tổng quan về API
account/read- tìm nạp thông tin tài khoản hiện tại; có thể làm mới token.account/login/start- bắt đầu đăng nhập (apiKey,chatgpt,chatgptDeviceCodehoặcchatgptAuthTokensthử nghiệm).account/login/completed(thông báo) - được phát khi một lần đăng nhập hoàn tất (thành công hoặc có lỗi).account/login/cancel- hủy một lần đăng nhập ChatGPT được quản lý đang chờ bằngloginId.account/logout- đăng xuất; kích hoạtaccount/updated.account/updated(thông báo) - được phát bất cứ khi nào chế độ xác thực thay đổi (authMode:apikey,chatgpt,chatgptAuthTokens,agentIdentity,personalAccessToken,bedrockApiKeyhoặcnull) và bao gồmplanTypekhi có.account/chatgptAuthTokens/refresh(yêu cầu máy chủ) - yêu cầu token ChatGPT mới được quản lý bên ngoài sau lỗi ủy quyền.account/rateLimits/read- tìm nạp giới hạn tốc độ của ChatGPT.account/rateLimits/updated(thông báo) - được phát bất cứ khi nào giới hạn tốc độ ChatGPT của người dùng thay đổi.account/sendAddCreditsNudgeEmail- yêu cầu ChatGPT gửi email cho chủ sở hữu không gian làm việc về tín dụng đã cạn hoặc giới hạn mức sử dụng đã đạt tới.account/rateLimitResetCredit/consume- sử dụng một lần đặt lại giới hạn tốc độ đã nhận được bằng giá trịidempotencyKeydo bên gọi cung cấp.account/usage/read- tìm nạp bản tóm tắt hoạt động token của tài khoản ChatGPT và các nhóm dữ liệu hằng ngày.account/workspaceMessages/read- tìm nạp các thông báo đang hoạt động của không gian làm việc, bao gồm tiêu đề thông báo khi có.mcpServer/oauthLogin/completed(thông báo) - được phát sau khi quy trìnhmcpServer/oauth/loginhoàn tất; payload bao gồm{ name, threadId, success, error? }.threadIdcó thể lànullcho các quy trình OAuth trong phạm vi ứng dụng hoặc plugin.mcpServer/startupStatus/updated(thông báo) - được phát khi trạng thái khởi động của một máy chủ MCP đã cấu hình thay đổi; payload bao gồm{ threadId, name, status, error, failureReason }.threadIdlànullđối với quá trình khởi động trong phạm vi ứng dụng. Khi khởi động thất bại,failureReason: "reauthenticationRequired"có nghĩa là thông tin xác thực OAuth đã lưu đã hết hạn và không thể làm mới, vì vậy client nên cung cấp tùy chọn kết nối lại máy chủ.
1) Kiểm tra trạng thái xác thực
Yêu cầu:
{ "method": "account/read", "id": 1, "params": { "refreshToken": false } }Ví dụ phản hồi:
{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": false } }{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": true } }{
"id": 1,
"result": { "account": { "type": "apiKey" }, "requiresOpenaiAuth": true }
}{
"id": 1,
"result": {
"account": {
"type": "amazonBedrock",
"credentialSource": "codexManaged"
},
"requiresOpenaiAuth": false
}
}{
"id": 1,
"result": {
"account": {
"type": "amazonBedrock",
"credentialSource": "awsManaged"
},
"requiresOpenaiAuth": false
}
}{
"id": 1,
"result": {
"account": {
"type": "chatgpt",
"email": "user@example.com",
"planType": "pro"
},
"requiresOpenaiAuth": true
}
}Lưu ý về trường:
refreshToken(boolean): đặttrueđể buộc làm mới token trong chế độ ChatGPT được quản lý. Trong chế độ token bên ngoài (chatgptAuthTokens), app-server bỏ qua cờ này.emaillànullkhi tài khoản ChatGPT không có địa chỉ email.requiresOpenaiAuthphản ánh nhà cung cấp đang hoạt động; khi làfalse, Codex có thể chạy mà không cần thông tin xác thực OpenAI.- Amazon Bedrock báo cáo
credentialSource: "codexManaged"khi sử dụng một Bedrock API key do Codex quản lý. Hệ thống báo cáocredentialSource: "awsManaged"cho đường dẫn thông tin xác thực AWS bên ngoài. Giá trị này xác định nguồn thông tin xác thực đã chọn; không xác thực rằng chuỗi thông tin xác thực AWS có thể phân giải được thông tin xác thực.
2) Đăng nhập bằng API key
- Gửi:
{
"method": "account/login/start",
"id": 2,
"params": { "type": "apiKey", "apiKey": "sk-..." }
}- Kết quả mong đợi:
{ "id": 2, "result": { "type": "apiKey" } }- Thông báo:
{
"method": "account/login/completed",
"params": { "loginId": null, "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "apikey", "planType": null }
}3) Đăng nhập bằng ChatGPT (quy trình trên trình duyệt)
- Bắt đầu:
{
"method": "account/login/start",
"id": 3,
"params": {
"type": "chatgpt",
"useHostedLoginSuccessPage": true,
"appBrand": "chatgpt"
}
} Theo mặc định, một lệnh callback thành công trên trình duyệt sẽ chuyển hướng đến trang thành công cục bộ.
Đặt useHostedLoginSuccessPage: true để sử dụng trang thành công được lưu trữ khi
không cần thiết lập tổ chức. Khi bật trang thành công được lưu trữ, appBrand
có thể là "codex" hoặc "chatgpt"; các giá trị bị bỏ qua hoặc là null sẽ mặc định thành
"codex".
{
"id": 3,
"result": {
"type": "chatgpt",
"loginId": "<uuid>",
"authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
}
}- Mở
authUrltrong trình duyệt; app-server lưu trữ callback cục bộ. - Chờ thông báo:
{
"method": "account/login/completed",
"params": { "loginId": "<uuid>", "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgpt", "planType": "plus" }
}3b) Đăng nhập bằng ChatGPT (quy trình mã thiết bị)
Sử dụng quy trình này khi client của bạn quản lý trải nghiệm đăng nhập hoặc khi callback trên trình duyệt không ổn định.
- Bắt đầu:
{
"method": "account/login/start",
"id": 4,
"params": { "type": "chatgptDeviceCode" }
} {
"id": 4,
"result": {
"type": "chatgptDeviceCode",
"loginId": "<uuid>",
"verificationUrl": "https://auth.openai.com/codex/device",
"userCode": "ABCD-1234"
}
}- Hiển thị
verificationUrlvàuserCodecho người dùng; frontend quản lý UX. - Chờ thông báo:
{
"method": "account/login/completed",
"params": { "loginId": "<uuid>", "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgpt", "planType": "plus" }
}3c) Đăng nhập bằng token ChatGPT được quản lý bên ngoài (chatgptAuthTokens)
Chỉ sử dụng chế độ thử nghiệm này khi ứng dụng máy chủ quản lý vòng đời xác thực ChatGPT của người dùng và cung cấp token trực tiếp. Client phải đặt capabilities.experimentalApi = true trong initialize trước khi sử dụng kiểu đăng nhập này.
- Gửi:
{
"method": "account/login/start",
"id": 7,
"params": {
"type": "chatgptAuthTokens",
"accessToken": "<jwt>",
"chatgptAccountId": "org-123",
"chatgptPlanType": "business"
}
}- Kết quả mong đợi:
{ "id": 7, "result": { "type": "chatgptAuthTokens" } }- Thông báo:
{
"method": "account/login/completed",
"params": { "loginId": null, "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgptAuthTokens", "planType": "business" }
}Khi máy chủ nhận được 401 Unauthorized, máy chủ có thể yêu cầu token đã làm mới từ ứng dụng máy chủ:
{
"method": "account/chatgptAuthTokens/refresh",
"id": 8,
"params": { "reason": "unauthorized", "previousAccountId": "org-123" }
}
{ "id": 8, "result": { "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } }Máy chủ thử lại yêu cầu ban đầu sau khi nhận được phản hồi làm mới thành công. Yêu cầu hết thời gian chờ sau khoảng 10 giây.
4) Hủy đăng nhập ChatGPT
{ "method": "account/login/cancel", "id": 4, "params": { "loginId": "<uuid>" } }
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": false, "error": "..." } }5) Đăng xuất
{ "method": "account/logout", "id": 5 }
{ "id": 5, "result": {} }
{ "method": "account/updated", "params": { "authMode": null, "planType": null } }6) Giới hạn tốc độ (ChatGPT)
{ "method": "account/rateLimits/read", "id": 6 }
{ "id": 6, "result": {
"rateLimits": {
"limitId": "codex",
"limitName": null,
"primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
"secondary": null,
"rateLimitReachedType": null
},
"rateLimitsByLimitId": {
"codex": {
"limitId": "codex",
"limitName": null,
"primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
"secondary": null,
"rateLimitReachedType": null
},
"codex_other": {
"limitId": "codex_other",
"limitName": "codex_other",
"primary": { "usedPercent": 42, "windowDurationMins": 60, "resetsAt": 1730950800 },
"secondary": null,
"rateLimitReachedType": null
}
},
"rateLimitResetCredits": {
"availableCount": 2,
"credits": [{
"id": "RateLimitResetCredit_1",
"resetType": "codexRateLimits",
"status": "available",
"grantedAt": 1781654400,
"expiresAt": 1784246400,
"title": "Rate-limit reset",
"description": "Reset an eligible Codex rate-limit window."
}]
}
} }
{ "method": "account/rateLimits/updated", "params": {
"rateLimits": {
"limitId": "codex",
"primary": { "usedPercent": 31, "windowDurationMins": 15, "resetsAt": 1730948100 }
}
} }Lưu ý về trường:
rateLimitslà chế độ xem một nhóm duy nhất có khả năng tương thích ngược.rateLimitsByLimitId(khi có) là chế độ xem nhiều nhóm được lập khóa theolimit_idđược đo lường (ví dụ:codex).limitIdlà mã định danh nhóm được đo lường.limitNamelà nhãn tùy chọn dành cho người dùng của nhóm.usedPercentlà mức sử dụng hiện tại trong cửa sổ hạn ngạch.windowDurationMinslà độ dài cửa sổ hạn ngạch.resetsAtlà dấu thời gian Unix (giây) cho lần đặt lại tiếp theo.planTypeđược bao gồm khi máy chủ trả về gói ChatGPT được liên kết với một nhóm.creditsđược bao gồm khi máy chủ trả về chi tiết tín dụng còn lại của không gian làm việc.rateLimitReachedTypexác định trạng thái giới hạn do máy chủ phân loại khi đã đạt đến một giới hạn.rateLimitResetCreditschứa số lần đặt lại đã nhận được hiện có khi dịch vụ cung cấp; nếu không, giá trị lànull.rateLimitResetCredits.creditslànullkhi chỉ biết số lượng. Mảng trống có nghĩa là dịch vụ đã tìm nạp thông tin chi tiết và không trả về tín dụng khả dụng nào. Dịch vụ có thể giới hạn số hàng chi tiết, vì vậyavailableCountlà giá trị có thẩm quyền.- Mỗi hàng chi tiết bao gồm một
idkhông rõ nghĩa,resetType,status,grantedAt,expiresAt(có thể lànull),title(có thể lànull) vàdescription(có thể lànull). - Tìm nạp
account/rateLimits/readsau khi sử dụng một lần đặt lại.
7) Mức sử dụng token (ChatGPT)
Sử dụng account/usage/read để tìm nạp các trường tóm tắt hoạt động token của ChatGPT và
các nhóm dữ liệu hằng ngày tùy chọn.
{ "method": "account/usage/read", "id": 7 }
{ "id": 7, "result": {
"summary": {
"lifetimeTokens": 1234567,
"peakDailyTokens": 45678,
"longestRunningTurnSec": 540,
"currentStreakDays": 8,
"longestStreakDays": 14
},
"dailyUsageBuckets": [
{ "startDate": "2026-06-18", "tokens": 12345 }
]
} }Lưu ý về trường:
- Các giá trị
summarycó thể lànullkhi dịch vụ chưa trả về chỉ số đó. dailyUsageBucketscó thể lànull; khi có, mỗi nhóm bao gồmstartDatevàtokens.- Điểm cuối yêu cầu xác thực dựa trên các dịch vụ Codex. ChatGPT, token ChatGPT bên ngoài, danh tính tác nhân và xác thực bằng token truy cập cá nhân đều hoạt động; xác thực chỉ bằng API key và xác thực Bedrock thì không.
8) Các lần đặt lại giới hạn tốc độ đã nhận được (ChatGPT)
Sử dụng account/rateLimitResetCredit/consume để sử dụng một lần đặt lại đã nhận được.
{ "method": "account/rateLimitResetCredit/consume", "id": 8, "params": { "idempotencyKey": "8ae96ff3-3425-4f4c-8772-b6fd61502868", "creditId": "RateLimitResetCredit_1" } }
{ "id": 8, "result": { "outcome": "reset" } }Lưu ý về trường:
idempotencyKeykhông được để trống. Sử dụng một UUID cho mỗi lần thử quy đổi logic và dùng lại cùng giá trị khi thử lại lần đó.creditIdlà tùy chọn. Khi được cung cấp, giá trị này phải là một mã không rõ nghĩa, không trống từaccount/rateLimits/read. Khi bị bỏ qua, dịch vụ chọn tín dụng khả dụng tiếp theo.resetcó nghĩa là một tín dụng đã được sử dụng.alreadyRedeemedcó nghĩa là cùng một lần quy đổi đã hoàn tất trước đó. Hãy xem đây là thành công có tính lũy đẳng và làm mới giới hạn tài khoản.nothingToResetcó nghĩa là không có cửa sổ giới hạn tốc độ đủ điều kiện để đặt lại.noCreditcó nghĩa là tài khoản không còn tín dụng đặt lại đã nhận được nào.- Tìm nạp
account/rateLimits/readsau khi sử dụng một lần đặt lại thay vì suy luận các cửa sổ đã cập nhật từ phản hồi này.
9) Thông báo cho chủ sở hữu không gian làm việc về một giới hạn
Sử dụng account/sendAddCreditsNudgeEmail để yêu cầu ChatGPT gửi email cho chủ sở hữu không gian làm việc khi tín dụng đã cạn hoặc giới hạn mức sử dụng đã đạt tới.
{ "method": "account/sendAddCreditsNudgeEmail", "id": 9, "params": { "creditType": "credits" } }
{ "id": 9, "result": { "status": "sent" } }Sử dụng creditType: "credits" khi tín dụng của không gian làm việc đã cạn hoặc creditType: "usage_limit" khi đã đạt đến giới hạn mức sử dụng của không gian làm việc. Nếu chủ sở hữu đã được thông báo gần đây, trạng thái phản hồi là cooldown_active.
10) Thông báo của không gian làm việc (ChatGPT)
Sử dụng account/workspaceMessages/read để tìm nạp các thông báo đang hoạt động cho
không gian làm việc hiện tại, bao gồm tiêu đề thông báo khi có.
{ "method": "account/workspaceMessages/read", "id": 10 }
{ "id": 10, "result": { "featureEnabled": true, "messages": [
{ "messageId": "msg_123", "messageType": "headline", "messageBody": "Workspace maintenance starts at 5pm.", "createdAt": 1781395200, "archivedAt": null }
] } }