Thanks to visit codestin.com
Credit goes to docs.github.com

Skip to main content

Enlace enviado de la solicitud de usuario

Se llama al onUserPromptSubmitted gancho cuando un usuario envía un mensaje. Úselo 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 gancho

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

UserPromptSubmittedHandler = Callable[
    [UserPromptSubmittedHookInput, dict[str, str]],
    Awaitable[UserPromptSubmittedHookOutput | None]
]
UserPromptSubmittedHandler = Callable[
    [UserPromptSubmittedHookInput, dict[str, str]],
    Awaitable[UserPromptSubmittedHookOutput | None]
]
Go
package main

import copilot "github.com/github/copilot-sdk/go"

type UserPromptSubmittedHandler func(
    input copilot.UserPromptSubmittedHookInput,
    invocation copilot.HookInvocation,
) (*copilot.UserPromptSubmittedHookOutput, error)

func main() {}
type UserPromptSubmittedHandler func(
    input UserPromptSubmittedHookInput,
    invocation HookInvocation,
) (*UserPromptSubmittedHookOutput, error)
.NET
using GitHub.Copilot;

public delegate Task<UserPromptSubmittedHookOutput?> UserPromptSubmittedHandler(
    UserPromptSubmittedHookInput input,
    HookInvocation invocation);
public delegate Task<UserPromptSubmittedHookOutput?> UserPromptSubmittedHandler(
    UserPromptSubmittedHookInput input,
    HookInvocation invocation);
Java
import com.github.copilot.rpc.*;
import java.util.concurrent.CompletableFuture;

public class UserPromptSubmittedSignature {
    UserPromptSubmittedHandler handler = (UserPromptSubmittedHookInput input, HookInvocation invocation) ->
        CompletableFuture.completedFuture(null);
    public static void main(String[] args) {}
}
@FunctionalInterface
public interface UserPromptSubmittedHandler {
    CompletableFuture<UserPromptSubmittedHookOutput> handle(
        UserPromptSubmittedHookInput input,
        HookInvocation invocation);
}

Entrada

CampoTipoDescripción
timestampnumberMarca de tiempo de Unix cuando se desencadenó el hook
cwdstringDirectorio de trabajo actual
promptstringMensaje enviado por el usuario

Output

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

CampoTipoDescripción
modifiedPromptstringSolicitud modificada para usar en lugar de la original
additionalContextstringContexto adicional agregado a la conversación
suppressOutputbooleanSi es true, suprima la salida de respuesta del asistente.

Ejemplos

Registro de todas las solicitudes de usuario

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

async def on_user_prompt_submitted(input_data, invocation):
    print(f"[{invocation['session_id']}] User: {input_data['prompt']}")
    return None

session = await client.create_session(on_permission_request=PermissionHandler.approve_all, hooks={"on_user_prompt_submitted": on_user_prompt_submitted})
Go
package main

import (
    "context"
    "fmt"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    client := copilot.NewClient(nil)
    session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
        OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
        Hooks: &copilot.SessionHooks{
            OnUserPromptSubmitted: func(input copilot.UserPromptSubmittedHookInput, inv copilot.HookInvocation) (*copilot.UserPromptSubmittedHookOutput, error) {
                fmt.Printf("[%s] User: %s\n", inv.SessionID, input.Prompt)
                return nil, nil
            },
        },
    })
    _ = session
}
session, _ := client.CreateSession(context.Background(), &copilot.SessionConfig{
    Hooks: &copilot.SessionHooks{
        OnUserPromptSubmitted: func(input copilot.UserPromptSubmittedHookInput, inv copilot.HookInvocation) (*copilot.UserPromptSubmittedHookOutput, error) {
            fmt.Printf("[%s] User: %s\n", inv.SessionID, input.Prompt)
            return nil, nil
        },
    },
})
.NET
using GitHub.Copilot;

public static class UserPromptSubmittedExample
{
    public static async Task Main()
    {
        await using var client = new CopilotClient();
        var session = await client.CreateSessionAsync(new SessionConfig
        {
            Hooks = new SessionHooks
            {
                OnUserPromptSubmitted = (input, invocation) =>
                {
                    Console.WriteLine($"[{invocation.SessionId}] User: {input.Prompt}");
                    return Task.FromResult<UserPromptSubmittedHookOutput?>(null);
                },
            },
        });
    }
}
var session = await client.CreateSessionAsync(new SessionConfig
{
    Hooks = new SessionHooks
    {
        OnUserPromptSubmitted = (input, invocation) =>
        {
            Console.WriteLine($"[{invocation.SessionId}] User: {input.Prompt}");
            return Task.FromResult<UserPromptSubmittedHookOutput?>(null);
        },
    },
});
Java
import com.github.copilot.*;
import com.github.copilot.rpc.*;
import java.util.concurrent.CompletableFuture;

var hooks = new SessionHooks()
    .setOnUserPromptSubmitted((input, invocation) -> {
        System.out.println("[" + invocation.getSessionId() + "] User: " + input.prompt());
        return CompletableFuture.completedFuture(null);
    });

var session = client.createSession(
    new SessionConfig()
        .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
        .setHooks(hooks)
).get();

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)) {
          // Replace the prompt with a warning message
          return {
            modifiedPrompt: "[Content blocked: Please don't include sensitive credentials in your prompts. Use environment variables instead.]",
            suppressOutput: true,
          };
        }
      }
      return null;
    },
  },
});

Aplicar límites de longitud a los 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;
    },
  },
});

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}

Please help me:
1. Understand why this is happening
2. Suggest a fix
3. Explain how to prevent similar bugs`,

  "feature:": (desc) => `I want to implement this feature: ${desc}

Please:
1. Outline the implementation approach
2. Identify potential challenges
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

  1. Conservar la intención del usuario : al modificar las solicitudes, asegúrese de que la intención principal permanece clara.

  2. Ser transparente acerca de las modificaciones : si cambia significativamente un mensaje, considere la posibilidad de registrar o notificar al usuario.

  3. Usa additionalContext en lugar de modifiedPrompt - Añadir contexto es menos intrusivo que reescribir la instrucción.

  4. Proporcionar motivos de rechazo claros : al rechazar mensajes, explique por qué y cómo corregirlo.

  5. Mantén el procesamiento rápido - Este hook se ejecuta con cada mensaje del usuario. Evite las operaciones lentas.

Consulte también