Skip to main content

Gancho enviado pelo prompt do usuário

Use o onUserPromptSubmitted gancho para modificar prompts, adicionar contexto e filtrar a entrada do usuário em SDK do Copilot.

Quem pode usar esse recurso?

SDK do GitHub Copilot está disponível com todos os Copilot planos.

Observação

SDK do Copilot está atualmente em versão prévia técnica. A funcionalidade e a disponibilidade estão sujeitas a alterações.

O onUserPromptSubmitted gancho é chamado quando um usuário envia uma mensagem. Use-o para:

  • Modificar ou aprimorar as sugestões/avisos do usuário
  • Adicionar contexto antes do processamento
  • Filtrar ou validar a entrada do usuário
  • Implementar modelos de prompt

Assinatura de Hook

import type { UserPromptSubmittedHookInput, HookInvocation, UserPromptSubmittedHookOutput } from "@github/copilot-sdk";
type UserPromptSubmittedHandler = (
  input: UserPromptSubmittedHookInput,
  invocation: HookInvocation
) => Promise<
  UserPromptSubmittedHookOutput | null | undefined
>;

Para obter assinaturas de hooks em Python, Go e .NET, consulte o github/copilot-sdk repositório.

Entrada

CampoTipoDescrição
timestampnúmeroTimestamp Unix quando o hook foi acionado
cwdcadeiaDiretório de trabalho atual
promptcadeiaO prompt enviado pelo usuário

Saída

Retornar null ou undefined para usar o prompt inalterado. Caso contrário, retorne um objeto com qualquer um dos campos a seguir.

CampoTipoDescrição
modifiedPromptcadeiaPrompt modificado para ser usado em vez do original
additionalContextcadeiaContexto extra adicionado à conversa
suppressOutputbooleanSe for true, suprime a saída de resposta do assistente

Exemplos

Registrar todos os prompts do usuário

const session = await client.createSession({
  hooks: {
    onUserPromptSubmitted: async (
      input, invocation
    ) => {
      console.log(
        `[${invocation.sessionId}] `
        + `User: ${input.prompt}`
      );
      return null; // Pass through unchanged
    },
  },
});

Para obter exemplos em Python, Go e .NET, consulte o github/copilot-sdk repositório.

Adicionar contexto de projeto

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(),
      };
    },
  },
});

Expandir comandos abreviados

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;
    },
  },
});

Filtragem de conteúdo

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;
    },
  },
});

Aplicar limites de comprimento para prompts

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;
    },
  },
});

Adicionar preferências do usuário

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(" "),
      };
    },
  },
});

Limitação de taxa

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;
    },
  },
});

Modelos de prompt

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;
    },
  },
});

Práticas recomendadas

  •         **Preservar a intenção do usuário.** Ao modificar prompts, verifique se a intenção principal permanece clara.
    
  •         **Seja transparente sobre modificações.** Se você alterar significativamente um prompt, considere registrar ou notificar o usuário.
    
  •         **Use `additionalContext` over `modifiedPrompt`.** Adicionar contexto é menos intrusivo do que reescrever o prompt.
    
  •         **Forneça razões claras de rejeição.** Ao rejeitar prompts, explique por que e como corrigir o problema.
    
  •         **Mantenha o processamento rápido.** Esse gancho é executado em cada mensagem de usuário. Evite operações lentas.
    

Leitura adicional

  •         [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)