Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Unit 5: Hooks","local":"unit-5-hooks","sections":[{"title":"What Are Hooks?","local":"what-are-hooks","sections":[],"depth":2},{"title":"Why Hooks Matter","local":"why-hooks-matter","sections":[],"depth":2},{"title":"Platform Landscape","local":"platform-landscape","sections":[],"depth":2},{"title":"What You’ll Build","local":"what-youll-build","sections":[],"depth":2},{"title":"What You’ll Learn","local":"what-youll-learn","sections":[],"depth":2}],"depth":1}"> | |
| <link href="/docs/context-course/pr_7/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/entry/start.55c3acaa.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/scheduler.4048030c.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/singletons.42509544.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/index.dd3f5310.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/paths.f6762227.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/entry/app.10ec5479.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/preload-helper.665302cf.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/index.5d0b9360.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/nodes/0.b63aa764.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/nodes/32.3bbcdb7a.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.99c2e6c8.js"> | |
| <link rel="modulepreload" href="/docs/context-course/pr_7/en/_app/immutable/chunks/CodeBlock.ff2a3276.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"Unit 5: Hooks","local":"unit-5-hooks","sections":[{"title":"What Are Hooks?","local":"what-are-hooks","sections":[],"depth":2},{"title":"Why Hooks Matter","local":"why-hooks-matter","sections":[],"depth":2},{"title":"Platform Landscape","local":"platform-landscape","sections":[],"depth":2},{"title":"What You’ll Build","local":"what-youll-build","sections":[],"depth":2},{"title":"What You’ll Learn","local":"what-youll-learn","sections":[],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="unit-5-hooks" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#unit-5-hooks"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Unit 5: Hooks</span></h1> <h2 class="relative group"><a id="what-are-hooks" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-are-hooks"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>What Are Hooks?</span></h2> <p data-svelte-h="svelte-zqhczd">Hooks are user-defined handlers that run at deterministic points in an agent’s lifecycle. When an agent is about to call a tool, finish a turn, or start a new session, the runtime pauses, invokes any hooks registered for that event, and then continues. Hooks let you observe what the agent is doing, block unsafe actions, inject extra context, or stream events to an external system. Crucially, they let you do this without asking the model to do it itself.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->User prompt | |
| │ | |
| ├─[UserPromptSubmit hook]─► log / inject context | |
| ▼ | |
| Model reasoning | |
| │ | |
| ├─[PreToolUse hook]─► allow, deny, rewrite args | |
| ▼ | |
| Tool executes | |
| │ | |
| ├─[PostToolUse hook]─► log, analyze, post-process | |
| ▼ | |
| Model continues | |
| │ | |
| └─[Stop / SessionEnd hooks]─► persist, notify, tear down<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-1f6o2ab">Skills, MCP, plugins, and subagents all shape <em>what the agent can do</em>. Hooks shape <em>what happens around every step the agent takes</em>. That makes them the right surface for observability, guardrails, and automation glue.</p> <h2 class="relative group"><a id="why-hooks-matter" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#why-hooks-matter"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Why Hooks Matter</span></h2> <p data-svelte-h="svelte-rsco57">A model asked to “always run the linter after editing” will eventually forget or may not be consistent in its implementation. A hook on <code>PostToolUse</code> that runs the linter is consistent every single time and always runs. Hooks turn conventions into code.</p> <blockquote class="note" data-svelte-h="svelte-qbisuq"><p>A linter is a tool that checks code for common mistakes, style issues, and project rule violations. It does not usually run the whole program; it scans the code and reports things that look wrong or inconsistent.</p></blockquote> <p data-svelte-h="svelte-1dqxpz7">Three common patterns benefit the most:</p> <p data-svelte-h="svelte-1qcho6z"><strong>Observability.</strong> Every tool call, prompt, and stop event can be captured in a log or dashboard so you can see what the agent actually did — not what it said it did.</p> <p data-svelte-h="svelte-1d98sk5"><strong>Guardrails.</strong> A hook can inspect a <code>Bash</code> command before it runs and deny anything that touches <code>~/.ssh/</code> or <code>rm -rf /</code>. Guardrails expressed as code are more reliable than guardrails expressed as prompt instructions.</p> <p data-svelte-h="svelte-1t4u02l"><strong>Automation.</strong> Hooks can run formatters, linters, type-checkers, or test suites automatically after a file edit. The agent does not need to remember to do it — the runtime does.</p> <h2 class="relative group"><a id="platform-landscape" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#platform-landscape"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Platform Landscape</span></h2> <p data-svelte-h="svelte-vhz6jp">The four platforms in this course all support hooks, but with different shapes:</p> <ul data-svelte-h="svelte-cfjbwr"><li><strong>Claude Code</strong> — JSON configuration in <code>.claude/settings.json</code> (or inside a plugin). Events use <code>PascalCase</code> names like <code>PreToolUse</code> and <code>Stop</code>. Hooks can be shell commands, HTTP endpoints, prompts, or subagents.</li> <li><strong>Codex</strong> — JSON configuration in <code>.codex/hooks.json</code>, gated behind a feature flag in <code>config.toml</code>. A smaller set of events (also <code>PascalCase</code>), and shell-command handlers that receive a JSON payload on stdin.</li> <li><strong>OpenCode</strong> — TypeScript/JavaScript plugin modules in <code>.opencode/plugins/</code>. Hooks are object keys on the exported plugin, like <code>"tool.execute.before"</code> or a generic <code>event</code> callback. There is no JSON event config — everything is code.</li> <li><strong>Pi</strong> — TypeScript/JavaScript extensions in <code>.pi/extensions/</code> or <code>~/.pi/agent/extensions/</code>. Events use <code>lower_snake_case</code> names like <code>before_agent_start</code>, <code>tool_call</code>, and <code>tool_result</code>, and handlers are registered in code with <code>pi.on(...)</code>.</li></ul> <p data-svelte-h="svelte-14lpj1a">The mental model is consistent across all four: events fire, handlers run, and handlers can influence the agent’s next step. Only the syntax and the event names change.</p> <h2 class="relative group"><a id="what-youll-build" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-youll-build"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>What You’ll Build</span></h2> <p data-svelte-h="svelte-10fkn7v">This unit walks through the hook lifecycle, shows the exact config shape for each platform, and then builds a working <strong>Agent Activity Dashboard</strong>: a Gradio app that receives hook events over HTTP and visualizes tool calls, prompts, and sessions in real time. By the end you will have one dashboard that works against all four agents.</p> <h2 class="relative group"><a id="what-youll-learn" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-youll-learn"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>What You’ll Learn</span></h2> <p data-svelte-h="svelte-1jt7p5l">This unit covers the common hook lifecycle shared by Claude Code, Codex, OpenCode, and Pi; where hook configuration lives on each platform and what JSON or code shape it takes; how hook handlers influence the agent through exit codes, JSON output, thrown errors, or returned values; and how to build a Gradio dashboard that turns hook events into a live view of agent activity.</p> <p data-svelte-h="svelte-jclqkm">Next, a tour of the hook events themselves.</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/context-course/blob/main/units/en/unit5/introduction.mdx" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_ck2jc = { | |
| assets: "/docs/context-course/pr_7/en", | |
| base: "/docs/context-course/pr_7/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/context-course/pr_7/en/_app/immutable/entry/start.55c3acaa.js"), | |
| import("/docs/context-course/pr_7/en/_app/immutable/entry/app.10ec5479.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 32], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 19.2 kB
- Xet hash:
- dc7ee8c2a037044bbb62197168e2e620ce2faf798cb9414f941e6f4e6c909f36
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.