Hook
Chạy các tập lệnh có tính xác định trong vòng đời Codex
Hook là một khung mở rộng dành cho Codex. Hook cho phép bạn chèn các tập lệnh của riêng mình vào vòng lặp tác nhân, qua đó hỗ trợ các tính năng như:
- Gửi cuộc trò chuyện đến một công cụ ghi nhật ký/phân tích tùy chỉnh
- Quét prompt của nhóm để ngăn việc vô tình dán API key
- Tóm tắt các cuộc trò chuyện để tự động tạo bộ nhớ lâu dài
- Chạy một bước kiểm tra xác thực tùy chỉnh khi một lượt trò chuyện dừng lại để bảo đảm tuân thủ các tiêu chuẩn
- Tùy chỉnh prompt khi ở trong một thư mục nhất định
Các hành vi trong thời gian chạy cần lưu ý:
- Tất cả hook khớp từ nhiều tệp đều sẽ chạy.
- Nhiều hook lệnh cùng khớp với một sự kiện được khởi chạy đồng thời, vì vậy một hook không thể ngăn hook khớp khác bắt đầu.
- Hook lệnh không được quản lý phải được xem xét và tin cậy trước khi chạy.
Hook chạy tại những thời điểm khác nhau trong cuộc trò chuyện:
| Thời điểm | Hook |
|---|---|
| Trong một lượt | PreToolUse, PermissionRequest, PostToolUse, PreCompact, PostCompact, UserPromptSubmit, SubagentStop, Stop |
| Khi phiên hoặc tác nhân phụ bắt đầu | SessionStart, SubagentStart |
| Khi luồng chính kết thúc | SessionEnd (không chạy cho tác nhân phụ) |
Nơi Codex tìm hook
Codex phát hiện hook bên cạnh các lớp cấu hình đang hoạt động ở một trong hai dạng sau:
hooks.json- các bảng
[hooks]nội tuyến bên trongconfig.toml
Plugin đã cài đặt cũng có thể đóng gói cấu hình vòng đời thông qua tệp kê khai
plugin hoặc một tệp hooks/hooks.json mặc định. Xem Xây dựng
plugin để biết các quy tắc
đóng gói plugin.
Trong thực tế, bốn vị trí hữu ích nhất là:
~/.codex/hooks.json~/.codex/config.toml<repo>/.codex/hooks.json<repo>/.codex/config.toml
Nếu có nhiều nguồn hook, Codex sẽ tải tất cả hook khớp.
Các lớp cấu hình có độ ưu tiên cao hơn không thay thế hook ở lớp có độ ưu tiên thấp hơn.
Nếu một lớp chứa cả hooks.json và [hooks] nội tuyến, Codex
sẽ hợp nhất chúng và cảnh báo khi khởi động. Nên dùng một cách biểu diễn cho mỗi lớp.
Codex cũng có thể phát hiện hook được đóng gói cùng các plugin đang bật. Hook đi kèm plugin được tải cùng các nguồn hook khác và sử dụng cùng quy trình xem xét độ tin cậy như các hook không được quản lý khác.
Hook cục bộ của dự án chỉ được tải khi lớp .codex/ của dự án được tin cậy. Trong
các dự án không đáng tin cậy, Codex vẫn tải hook người dùng và hệ thống từ các
lớp cấu hình đang hoạt động tương ứng.
Xem xét và tin cậy hook
Codex liệt kê các hook đã cấu hình trước khi quyết định hook nào có thể chạy. Trước khi một hook lệnh không được quản lý có thể chạy, Codex yêu cầu bạn xem xét và tin cậy đúng định nghĩa hook đó. Codex ghi nhận trạng thái tin cậy dựa trên hàm băm hiện tại của hook, vì vậy hook mới hoặc đã thay đổi sẽ được đánh dấu để xem xét và bị bỏ qua cho đến khi được tin cậy.
Dùng /hooks trong CLI để kiểm tra nguồn hook, xem xét hook mới hoặc đã thay đổi,
tin cậy hook hoặc vô hiệu hóa từng hook không được quản lý. Nếu cần xem xét hook khi
khởi động, Codex sẽ in cảnh báo yêu cầu bạn mở /hooks.
Hook được quản lý từ nguồn hệ thống, MDM, đám mây hoặc requirements.toml được đánh dấu
là được quản lý, được chính sách tin cậy và không thể bị vô hiệu hóa từ trình duyệt hook của người dùng.
Đối với tác vụ tự động hóa dùng một lần đã kiểm định nguồn hook bên ngoài Codex, hãy truyền
--dangerously-bypass-hook-trust để chạy các hook đang bật mà không yêu cầu
trạng thái tin cậy hook được lưu cho lần gọi đó.
Cấu trúc cấu hình
Hook được tổ chức thành ba cấp:
- Một sự kiện hook như
PreToolUse,PostToolUse,PreCompact,SubagentStarthoặcStop - Một nhóm đối sánh quyết định thời điểm sự kiện đó khớp
- Một hoặc nhiều trình xử lý hook chạy khi nhóm đối sánh khớp
{
"description": "Optional lifecycle hooks for this workspace.",
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_start.py",
"statusMessage": "Loading session notes",
"additionalContextLimit": 5000
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_end.py",
"timeout": 3
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py\"",
"statusMessage": "Checking Bash command"
}
]
}
],
"PermissionRequest": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/permission_request.py\"",
"statusMessage": "Checking approval request"
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use_review.py\"",
"statusMessage": "Reviewing Bash output"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/user_prompt_submit_data_flywheel.py\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/stop_continue.py\"",
"timeout": 30
}
]
}
]
}
}Lưu ý:
descriptionlà siêu dữ liệu cấp cao nhất không bắt buộc dành cho tệphooks.json. Nó không thay đổi hook nào sẽ chạy.timeoutđược tính bằng giây.- Nếu bỏ qua
timeout, Codex sử dụng600giây cho hầu hết hook.SessionEndmặc định dùng1giây và hỗ trợ tối đa3giây.
statusMessagelà tùy chọn.additionalContextLimitđặt lượngadditionalContextmà một hook lệnh có thể gửi đến mô hình trước khi Codex lưu toàn bộ văn bản vào ổ đĩa và thay vào đó gửi một bản xem trước ngắn hơn. Xem Đầu ra hook lớn.commandWindowslà phần ghi đè lệnh chỉ dành cho Windows và không bắt buộc. Trong TOML, hãy dùngcommand_windowshoặccommandWindows.- Tùy chọn
asyncđược phân tích cú pháp, nhưng hook lệnh bất đồng bộ chưa được hỗ trợ. - Hiện chỉ các trình xử lý
type: "command"chạy. Các trình xử lýpromptvàagentđược phân tích cú pháp nhưng bị bỏ qua. - Lệnh chạy với
cwdcủa phiên làm thư mục làm việc. - Đối với hook cục bộ của kho lưu trữ, nên phân giải từ thư mục gốc git thay vì dùng một
đường dẫn tương đối như
.codex/hooks/.... Codex có thể được khởi động từ một thư mục con, còn đường dẫn dựa trên thư mục gốc git sẽ giữ vị trí hook ổn định.
TOML nội tuyến tương đương trong config.toml:
[[hooks.SessionStart]]
matcher = "^compact$"
[[hooks.SessionStart.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/session_start.py"'
additionalContextLimit = 5000
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py"'
timeout = 30
statusMessage = "Checking Bash command"
[[hooks.PostToolUse]]
matcher = "^Bash$"
[[hooks.PostToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use_review.py"'
timeout = 30
statusMessage = "Reviewing Bash output"Tắt hook
Hook được bật theo mặc định. Để tắt hook trong config.toml, hãy đặt:
[features]
hooks = falseDùng hooks làm khóa tính năng chuẩn. codex_hooks vẫn hoạt động dưới dạng
bí danh không còn được khuyến nghị. Quản trị viên có thể buộc tắt hook theo cùng cách trong
requirements.toml bằng [features].hooks = false.
Hook được quản lý từ requirements.toml
Các yêu cầu do doanh nghiệp quản lý cũng có thể định nghĩa hook nội tuyến trong [hooks].
Điều này hữu ích khi quản trị viên muốn bắt buộc cấu hình hook trong khi
phân phối các tập lệnh thực tế qua MDM hoặc một hệ thống quản lý thiết bị khác.
Để bắt buộc hook được quản lý ngay cả với người dùng đã tắt hook cục bộ, hãy ghim
[features].hooks = true trong requirements.toml cùng với [hooks]. Để bỏ qua
hook của người dùng, dự án, phiên và plugin nhưng vẫn cho phép hook do quản trị viên
quản lý, hãy đặt allow_managed_hooks_only = true.
allow_managed_hooks_only = true
[features]
hooks = true
[hooks]
managed_dir = "/enterprise/hooks"
windows_managed_dir = 'C:\enterprise\hooks'
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = "python3 /enterprise/hooks/pre_tool_use_policy.py"
command_windows = 'py -3 C:\enterprise\hooks\pre_tool_use_policy.py'
timeout = 30
statusMessage = "Checking managed Bash command"Lưu ý về hook được quản lý:
managed_dirđược dùng trên macOS và Linux.windows_managed_dirđược dùng trên Windows.- Codex không phân phối các tập lệnh trong
managed_dir; công cụ doanh nghiệp của bạn phải cài đặt và cập nhật chúng riêng. - Lệnh hook được quản lý nên dùng đường dẫn tập lệnh tuyệt đối trong thư mục được quản lý đã cấu hình.
allow_managed_hooks_only = truebỏ qua hook từ nguồn người dùng, dự án, phiên và plugin, nhưng vẫn tải hook được quản lý từrequirements.tomlvà các lớp cấu hình được quản lý khác.
Hook đi kèm plugin
Khi một plugin được bật, Codex có thể tải hook vòng đời từ plugin đó cùng với hook người dùng, dự án và được quản lý.
Theo mặc định, Codex tìm hooks/hooks.json bên trong thư mục gốc plugin. Tệp kê khai plugin
có thể ghi đè giá trị mặc định đó bằng một mục hooks trong
.codex-plugin/plugin.json. Mục trong tệp kê khai có thể là một đường dẫn có tiền tố ./, một
mảng đường dẫn có tiền tố ./, một đối tượng hook nội tuyến hoặc một mảng
đối tượng hook nội tuyến.
{
"name": "repo-policy",
"hooks": "./hooks/hooks.json"
}Đường dẫn hook trong tệp kê khai được phân giải tương đối với thư mục gốc plugin và phải nằm
trong thư mục gốc đó. Nếu tệp kê khai định nghĩa hooks, Codex sẽ dùng các mục trong tệp kê khai
đó thay cho hooks/hooks.json mặc định.
Lệnh hook plugin nhận các biến môi trường sau:
PLUGIN_ROOTlà phần mở rộng riêng của Codex trỏ đến thư mục gốc của plugin đã cài đặt.PLUGIN_DATAlà phần mở rộng riêng của Codex trỏ đến thư mục dữ liệu có thể ghi của plugin.- Codex cũng đặt
CLAUDE_PLUGIN_ROOTvàCLAUDE_PLUGIN_DATAđể tương thích với các hook plugin hiện có.
Hook plugin sử dụng cùng lược đồ sự kiện như các hook khác. Việc cài đặt hoặc bật một plugin không tự động khiến hook của plugin được tin cậy; Codex bỏ qua hook đi kèm plugin cho đến khi bạn xem xét và tin cậy định nghĩa hook hiện tại.
Mẫu đối sánh
Trường matcher là một chuỗi biểu thức chính quy lọc thời điểm hook kích hoạt. Dùng "*",
"" hoặc bỏ hoàn toàn matcher để khớp mọi lần xuất hiện của một
sự kiện được hỗ trợ.
Chỉ một số sự kiện Codex hiện tại tuân theo matcher:
| Sự kiện | Nội dung được matcher lọc |
Lưu ý |
|---|---|---|
PermissionRequest |
tên công cụ | Phạm vi hỗ trợ gồm Bash, apply_patch* và tên công cụ MCP |
PostToolUse |
tên công cụ | Xem Phạm vi công cụ |
PostCompact |
tác nhân kích hoạt nén | Các giá trị là manual hoặc auto |
PreCompact |
tác nhân kích hoạt nén | Các giá trị là manual hoặc auto |
PreToolUse |
tên công cụ | Xem Phạm vi công cụ |
SessionEnd |
lý do kết thúc | Hiện chỉ có other |
SessionStart |
nguồn khởi động | Các giá trị là startup, resume, clear và compact |
SubagentStart |
loại tác nhân phụ | Giá trị phụ thuộc vào tác nhân phụ khởi động |
SubagentStop |
loại tác nhân phụ | Giá trị phụ thuộc vào tác nhân phụ dừng |
UserPromptSubmit |
không được hỗ trợ | Mọi matcher đã cấu hình đều bị bỏ qua cho sự kiện này |
Stop |
không được hỗ trợ | Mọi matcher đã cấu hình đều bị bỏ qua cho sự kiện này |
*Đối với apply_patch, các giá trị matcher cũng có thể dùng Edit hoặc Write.
Ví dụ:
Bash^apply_patch$Edit|Writemcp__filesystem__read_filemcp__filesystem__.*startup|resume|clear|compactmanual|auto
Phạm vi công cụ
PreToolUse và PostToolUse có thể quan sát nhiều loại lệnh gọi hơn lệnh shell và MCP. Hầu hết
công cụ hàm cục bộ sử dụng cùng đường dẫn hook, vì vậy bạn có thể đối sánh tên công cụ,
kiểm tra đối số JSON và, với PreToolUse, chặn hoặc viết lại lệnh gọi.
| Đường dẫn công cụ | PreToolUse |
PostToolUse |
Lưu ý |
|---|---|---|---|
| Lệnh shell | Có | Có | Đối sánh dưới dạng Bash. |
Thực thi hợp nhất (exec_command) |
Có | Có | Đối sánh dưới dạng Bash. Một lần thăm dò write_stdin sau đó có thể chuyển PostToolUse của lệnh ban đầu khi lệnh hoàn tất. |
apply_patch |
Có | Có | Đối sánh dưới dạng apply_patch, Edit hoặc Write. |
| Công cụ MCP | Có | Có | Đối sánh tên công cụ MCP, chẳng hạn như mcp__filesystem__read_file. |
| Công cụ hàm cục bộ khác | Có | Có | Đối sánh tên công cụ hàm, chẳng hạn như update_plan. spawn_agent cũng khớp với Agent. |
Công cụ được lưu trữ, như WebSearch |
Không | Không | Các công cụ này không sử dụng đường dẫn hook công cụ hàm cục bộ. |
write_stdin là lớp truyền tải cho một phiên thực thi hợp nhất hiện có. Nó không chạy lại
PreToolUse khi gửi dữ liệu đầu vào hoặc thăm dò một lệnh đã vượt qua
PreToolUse.
Một số đường dẫn công cụ chuyên biệt có thể không dùng đường dẫn hook mặc định. Hãy xem hook công cụ như một lớp bảo vệ hữu ích, không phải ranh giới thực thi hoàn chỉnh.
Các trường đầu vào chung
Mỗi hook lệnh nhận một đối tượng JSON trên stdin.
Đây là các trường dùng chung mà bạn thường sử dụng:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
session_id |
string |
ID phiên Codex hiện tại. Hook tác nhân phụ dùng ID phiên cha. |
transcript_path |
string | null |
Đường dẫn đến tệp bản ghi phiên, nếu có |
cwd |
string |
Thư mục làm việc của phiên |
hook_event_name |
string |
Tên sự kiện hook hiện tại |
model |
string |
Phần mở rộng riêng của Codex. Slug mô hình đang hoạt động |
Hook theo phạm vi lượt liệt kê turn_id dưới dạng phần mở rộng riêng của Codex trong
các bảng dành riêng cho sự kiện tương ứng.
SessionStart, PreToolUse, PermissionRequest, PostToolUse,
UserPromptSubmit, SubagentStart, SubagentStop và Stop cũng bao gồm
permission_mode, mô tả chế độ quyền hiện tại là default,
acceptEdits, plan, dontAsk hoặc bypassPermissions.
transcript_path trỏ đến bản ghi cuộc trò chuyện để tiện sử dụng, nhưng
định dạng bản ghi không phải là giao diện ổn định cho hook và có thể thay đổi theo thời gian.
Nếu cần toàn bộ định dạng truyền, hãy xem Lược đồ.
Các trường đầu ra chung
SessionStart, PreCompact, PostCompact, UserPromptSubmit,
SubagentStop và Stop hỗ trợ các trường JSON dùng chung sau. SubagentStart
chấp nhận cùng cấu trúc cho systemMessage và ngữ cảnh dành riêng cho hook, nhưng
continue: false không dừng tác nhân phụ:
{
"continue": true,
"stopReason": "optional",
"systemMessage": "optional",
"suppressOutput": false
}| Trường | Tác dụng |
|---|---|
continue |
Nếu là false, đánh dấu lần chạy hook đó là đã dừng |
stopReason |
Được ghi lại làm lý do dừng |
systemMessage |
Hiển thị dưới dạng cảnh báo trong UI hoặc luồng sự kiện |
suppressOutput |
Hiện được phân tích cú pháp nhưng chưa triển khai |
Thoát với 0 mà không có đầu ra được coi là thành công và Codex tiếp tục.
PreToolUse và PermissionRequest hỗ trợ systemMessage, nhưng continue,
stopReason và suppressOutput hiện chưa được hỗ trợ cho các sự kiện đó.
Nếu một hook PreToolUse trả về một trong các trường không được hỗ trợ này, Codex sẽ đánh dấu
lần chạy hook đó là thất bại, báo lỗi và tiếp tục lệnh gọi công cụ.
PostToolUse hỗ trợ systemMessage, continue: false và stopReason.
suppressOutput được phân tích cú pháp nhưng hiện chưa được hỗ trợ cho sự kiện đó.
Đầu ra hook lớn
Theo mặc định, Codex giới hạn mỗi thông báo đầu ra hook mà mô hình có thể nhìn thấy ở khoảng
2.500 token. Nếu hook trả về nhiều hơn, Codex sẽ lưu toàn bộ văn bản trong
<temp_dir>/hook_outputs/<session_id>/<uuid>.txt và cung cấp cho mô hình một
bản xem trước gồm phần đầu và phần cuối cùng với đường dẫn tệp đã lưu. Hành vi này được gọi là
tràn ra đĩa: Codex lưu đầu ra quá lớn trên ổ đĩa và thay thế bằng một
bản xem trước ngắn hơn mà mô hình có thể nhìn thấy. Nếu không thể ghi tệp, mô hình vẫn
nhận được bản xem trước đã cắt ngắn.
Đối với bất kỳ hook lệnh nào trả về additionalContext, hãy đặt
additionalContextLimit trên trình xử lý để tùy chỉnh ngưỡng token
xấp xỉ:
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_start.py",
"additionalContextLimit": 5000
}Bỏ qua additionalContextLimit để dùng ngưỡng 2500 token mặc định. Dùng một
số nguyên dương để chọn ngưỡng khác hoặc 0 để truyền toàn bộ ngữ cảnh bổ sung
của trình xử lý trực tiếp đến mô hình. Codex đánh giá độc lập từng
trình xử lý khớp. Đối với các sự kiện không thể tạo ngữ cảnh bổ sung,
Codex bỏ qua additionalContextLimit và báo cảnh báo cấu hình.
Cài đặt này chỉ áp dụng cho additionalContext. Phản hồi công cụ và prompt tiếp tục
giữ nguyên giới hạn mặc định.
Vì đầu ra quá lớn có thể được ghi vào ổ đĩa, hãy tránh trả về thông tin bí mật hoặc dữ liệu nhạy cảm khác trong đầu ra hook.
Hook
SessionStart
matcher được áp dụng cho source đối với sự kiện này.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
source |
string |
Cách phiên bắt đầu: startup, resume, clear hoặc compact |
Văn bản thuần trên stdout được thêm làm ngữ cảnh bổ sung dành cho nhà phát triển.
JSON trên stdout hỗ trợ Các trường đầu ra chung và
cấu trúc dành riêng cho hook sau:
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Load the workspace conventions before editing."
}
}Văn bản additionalContext đó được thêm làm ngữ cảnh bổ sung dành cho nhà phát triển.
Sau khi Codex nén một phiên gốc, các hook SessionStart khớp với
source: "compact" sẽ chạy trước yêu cầu mô hình tiếp theo. Điều này cũng áp dụng khi
quá trình nén tự động xảy ra giữa một lượt: Codex chuyển ngữ cảnh bổ sung của hook
đến ngay lượt tiếp tục thay vì chờ một lượt người dùng
sau đó. Nếu hook trả về continue: false, Codex kết thúc lượt
mà không gửi thêm yêu cầu mô hình.
SessionEnd
SessionEnd cho phép bạn chạy lệnh khi một phiên kết thúc, chẳng hạn như lưu ghi chú
cuối cùng hoặc dọn dẹp tệp. Hook chạy cho luồng chính khi bạn lưu trữ hoặc
xóa một cuộc trò chuyện vẫn đang mở, khi Codex đóng bình thường hoặc sau khi một
cuộc trò chuyện không hoạt động và không mở trong bất kỳ máy khách kết nối nào trong 30
phút. Hook này không chạy cho tác nhân phụ.
Việc chuyển khỏi một cuộc trò chuyện hoặc gọi thread/unsubscribe không kết thúc
phiên ngay lập tức, vì vậy thao tác đó sẽ không chạy SessionEnd ngay. Hook của bạn vẫn có thể
đọc bản ghi phiên trong khi chạy.
matcher lọc reason cho sự kiện này. Hiện tại, reason luôn là other.
Bạn có thể bỏ qua matcher hoặc dùng other để chạy với mọi sự kiện SessionEnd.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
reason |
string |
Lý do phiên kết thúc: other |
Ví dụ, một lệnh SessionEnd nhận:
{
"session_id": "thr_123",
"transcript_path": "/workspace/.codex/rollout.jsonl",
"cwd": "/workspace",
"hook_event_name": "SessionEnd",
"reason": "other"
}Hook SessionEnd mang tính tư vấn. Đầu ra của hook không điều hướng Codex hoặc giữ
luồng tiếp tục mở. Nếu lệnh hết thời gian chờ hoặc thoát với lỗi, Codex sẽ báo đó là
lỗi hook.
SubagentStart
matcher được áp dụng cho agent_type đối với sự kiện này.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
agent_id |
string |
Mã định danh của tác nhân phụ |
agent_type |
string |
Loại hoặc hồ sơ tác nhân phụ |
permission_mode |
string |
Chế độ quyền hiện tại |
Văn bản thuần trên stdout được thêm làm ngữ cảnh bổ sung dành cho nhà phát triển cho tác nhân phụ.
JSON trên stdout hỗ trợ systemMessage và cấu trúc dành riêng cho hook sau:
{
"hookSpecificOutput": {
"hookEventName": "SubagentStart",
"additionalContext": "Review the repository test conventions first."
}
}Văn bản additionalContext đó được thêm làm ngữ cảnh bổ sung dành cho nhà phát triển cho
tác nhân phụ. continue: false được phân tích cú pháp để tương thích, nhưng không ngăn
tác nhân phụ khởi động.
PreToolUse
PreToolUse có thể chặn Bash, thao tác chỉnh sửa tệp được thực hiện qua apply_patch,
lệnh gọi công cụ MCP và các công cụ hàm cục bộ khác. Xem Phạm vi
công cụ để biết các đường dẫn được hỗ trợ và ngoại lệ.
matcher được áp dụng cho tool_name và các bí danh đối sánh. Đối với chỉnh sửa tệp qua
apply_patch, các giá trị matcher có thể dùng apply_patch, Edit hoặc Write; đầu vào hook
vẫn báo cáo tool_name: "apply_patch".
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
tool_name |
string |
Tên công cụ hook chuẩn, chẳng hạn như Bash, apply_patch hoặc tên MCP như mcp__fs__read |
tool_use_id |
string |
ID lệnh gọi công cụ cho lần gọi này |
tool_input |
JSON value |
Đầu vào dành riêng cho công cụ. Bash và apply_patch dùng tool_input.command. MCP và các công cụ hàm cục bộ khác gửi đối số của chúng. |
Văn bản thuần trên stdout bị bỏ qua.
JSON trên stdout có thể dùng systemMessage. Để từ chối một lệnh gọi công cụ được hỗ trợ, hãy trả về
cấu trúc dành riêng cho hook sau:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by hook."
}
}Codex cũng chấp nhận cấu trúc khối cũ hơn sau:
{
"decision": "block",
"reason": "Destructive command blocked by hook."
}Bạn cũng có thể dùng mã thoát 2 và ghi lý do chặn vào stderr.
Để thêm ngữ cảnh mà mô hình có thể nhìn thấy mà không chặn, hãy trả về
hookSpecificOutput.additionalContext:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"additionalContext": "The pending command touches generated files."
}
}Để viết lại một lệnh gọi công cụ được hỗ trợ mà không chặn, hãy trả về
permissionDecision: "allow" cùng updatedInput:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": {
"command": "echo rewritten"
}
}
}Đối với lệnh Bash và apply_patch, updatedInput phải bao gồm trường chuỗi
command. Đối với MCP và các công cụ hàm cục bộ khác, updatedInput là
đối tượng đối số thay thế. Chỉ trả về updatedInput cùng với
permissionDecision: "allow"; các cấu trúc updatedInput khác được báo là
lỗi.
permissionDecision: "ask", decision: "approve" cũ, continue: false,
stopReason và suppressOutput được phân tích cú pháp nhưng chưa được hỗ trợ. Codex đánh dấu
lần chạy hook là thất bại, báo lỗi và tiếp tục lệnh gọi công cụ.
PermissionRequest
PermissionRequest chạy khi Codex sắp yêu cầu phê duyệt, chẳng hạn như
nâng quyền shell hoặc phê duyệt mạng được quản lý. Hook có thể cho phép yêu cầu, từ chối
yêu cầu hoặc không đưa ra quyết định để tiếp tục hiển thị prompt phê duyệt thông thường.
Hook không chạy cho các lệnh không cần phê duyệt.
matcher được áp dụng cho tool_name và các bí danh đối sánh. Các giá trị chuẩn hiện tại
bao gồm Bash, apply_patch và tên công cụ MCP như
mcp__server__tool; apply_patch cũng khớp với Edit và Write.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
tool_name |
string |
Tên công cụ hook chuẩn, chẳng hạn như Bash, apply_patch hoặc tên MCP như mcp__fs__read |
tool_input |
JSON value |
Đầu vào dành riêng cho công cụ. Bash và apply_patch dùng tool_input.command, còn công cụ MCP gửi tất cả đối số. |
tool_input.description |
string | null |
Lý do phê duyệt dễ đọc, khi Codex có lý do đó |
Văn bản thuần trên stdout bị bỏ qua.
Một số đầu vào công cụ có thể bao gồm mô tả dễ đọc, nhưng đừng dựa vào
trường tool_input.description cho mọi công cụ.
Để phê duyệt yêu cầu, hãy trả về:
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow"
}
}
}Để từ chối yêu cầu, hãy trả về:
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "deny",
"message": "Blocked by repository policy."
}
}
}Nếu nhiều hook khớp trả về quyết định, bất kỳ deny nào cũng được ưu tiên. Nếu không, một
allow sẽ cho phép yêu cầu tiếp tục mà không hiển thị prompt phê duyệt. Nếu không
có hook khớp nào đưa ra quyết định, Codex sử dụng quy trình phê duyệt thông thường.
Không trả về updatedInput, updatedPermissions hoặc interrupt cho
PermissionRequest; các trường đó được dành riêng cho hành vi trong tương lai và hiện sẽ
từ chối theo mặc định.
PostToolUse
PostToolUse chạy sau khi các công cụ được hỗ trợ tạo đầu ra, bao gồm Bash,
apply_patch, lệnh gọi công cụ MCP và các công cụ hàm cục bộ khác. Với Bash, hook
cũng chạy sau các lệnh thoát với trạng thái khác 0. Hook không thể hoàn tác tác dụng
phụ của một công cụ đã chạy. Xem Phạm vi công cụ để
biết các đường dẫn được hỗ trợ và ngoại lệ.
matcher được áp dụng cho tool_name và các bí danh đối sánh. Đối với chỉnh sửa tệp qua
apply_patch, các giá trị matcher có thể dùng apply_patch, Edit hoặc Write; đầu vào hook
vẫn báo cáo tool_name: "apply_patch".
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
tool_name |
string |
Tên công cụ hook chuẩn, chẳng hạn như Bash, apply_patch hoặc tên MCP như mcp__fs__read |
tool_use_id |
string |
ID lệnh gọi công cụ cho lần gọi này |
tool_input |
JSON value |
Đầu vào dành riêng cho công cụ. Bash và apply_patch dùng tool_input.command. MCP và các công cụ hàm cục bộ khác gửi đối số của chúng. |
tool_response |
JSON value |
Đầu ra dành riêng cho công cụ. Công cụ MCP gửi kết quả lệnh gọi MCP. Các công cụ hàm cục bộ khác thường gửi đầu ra dành cho mô hình. |
Văn bản thuần trên stdout bị bỏ qua.
JSON trên stdout có thể dùng systemMessage và cấu trúc dành riêng cho hook sau:
{
"decision": "block",
"reason": "The Bash output needs review before continuing.",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "The command updated generated files."
}
}Văn bản additionalContext đó được thêm làm ngữ cảnh bổ sung dành cho nhà phát triển.
Đối với sự kiện này, decision: "block" không hoàn tác lệnh Bash đã hoàn thành.
Thay vào đó, Codex ghi lại phản hồi, thay thế kết quả công cụ bằng
phản hồi đó và để mô hình tiếp tục từ thông báo do hook cung cấp.
Bạn cũng có thể dùng mã thoát 2 và ghi lý do phản hồi vào stderr.
Để dừng quá trình xử lý thông thường của kết quả công cụ ban đầu sau khi lệnh đã
chạy, hãy trả về continue: false. Codex sẽ thay thế kết quả công cụ bằng
phản hồi hoặc văn bản dừng của bạn và tiếp tục từ đó.
updatedMCPToolOutput và suppressOutput được phân tích cú pháp nhưng chưa được hỗ trợ.
Codex đánh dấu lần chạy hook là thất bại, báo lỗi và tiếp tục xử lý
kết quả công cụ theo cách thông thường.
Lệnh gọi công cụ từ chế độ mã
Khi mô hình dùng chế độ mã để gọi công cụ từ JavaScript, quyết định của hook áp dụng
cho lệnh gọi lồng nhau đó. PreToolUse có thể dừng công cụ trước khi chạy hoặc viết lại
đầu vào của công cụ. PostToolUse chặn không thể hoàn tác tác dụng phụ của công cụ, nhưng có thể
ngăn kết quả ban đầu đến được tập lệnh đang chạy.
| Kết quả hook | Nội dung chế độ mã nhận được |
|---|---|
PreToolUse chặn |
Promise của công cụ bị từ chối trước khi công cụ chạy. |
PreToolUse trả về updatedInput |
Công cụ chạy với đầu vào đã viết lại và promise được hoàn thành với kết quả đó. |
PostToolUse trả về decision: "block" hoặc thoát với mã 2 |
Công cụ chạy, sau đó promise bị từ chối với lý do của hook. |
PostToolUse trả về continue: false |
Codex dùng phản hồi hook cho kết quả mà mô hình nhìn thấy, nhưng không từ chối promise công cụ lồng nhau. |
PreCompact
PreCompact chạy trước khi Codex nén cuộc trò chuyện. matcher được áp dụng
cho trigger, có các giá trị là manual và auto.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
trigger |
string |
Yếu tố kích hoạt quá trình nén: manual hoặc auto |
Văn bản thuần trên stdout bị bỏ qua.
JSON trên stdout hỗ trợ Các trường đầu ra chung. Nếu một
hook PreCompact khớp trả về continue: false, Codex sẽ dừng trước khi
nén.
PostCompact
PostCompact chạy sau khi Codex nén cuộc trò chuyện. matcher được áp dụng
cho trigger, có các giá trị là manual và auto.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
trigger |
string |
Yếu tố kích hoạt quá trình nén: manual hoặc auto |
Văn bản thuần trên stdout bị bỏ qua.
JSON trên stdout hỗ trợ Các trường đầu ra chung. Nếu một
hook PostCompact khớp trả về continue: false, Codex sẽ dừng sau khi
nén.
UserPromptSubmit
matcher hiện không được dùng cho sự kiện này.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
prompt |
string |
Prompt người dùng sắp được gửi |
Văn bản thuần trên stdout được thêm làm ngữ cảnh bổ sung dành cho nhà phát triển.
JSON trên stdout hỗ trợ Các trường đầu ra chung và
cấu trúc dành riêng cho hook sau:
{
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "Ask for a clearer reproduction before editing files."
}
}Văn bản additionalContext đó được thêm làm ngữ cảnh bổ sung dành cho nhà phát triển.
Để chặn prompt, hãy trả về:
{
"decision": "block",
"reason": "Ask for confirmation before doing that."
}Bạn cũng có thể dùng mã thoát 2 và ghi lý do chặn vào stderr.
SubagentStop
matcher được áp dụng cho agent_type đối với sự kiện này.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
agent_id |
string |
Mã định danh của tác nhân phụ |
agent_type |
string |
Loại hoặc hồ sơ tác nhân phụ |
agent_transcript_path |
string | null |
Đường dẫn đến tệp bản ghi tác nhân phụ, nếu có |
stop_hook_active |
boolean |
Tác nhân phụ này đã được tiếp tục hay chưa |
last_assistant_message |
string | null |
Thông báo mới nhất của trợ lý tác nhân phụ, nếu có |
SubagentStop yêu cầu JSON trên stdout khi thoát với 0. Đầu ra văn bản thuần
không hợp lệ cho sự kiện này.
JSON trên stdout hỗ trợ Các trường đầu ra chung. Để yêu cầu
Codex tiếp tục luồng tác nhân phụ, hãy trả về:
{
"decision": "block",
"reason": "Run one more focused pass inside the subagent."
}Bạn cũng có thể dùng mã thoát 2 và ghi lý do tiếp tục vào stderr.
Nếu bất kỳ hook SubagentStop khớp nào trả về continue: false, kết quả đó sẽ
được ưu tiên hơn quyết định tiếp tục từ các hook SubagentStop khớp khác.
Stop
matcher hiện không được dùng cho sự kiện này.
Các trường ngoài Các trường đầu vào chung:
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
turn_id |
string |
Phần mở rộng riêng của Codex. ID lượt Codex đang hoạt động |
stop_hook_active |
boolean |
Lượt này đã được Stop tiếp tục hay chưa |
last_assistant_message |
string | null |
Văn bản thông báo mới nhất của trợ lý, nếu có |
Stop yêu cầu JSON trên stdout khi thoát với 0. Đầu ra văn bản thuần không hợp lệ
cho sự kiện này.
JSON trên stdout hỗ trợ Các trường đầu ra chung. Để giữ
Codex tiếp tục chạy, hãy trả về:
{
"decision": "block",
"reason": "Run one more pass over the failing tests."
}Bạn cũng có thể dùng mã thoát 2 và ghi lý do tiếp tục vào stderr.
Đối với sự kiện này, decision: "block" không từ chối lượt. Thay vào đó, nó yêu cầu
Codex tiếp tục và tự động tạo một prompt tiếp tục mới hoạt động
như prompt người dùng mới, sử dụng reason của bạn làm văn bản prompt đó.
Nếu bất kỳ hook Stop khớp nào trả về continue: false, kết quả đó được ưu tiên
hơn quyết định tiếp tục từ các hook Stop khớp khác.
Lược đồ
Nếu cần định dạng truyền chính xác hiện tại, hãy xem các lược đồ được tạo trong kho lưu trữ Codex trên GitHub.
Bí danh văn bản thuần
- string | null