Remarque
Kit de développement logiciel (SDK) Copilot est actuellement en préversion technique. Les fonctionnalités et la disponibilité sont susceptibles de changer.
Le onPostToolUse hook est appelé après l’exécution d’un outil. Utilisez-le pour :
- Transformer ou filtrer les résultats de l’outil
- Exécution de l’outil de journalisation pour l’audit
- Ajouter un contexte en fonction des résultats
- Supprimer les résultats de la conversation
Signature de point d'interception
import type { PostToolUseHookInput, HookInvocation, PostToolUseHookOutput } from "@github/copilot-sdk";
type PostToolUseHandler = (
input: PostToolUseHookInput,
invocation: HookInvocation
) => Promise<PostToolUseHookOutput | null | undefined>;
Pour obtenir les signatures de hook dans Python, Go et .NET, consultez le github/copilot-sdk référentiel.
Input
| Champ | Type | Description |
|---|---|---|
timestamp | nombre | Horodatage Unix lorsque le hook a été déclenché |
cwd | ficelle | Répertoire de travail actuel |
toolName | ficelle | Nom de l’outil appelé |
toolArgs | objet | Arguments passés à l’outil |
toolResult | objet | Résultat retourné par l’outil |
Sortie
Retournez null ou undefined pour laisser le résultat inchangé. Sinon, retournez un objet avec l’un des champs suivants.
| Champ | Type | Description |
|---|---|---|
modifiedResult | objet | Résultat modifié à utiliser au lieu d’origine |
additionalContext | ficelle | Contexte supplémentaire injecté dans la conversation |
suppressOutput | booléen | Si la valeur est true, le résultat n’apparaît pas dans la conversation |
Exemples
Journaliser tous les résultats de l’outil
const session = await client.createSession({
hooks: {
onPostToolUse: async (input, invocation) => {
console.log(
`[${invocation.sessionId}] `
+ `Tool: ${input.toolName}`
);
console.log(
` Args: ${JSON.stringify(input.toolArgs)}`
);
console.log(
` Result: `
+ `${JSON.stringify(input.toolResult)}`
);
return null; // Pass through unchanged
},
},
});
Pour obtenir des exemples dans Python, Go et .NET, consultez le github/copilot-sdk référentiel.
Réactez les données sensibles
const SENSITIVE_PATTERNS = [
/api[_-]?key["\s:=]+["']?[\w-]+["']?/gi,
/password["\s:=]+["']?[\w-]+["']?/gi,
/secret["\s:=]+["']?[\w-]+["']?/gi,
];
const session = await client.createSession({
hooks: {
onPostToolUse: async (input) => {
if (typeof input.toolResult === "string") {
let redacted = input.toolResult;
for (const pattern of SENSITIVE_PATTERNS) {
redacted = redacted.replace(
pattern, "[REDACTED]"
);
}
if (redacted !== input.toolResult) {
return { modifiedResult: redacted };
}
}
return null;
},
},
});
Tronquer les résultats importants
const MAX_RESULT_LENGTH = 10000;
const session = await client.createSession({
hooks: {
onPostToolUse: async (input) => {
const resultStr =
JSON.stringify(input.toolResult);
if (resultStr.length > MAX_RESULT_LENGTH) {
return {
modifiedResult: {
truncated: true,
originalLength: resultStr.length,
content:
resultStr.substring(
0, MAX_RESULT_LENGTH
) + "...",
},
additionalContext:
`Note: Result was truncated from `
+ `${resultStr.length} to `
+ `${MAX_RESULT_LENGTH} characters.`,
};
}
return null;
},
},
});
Ajouter un contexte en fonction des résultats
const session = await client.createSession({
hooks: {
onPostToolUse: async (input) => {
// If a file read returned an error,
// add helpful context
if (
input.toolName === "read_file"
&& input.toolResult?.error
) {
return {
additionalContext:
"Tip: If the file doesn't exist, "
+ "consider creating it or "
+ "checking the path.",
};
}
// If shell command failed,
// add debugging hint
if (
input.toolName === "shell"
&& input.toolResult?.exitCode !== 0
) {
return {
additionalContext:
"The command failed. Check if "
+ "required dependencies are installed.",
};
}
return null;
},
},
});
Filtrer les traces de pile d’erreurs
const session = await client.createSession({
hooks: {
onPostToolUse: async (input) => {
if (input.toolResult?.error && input.toolResult?.stack) {
// Remove internal stack trace details
return {
modifiedResult: {
error: input.toolResult.error,
// Keep only first 3 lines of stack
stack: input.toolResult.stack.split("\n").slice(0, 3).join("\n"),
},
};
}
return null;
},
},
});
Piste d’audit pour la conformité
interface AuditEntry {
timestamp: number;
sessionId: string;
toolName: string;
args: unknown;
result: unknown;
success: boolean;
}
const auditLog: AuditEntry[] = [];
const session = await client.createSession({
hooks: {
onPostToolUse: async (input, invocation) => {
auditLog.push({
timestamp: input.timestamp,
sessionId: invocation.sessionId,
toolName: input.toolName,
args: input.toolArgs,
result: input.toolResult,
success: !input.toolResult?.error,
});
// Optionally persist to database/file
await saveAuditLog(auditLog);
return null;
},
},
});
Supprimer les résultats bruyants
const NOISY_TOOLS = ["list_directory", "search_codebase"];
const session = await client.createSession({
hooks: {
onPostToolUse: async (input) => {
if (NOISY_TOOLS.includes(input.toolName)) {
// Summarize instead of showing full result
const items = Array.isArray(input.toolResult)
? input.toolResult
: input.toolResult?.items || [];
return {
modifiedResult: {
summary: `Found ${items.length} items`,
firstFew: items.slice(0, 5),
},
};
}
return null;
},
},
});
Bonnes pratiques
-
**Retournez `null` quand aucune modification n’est nécessaire.** Cela est plus efficace que de retourner un objet vide ou le même résultat. -
**Soyez prudent avec la modification du résultat.** La modification des résultats peut affecter la façon dont le modèle interprète la sortie de l’outil. Modifiez uniquement si nécessaire. -
**Utiliser `additionalContext` pour les indicateurs.** Au lieu de modifier les résultats, ajoutez un contexte pour aider le modèle à les interpréter. -
**Prenez en compte la confidentialité lors de la journalisation.** Les résultats de l’outil peuvent contenir des données sensibles. Appliquez la rédaction avant la journalisation. -
**Gardez les crochets bien serrés.** Les crochets post-outils s’exécutent de manière synchrone. Le traitement lourd doit être effectué de manière asynchrone ou par lot.
Lectures complémentaires
-
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/quickstart) -
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/pre-tool-use) -
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/error-handling)