Skip to content

Commit d0c54fe

Browse files
committed
docs(copilot-cli): document agentStop, subagentStop, and preCompact hooks
1 parent 97bc4dd commit d0c54fe

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

content/copilot/reference/hooks-configuration.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,158 @@ if [ "$RESULT_TYPE" = "failure" ]; then
257257
fi
258258
```
259259

260+
### Agent stop hook
261+
262+
Executed when the main agent finishes responding to a prompt and is about to stop. Use this hook to log session completion or to inject a follow-up instruction by blocking the stop. When you block, the `reason` you provide is enqueued as the next user prompt, so the agent continues with that input.
263+
264+
**Example input JSON:**
265+
266+
```json copy
267+
{
268+
"timestamp": 1704614750000,
269+
"cwd": "/path/to/project",
270+
"sessionId": "01HW2X3Y4Z5...",
271+
"transcriptPath": "/path/to/transcript.jsonl",
272+
"stopReason": "end_turn"
273+
}
274+
```
275+
276+
**Fields:**
277+
278+
* `timestamp`: Unix timestamp in milliseconds
279+
* `cwd`: Current working directory
280+
* `sessionId`: The unique identifier of the current session
281+
* `transcriptPath`: Path to the JSONL transcript file for the session
282+
* `stopReason`: Why the agent is stopping (currently always `"end_turn"`)
283+
284+
**Output JSON (optional):**
285+
286+
```json copy
287+
{
288+
"decision": "block",
289+
"reason": "Run the test suite before stopping."
290+
}
291+
```
292+
293+
**Output fields:**
294+
295+
* `decision`: Set to `"block"` to keep the agent running by enqueueing `reason` as the next user prompt. Omit the field, or return `{}`, to allow the stop.
296+
* `reason`: The text to feed back into the agent as a new prompt when blocking. Required when `decision` is `"block"`.
297+
298+
**Example script that asks the agent to summarize before stopping:**
299+
300+
```shell copy
301+
#!/bin/bash
302+
INPUT=$(cat)
303+
304+
# Avoid an infinite loop: only inject a follow-up if no summary marker exists yet
305+
TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcriptPath')
306+
if [ -f "$TRANSCRIPT" ] && grep -q "## Session summary" "$TRANSCRIPT"; then
307+
echo "{}"
308+
exit 0
309+
fi
310+
311+
echo '{"decision":"block","reason":"Before you stop, write a one-paragraph session summary under a `## Session summary` heading."}'
312+
```
313+
314+
### Subagent stop hook
315+
316+
Executed when a subagent finishes its turn, before its output is returned to the parent agent. Use this hook to log subagent activity or to keep the subagent running by injecting follow-up instructions.
317+
318+
**Example input JSON:**
319+
320+
```json copy
321+
{
322+
"timestamp": 1704614760000,
323+
"cwd": "/path/to/project",
324+
"sessionId": "01HW2X3Y4Z5...",
325+
"transcriptPath": "/path/to/subagent-transcript.jsonl",
326+
"agentName": "researcher",
327+
"agentDisplayName": "Research Agent",
328+
"stopReason": "end_turn"
329+
}
330+
```
331+
332+
**Fields:**
333+
334+
* `timestamp`: Unix timestamp in milliseconds
335+
* `cwd`: Current working directory
336+
* `sessionId`: The unique identifier of the subagent session
337+
* `transcriptPath`: Path to the JSONL transcript file for the subagent
338+
* `agentName`: The internal name of the subagent
339+
* `agentDisplayName`: The human-readable display name of the subagent
340+
* `stopReason`: Why the subagent is stopping (currently always `"end_turn"`)
341+
342+
**Output JSON (optional):**
343+
344+
```json copy
345+
{
346+
"decision": "block",
347+
"reason": "Cite at least three sources before returning."
348+
}
349+
```
350+
351+
**Output fields:**
352+
353+
* `decision`: Set to `"block"` to keep the subagent running by injecting `reason` as the next message. Omit, or return `{}`, to let the subagent return its result to the parent.
354+
* `reason`: The text to feed back into the subagent. Required when `decision` is `"block"`.
355+
356+
**Example script that logs every subagent completion:**
357+
358+
```shell copy
359+
#!/bin/bash
360+
INPUT=$(cat)
361+
NAME=$(echo "$INPUT" | jq -r '.agentName')
362+
SESSION=$(echo "$INPUT" | jq -r '.sessionId')
363+
echo "$(date -Iseconds) subagent=$NAME session=$SESSION" >> ~/.copilot/subagent-activity.log
364+
echo "{}"
365+
```
366+
367+
### Pre-compact hook
368+
369+
Executed just before the conversation is compacted to free space in the context window. Compaction summarizes earlier messages and discards the originals, so this is a useful point to persist details that the summary may not preserve.
370+
371+
**Example input JSON:**
372+
373+
```json copy
374+
{
375+
"timestamp": 1704614800000,
376+
"cwd": "/path/to/project",
377+
"sessionId": "01HW2X3Y4Z5...",
378+
"transcriptPath": "/path/to/transcript.jsonl",
379+
"trigger": "auto",
380+
"customInstructions": ""
381+
}
382+
```
383+
384+
**Fields:**
385+
386+
* `timestamp`: Unix timestamp in milliseconds
387+
* `cwd`: Current working directory
388+
* `sessionId`: The unique identifier of the current session
389+
* `transcriptPath`: Path to the JSONL transcript file for the session
390+
* `trigger`: How compaction was started. Either `"auto"` (the context window approached its limit) or `"manual"` (the user requested compaction)
391+
* `customInstructions`: Any custom instructions the user provided to guide the compaction. Empty string when none were provided.
392+
393+
**Output:** Ignored. Use this hook for side effects such as exporting the transcript or notifying an external system.
394+
395+
**Example script that archives the transcript before each compaction:**
396+
397+
```shell copy
398+
#!/bin/bash
399+
INPUT=$(cat)
400+
TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcriptPath')
401+
SESSION=$(echo "$INPUT" | jq -r '.sessionId')
402+
TRIGGER=$(echo "$INPUT" | jq -r '.trigger')
403+
404+
ARCHIVE_DIR="$HOME/.copilot/transcripts"
405+
mkdir -p "$ARCHIVE_DIR"
406+
407+
if [ -f "$TRANSCRIPT" ]; then
408+
cp "$TRANSCRIPT" "$ARCHIVE_DIR/${SESSION}-pre-compact-${TRIGGER}-$(date +%s).jsonl"
409+
fi
410+
```
411+
260412
### Error occurred hook
261413

262414
Executed when an error occurs during agent execution.

0 commit comments

Comments
 (0)