Skip to main content

Enlace enviado de la solicitud de usuario

Utiliza el onUserPromptSubmitted gancho para modificar mensajes, agregar contexto y filtrar la entrada del usuario en SDK de Copilot.

¿Quién puede utilizar esta característica?

SDK de GitHub Copilot está disponible con todos los Copilot planes.

Nota:

SDK de Copilot actualmente está en Versión preliminar técnica. La funcionalidad y la disponibilidad están sujetas a cambios.

Se llama al onUserPromptSubmitted gancho cuando un usuario envía un mensaje. Utilícelo para:

  • Modificar o mejorar las indicaciones del usuario
  • Adición de contexto antes del procesamiento
  • Filtrar o validar la entrada del usuario
  • Implementación de plantillas de aviso

Firma de hook

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

Para obtener firmas de enlace en Python, Go y .NET, consulte el github/copilot-sdk repositorio.

Entrada

CampoTipoDescripción
timestampnúmeroMarca de tiempo de Unix cuando se desencadenó el enlace
cwdcuerda / cadenaDirectorio de trabajo actual
promptcuerda / cadenaMensaje enviado por el usuario

Salida

Devuelve null o undefined para usar el símbolo del sistema sin cambios. De lo contrario, devuelve un objeto con cualquiera de los campos siguientes.

CampoTipoDescripción
modifiedPromptcuerda / cadenaSolicitud modificada para usar en lugar de la original
additionalContextcuerda / cadenaContexto adicional agregado a la conversación
suppressOutputbooleanSi es true, suprima la salida de respuesta del asistente.

Ejemplos

Registro de todas las solicitudes de usuario

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

Para obtener ejemplos en Python, Go y .NET, consulte el github/copilot-sdk repositorio.

Agregar contexto del proyecto

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

Filtrado de contenido

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

Exigir longitudes de límite de avisos

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

Agregar preferencias de usuario

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

Limitación de velocidad

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

Plantillas de solicitud

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

procedimientos recomendados

  •         **Conservar la intención del usuario.** Al modificar las solicitudes, asegúrese de que la intención principal permanece clara.
    
  •         **Sea transparente sobre las modificaciones.** Si cambia significativamente un mensaje, considere la posibilidad de registrar o notificar al usuario.
    
  •         **Use `additionalContext` sobre `modifiedPrompt`.** Agregar contexto es menos intrusivo que volver a escribir la sugerencia.
    
  •         **Proporcione razones claras de rechazo.** Al rechazar mensajes, explique por qué y cómo corregir el problema.
    
  •         **Siga procesando rápidamente.** Este gancho se ejecuta en cada mensaje de usuario. Evite las operaciones lentas.
    

Lectura 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)