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 onUserPromptSubmitted hook est appelé lorsqu’un utilisateur envoie un message. Utilisez-le pour :
- Modifier ou améliorer les messages utilisateur
- Ajouter un contexte avant le traitement
- Filtrer ou valider l’entrée utilisateur
- Implémenter des modèles d’invite
Signature de point d'interception
import type { UserPromptSubmittedHookInput, HookInvocation, UserPromptSubmittedHookOutput } from "@github/copilot-sdk";
type UserPromptSubmittedHandler = (
input: UserPromptSubmittedHookInput,
invocation: HookInvocation
) => Promise<
UserPromptSubmittedHookOutput | 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 |
prompt | ficelle | Proposition soumise par l'utilisateur |
Sortie
Renvoyez null ou undefined, pour utiliser l’invite inchangée. Sinon, retournez un objet avec l’un des champs suivants.
| Champ | Type | Description |
|---|---|---|
modifiedPrompt | ficelle | Invite modifiée à utiliser à la place de l'originale. |
additionalContext | ficelle | Contexte supplémentaire ajouté à la conversation |
suppressOutput | booléen | Si la valeur est true, supprimez la réponse de l’assistant. |
Exemples
Journaliser toutes les invites de l’utilisateur
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (
input, invocation
) => {
console.log(
`[${invocation.sessionId}] `
+ `User: ${input.prompt}`
);
return null; // Pass through unchanged
},
},
});
Pour obtenir des exemples dans Python, Go et .NET, consultez le github/copilot-sdk référentiel.
Ajouter un contexte de projet
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (input) => {
const projectInfo = await getProjectInfo();
return {
additionalContext: `
Project: ${projectInfo.name}
Language: ${projectInfo.language}
Framework: ${projectInfo.framework}
`.trim(),
};
},
},
});
Élargir les commandes abrégées
const SHORTCUTS: Record<string, string> = {
"/fix":
"Please fix the errors in the code",
"/explain":
"Please explain this code in detail",
"/test":
"Please write unit tests for this code",
"/refactor":
"Please refactor this code to improve "
+ "readability and maintainability",
};
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (input) => {
for (const [shortcut, expansion]
of Object.entries(SHORTCUTS)) {
if (input.prompt.startsWith(shortcut)) {
const rest = input.prompt
.slice(shortcut.length).trim();
return {
modifiedPrompt:
`${expansion}`
+ `${rest ? `: ${rest}` : ""}`,
};
}
}
return null;
},
},
});
Filtrage du contenu
const BLOCKED_PATTERNS = [
/password\s*[:=]/i,
/api[_-]?key\s*[:=]/i,
/secret\s*[:=]/i,
];
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (input) => {
for (const pattern of BLOCKED_PATTERNS) {
if (pattern.test(input.prompt)) {
return {
modifiedPrompt:
"[Content blocked: Please don't "
+ "include sensitive credentials "
+ "in your prompts. Use environment "
+ "variables instead.]",
suppressOutput: true,
};
}
}
return null;
},
},
});
Imposer des limites de longueur de l'invite
const MAX_PROMPT_LENGTH = 10000;
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (input) => {
if (input.prompt.length > MAX_PROMPT_LENGTH) {
// Truncate the prompt and add context
return {
modifiedPrompt: input.prompt.substring(0, MAX_PROMPT_LENGTH),
additionalContext: `Note: The original prompt was ${input.prompt.length} characters and was truncated to ${MAX_PROMPT_LENGTH} characters.`,
};
}
return null;
},
},
});
Ajouter des préférences utilisateur
interface UserPreferences {
codeStyle: "concise" | "verbose";
preferredLanguage: string;
experienceLevel: "beginner" | "intermediate" | "expert";
}
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (input) => {
const prefs: UserPreferences = await loadUserPreferences();
const contextParts = [];
if (prefs.codeStyle === "concise") {
contextParts.push("User prefers concise code with minimal comments.");
} else {
contextParts.push("User prefers verbose code with detailed comments.");
}
if (prefs.experienceLevel === "beginner") {
contextParts.push("Explain concepts in simple terms.");
}
return {
additionalContext: contextParts.join(" "),
};
},
},
});
Limitation de débit de données
const promptTimestamps: number[] = [];
const RATE_LIMIT = 10; // prompts
const RATE_WINDOW = 60000; // 1 minute
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (input) => {
const now = Date.now();
// Remove timestamps outside the window
while (promptTimestamps.length > 0 && promptTimestamps[0] < now - RATE_WINDOW) {
promptTimestamps.shift();
}
if (promptTimestamps.length >= RATE_LIMIT) {
return {
reject: true,
rejectReason: `Rate limit exceeded. Please wait before sending more prompts.`,
};
}
promptTimestamps.push(now);
return null;
},
},
});
Modèles d’invite
const TEMPLATES: Record<
string, (args: string) => string
> = {
"bug:": (desc) =>
`I found a bug: ${desc}\n\n`
+ `Please help me:\n`
+ `1. Understand why this is happening\n`
+ `2. Suggest a fix\n`
+ `3. Explain how to prevent similar bugs`,
"feature:": (desc) =>
`I want to implement this feature: `
+ `${desc}\n\n`
+ `Please:\n`
+ `1. Outline the implementation approach\n`
+ `2. Identify potential challenges\n`
+ `3. Provide sample code`,
};
const session = await client.createSession({
hooks: {
onUserPromptSubmitted: async (input) => {
for (const [prefix, template]
of Object.entries(TEMPLATES)) {
if (
input.prompt.toLowerCase()
.startsWith(prefix)
) {
const args = input.prompt
.slice(prefix.length).trim();
return {
modifiedPrompt: template(args),
};
}
}
return null;
},
},
});
Bonnes pratiques
-
**Conservez l’intention de l’utilisateur.** Lors de la modification des invites, assurez-vous que l’intention principale reste claire. -
**Soyez transparent sur les modifications.** Si vous modifiez considérablement une invite, envisagez de journaliser ou de notifier l’utilisateur. -
**Utilisez `additionalContext` plutôt que `modifiedPrompt`.** L’ajout de contexte est moins intrusif que la réécriture de l’invite. -
**Fournissez des raisons claires de rejet.** Lorsqu'on rejette des instructions, expliquez pourquoi et comment résoudre le problème. -
**Maintenez un traitement rapide.** Ce hook s’exécute sur chaque message utilisateur. Évitez les opérations lentes.
Lectures complémentaires
-
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/quickstart) -
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/session-lifecycle) -
[AUTOTITLE](/copilot/how-tos/copilot-sdk/use-hooks/pre-tool-use)