Proveedores de Contexto
Los Proveedores de Contexto te permiten escribir '@' y ver un menú desplegable de contenido que se puede utilizar como contexto para el LLM. Cada proveedor de contexto es un plugin, lo que significa que si deseas referenciar alguna fuente de información que no ves aquí, puedes solicitar (o crear) un nuevo proveedor de contexto.
Como ejemplo, supongamos que estás trabajando en resolver un nuevo Issue de GitHub. Escribes '@issue' y seleccionas el que estás trabajando. Continue ahora puede ver el título y el contenido del issue. También sabes que el issue está relacionado con los archivos 'readme.md' y 'helloNested.py', así que escribes '@readme' y '@hello' para encontrarlos y seleccionarlos. Ahora estos 3 "Elementos de Contexto" se muestran en línea con el resto de tu entrada.
Proveedores de Contexto Integrados
Para usar cualquiera de los proveedores de contexto integrados, abre ~/.continue/config.json
y agrégalo a la lista de contextProviders
.
Archivos
Escribe '@file' para referenciar cualquier archivo en tu espacio de trabajo actual.
{ "name": "file" }
Código
Escribe '@code' para referenciar funciones o clases específicas de todo tu proyecto.
{ "name": "code" }
Git Diff
Escribe '@diff' para referenciar todos los cambios que has realizado en tu rama actual. Esto es útil si deseas resumir lo que has hecho o pedir una revisión general de tu trabajo antes de hacer un commit.
{ "name": "diff" }
Terminal
Escribe '@terminal' para referenciar el contenido del terminal de tu IDE.
{ "name": "terminal" }
Documentación
Escriba @docs
para indexar y recuperar fragmentos de cualquier sitio de documentación. Puede agregar cualquier sitio seleccionando "Agregar Documentación" en el menú desplegable, luego ingresando la URL raíz del sitio de documentación y un título para recordarlo. Después de que el sitio ha sido indexado, puede escribir @docs
, seleccionar su documentación del menú desplegable, y Continue utilizará la búsqueda por similitud para encontrar automáticamente secciones importantes al responder su pregunta.
{ "name": "docs" }
Continue también pre-indexa una serie de sitios comunes, listados aquí. Las incrustaciones para estos sitios son alojadas por nosotros, pero descargadas para uso local después de la primera vez. Toda la demás indexación ocurre completamente de manera local.
Agregar un Sitio de Documentación mediante Configuración
Para agregar un sitio de documentación mediante configuración, actualice el archivo config.json
de la siguiente manera:
{
"name": "docs",
"params": {
"sites": [
{
"title": "ExampleDocs",
"startUrl": "https://exampledocs.com/docs",
"rootUrl": "https://exampledocs.com",
"maxDepth": 3 // Valor por defecto
}
]
}
}
Los documentos se indexan cuando modifica el archivo de configuración, a menos que la indexación esté deshabilitada. Si desea activar la indexación manualmente, puede usar el comando Continue: Docs Index
. Para forzar la indexación, puede usar el comando Continue: Docs Force Re-Index
. Tenga en cuenta que estos comandos funcionarán incluso si la indexación automática está deshabilitada.
Archivos Abiertos
Escriba @open
para hacer referencia al contenido de todos sus archivos abiertos. Configure onlyPinned
en true
para hacer referencia solo a los archivos fijados.
{ "name": "open", "params": { "onlyPinned": true } }
Recuperación de la Base de Código
Escriba @codebase
para recuperar automáticamente los fragmentos más relevantes de su base de código. Lea más sobre la indexación y recuperación aquí.
{ "name": "codebase" }
Carpetas
Escriba @folder
para usar el mismo mecanismo de recuperación que @codebase
, pero solo en una carpeta.
{ "name": "folder" }
Búsqueda Exacta
Escriba @search
para hacer referencia a los resultados de la búsqueda en la base de código, al igual que los resultados que obtendría de la búsqueda en VS Code. Este proveedor de contexto está impulsado por ripgrep.
{ "name": "search" }
URL
Escriba @url
e ingrese una URL, luego Continue la convertirá en un documento markdown para pasar al modelo.
{ "name": "url" }
Árbol de Archivos
Escriba @tree
para hacer referencia a la estructura de su espacio de trabajo actual. El LLM podrá ver la estructura de directorios anidados de su proyecto.
{ "name": "tree" }
Google
Escriba @google
para hacer referencia a los resultados de una búsqueda en Google. Por ejemplo, escriba "@google tutorial de python" si desea buscar y discutir formas de aprender Python.
{
"name": "google",
"params": { "serperApiKey": "<tu clave API de serper.dev>" }
}
Nota: Puede obtener una clave API de forma gratuita en serper.dev.
Issues de GitHub
Escriba @issue
para hacer referencia a la conversación en un problema de GitHub. Asegúrese de incluir su propio token de acceso personal de GitHub para evitar ser limitado por la tasa:
{
"name": "issue",
"params": {
"repos": [
{
"owner": "continuedev",
"repo": "continue"
}
],
"githubToken": "ghp_xxx"
}
}
Solicitud de Fusión de GitLab
Escriba @gitlab-mr
para hacer referencia a una solicitud de fusión abierta para esta rama en GitLab.
Configuración
Necesitará crear un token de acceso personal con el alcance read_api
. Luego, agregue lo siguiente a su configuración:
{
"name": "gitlab-mr",
"params": {
"token": "..."
}
}
Uso de GitLab Autohospedado
Puede especificar el dominio con el que comunicarse configurando el parámetro domain
en su configuración. De forma predeterminada, esto está configurado en gitlab.com
.
{
"name": "gitlab-mr",
"params": {
"token": "...",
"domain": "gitlab.example.com"
}
}
Filtrando Comentarios
Si selecciona algún código para ser editado, puede hacer que el proveedor de contexto filtre los comentarios de otros archivos. Para habilitar esta función, configure filterComments
en true
.
Issues de Jira
Escriba @jira
para hacer referencia a la conversación en un problema de Jira. Asegúrese de incluir su propio Token API de Atlassian, o use su email
y token
, con el token configurado como su contraseña para autenticación básica. Si usa su propio Token API de Atlassian, no configure su correo electrónico.
{
"name": "jira",
"params": {
"domain": "company.atlassian.net",
"token ": "ATATT..."
}
}
Soporte para Jira Datacenter
Este proveedor de contexto admite tanto la versión 2 como la versión 3 de la API de Jira. Usará la versión 3 de forma predeterminada, ya que es la que usa la versión en la nube, pero si tiene la versión del centro de datos de Jira, necesitará configurar la Versión de la API a 2 usando la propiedad apiVersion
.
"params": {
"apiVersion": "2",
...
}
Consulta de Problemas
De forma predeterminada, se utilizará la siguiente consulta para encontrar problemas:
assignee = currentUser() AND resolution = Unresolved order by updated DESC
Puede anular esta consulta configurando el parámetro issueQuery
.
PostgreSQL
Escriba @postgres
para hacer referencia al esquema de una tabla y algunas filas de muestra. Aparecerá un menú desplegable que le permitirá seleccionar una tabla específica o todas las tablas.
Los únicos parámetros requeridos son aquellos para crear la conexión a la base de datos: host
, port
, user
, password
y database
.
De forma predeterminada, el filtro schema
está configurado en public
y sampleRows
está configurado en 3. Puede desactivar el esquema si desea incluir tablas de todos los esquemas.
Aquí hay una breve demostración.
{
"name": "postgres",
"params": {
"host": "localhost",
"port": 5436,
"user": "myuser",
"password": "catsarecool",
"database": "animals",
"schema": "public",
"sampleRows": 3
}
}
Tablas de la Base de Datos
Escriba @database
para hacer referencia a los esquemas de las tablas. Puede usar el menú desplegable o comenzar a escribir los nombres de las tablas basándose en su configuración. La configuración admite múltiples bases de datos, lo que le permite especificar varios detalles de conexión para PostgreSQL, MySQL y SQLite. Cada conexión debe incluir un nombre único, el tipo de conexión (por ejemplo, postgres, sqlite) y los parámetros de conexión necesarios específicos para cada tipo de base de datos.
{
"name": "database",
"params": {
"connections": [
{
"name": "examplePostgres",
"connection_type": "postgres",
"connection": {
"user": "username",
"host": "localhost",
"database": "exampleDB",
"password": "yourPassword",
"port": 5432
}
},
{
"name": "exampleSqlite",
"connection_type": "sqlite",
"connection": {
"filename": "/path/to/your/sqlite/database.db"
}
}
]
}
}
Depurador: Variables Locales
Escriba @locals
para hacer referencia al contenido de las variables locales con el nivel superior n (predeterminado en 3) de la pila de llamadas para ese hilo. Aparecerá un menú desplegable que le permitirá seleccionar un hilo específico para ver las variables locales en ese hilo.
{
"name": "locals",
"params": {
"stackDepth": 3
}
}
Sistema Operativo
Escriba @os
para hacer referencia a la arquitectura y plataforma de su sistema operativo actual.
{ "name": "os" }
Solicitud de Proveedores de Contexto
¿No encuentra lo que quiere? Cree un problema aquí para solicitar un nuevo proveedor de contexto.
Crear su Propio Proveedor de Contexto
Ejemplo Introductorio
Para escribir su propio proveedor de contexto, solo tiene que implementar la interfaz CustomContextProvider
:
interface CustomContextProvider {
title: string;
displayTitle?: string;
description?: string;
renderInlineAs?: string;
type?: ContextProviderType;
getContextItems(
query: string,
extras: ContextProviderExtras
): Promise<ContextItem[]>;
loadSubmenuItems?: (
args: LoadSubmenuItemsArgs
) => Promise<ContextSubmenuItem[]>;
}
Como ejemplo, supongamos que tiene un conjunto de documentos internos que se han indexado en una base de datos vectorial. Ha configurado una API REST simple que permite a los usuarios internos consultar y obtener fragmentos relevantes. Este proveedor de contexto enviará la consulta a este servidor y devolverá los resultados de la base de datos vectorial. El tipo de retorno de getContextItems
debe ser una matriz de objetos que tengan todas las siguientes propiedades:
name
: El nombre del elemento de contexto, que se mostrará como un títulodescription
: Una descripción más larga del elemento de contextocontent
: El contenido real del elemento de contexto, que se alimentará al LLM como contexto
const RagContextProvider: CustomContextProvider = {
title: "rag",
displayTitle: "RAG",
description:
"Retrieve snippets from our vector database of internal documents",
getContextItems: async (
query: string,
extras: ContextProviderExtras
): Promise<ContextItem[]> => {
const response = await fetch("https://internal_rag_server.com/retrieve", {
method: "POST",
body: JSON.stringify({ query }),
});
const results = await response.json();
return results.map((result) => ({
name: result.title,
description: result.title,
content: result.contents,
}));
},
};
Luego se puede agregar en config.ts
de la siguiente manera:
export function modifyConfig(config: Config): Config {
if (!config.contextProviders) {
config.contextProviders = [];
}
config.contextProviders.push(RagContextProvider);
return config;
}
No es necesario modificar config.json
.
Proveedores de Contexto Personalizados con Submenú o Consulta
Hay 3 tipos de proveedores de contexto: "normal", "query" y "submenu". El tipo "normal" es el predeterminado y es el que hemos visto hasta ahora.
El tipo "query" se usa cuando desea mostrar un cuadro de texto al usuario y luego usar el contenido de ese cuadro de texto para generar los elementos de contexto. Los ejemplos integrados incluyen "search" y "google". Este texto es lo que se pasa al argumento "query" en getContextItems
. Para implementar un proveedor de contexto "query", simplemente establezca "type": "query"
en su objeto de proveedor de contexto personalizado.
El tipo "submenu" se usa cuando desea mostrar una lista de elementos buscables en el menú desplegable. Los ejemplos integrados incluyen "issue" y "folder". Para implementar un proveedor de contexto "submenu", establezca "type": "submenu"
e implemente las funciones loadSubmenuItems
y getContextItems
. Aquí hay un ejemplo que muestra una lista de todos los archivos README en el espacio de trabajo actual:
const ReadMeContextProvider: CustomContextProvider = {
title: "readme",
displayTitle: "README",
description: "Reference README.md files in your workspace",
type: "submenu",
getContextItems: async (
query: string,
extras: ContextProviderExtras
): Promise<ContextItem[]> => {
// 'query' is the filepath of the README selected from the dropdown
const content = await extras.ide.readFile(query);
return [
{
name: getFolder(query),
description: getFolderAndBasename(query),
content,
},
];
},
loadSubmenuItems: async (
args: LoadSubmenuItemsArgs
): Promise<ContextSubmenuItem[]> => {
// Filter all workspace files for READMEs
const allFiles = await args.ide.listWorkspaceContents();
const readmes = allFiles.filter((filepath) =>
filepath.endsWith("README.md")
);
// Return the items that will be shown in the dropdown
return readmes.map((filepath) => {
return {
id: filepath,
title: getFolder(filepath),
description: getFolderAndBasename(filepath),
};
});
},
};
export function modifyConfig(config: Config): Config {
if (!config.contextProviders) {
config.contextProviders = [];
}
config.contextProviders.push(ReadMeContextProvider);
return config;
}
function getFolder(path: string): string {
return path.split(/[\/\\]/g).slice(-2)[0];
}
function getFolderAndBasename(path: string): string {
return path
.split(/[\/\\]/g)
.slice(-2)
.join("/");
}
El flujo de información en el ejemplo anterior es el siguiente:
- El usuario escribe
@readme
y lo selecciona del menú desplegable, ahora mostrando el submenú donde pueden buscar cualquier elemento devuelto porloadSubmenuItems
. - El usuario selecciona uno de los README en el submenú, ingresa el resto de su entrada y presiona enter.
- El
id
delContextSubmenuItem
elegido se pasa agetContextItems
como el argumentoquery
. En este caso, es la ruta del README. - La función
getContextItems
puede usar laquery
para recuperar el contenido completo del README y formatear el contenido antes de devolver el elemento de contexto que se incluirá en el aviso.
Importación de Módulos Externos
Para incluir módulos Node externos en su config.ts, ejecute npm install <module_name>
desde el directorio ~/.continue
, y luego impórtelos en config.ts.
Continue usará esbuild para empaquetar su config.ts
y cualquier dependencia en un solo archivo Javascript. La configuración exacta utilizada se puede encontrar aquí.
Referencia de CustomContextProvider
title
: Un identificador para el proveedor de contextodisplayTitle
(opcional): El título que se muestra en el menú desplegabledescription
(opcional): La descripción más larga que se muestra en el menú desplegable al pasar el cursortype
(opcional): El tipo de proveedor de contexto. Las opciones son "normal", "query" y "submenu". Por defecto es "normal".renderInlineAs
(opcional): La cadena que se renderizará en línea en la parte superior del aviso. Si no se proporciona ningún valor, se usará eldisplayTitle
predeterminado. Se puede proporcionar una cadena vacía para evitar la representación deldisplayTitle
predeterminado.getContextItems
: Una función que devuelve los documentos a incluir en el aviso. Debe devolver una lista deContextItem
s, y tiene acceso a los siguientes argumentos:extras.fullInput
: Una cadena que representa la entrada completa del usuario en el cuadro de texto. Esto se puede usar, por ejemplo, para generar una incrustación para comparar con un conjunto de otros documentos incrustadosextras.embeddingsProvider
: El proveedor de incrustaciones tiene una funciónembed
que convertirá el texto (comofullInput
) en una incrustaciónextras.llm
: El LLM predeterminado actual, que puede usar para hacer solicitudes de finalizaciónextras.ide
: Una instancia de la claseIDE
, que le permite recopilar diversas fuentes de información del IDE, incluido el contenido del terminal, la lista de archivos abiertos o cualquier advertencia en el archivo actualmente abierto.query
: (actualmente no utilizado) Una cadena que representa la consulta
loadSubmenuItems
(opcional): Una función que devuelve una lista deContextSubmenuItem
s para mostrar en un submenú. Tiene acceso a unIDE
, el mismo que se pasa agetContextItems
.
Escribir Proveedores de Contexto en Otros Idiomas
Si desea escribir un proveedor de contexto en un idioma que no sea TypeScript, puede usar el proveedor de contexto "http" para llamar a un servidor que aloje su propio código. Agregue el proveedor de contexto a config.json
de esta manera:
{
"name": "http",
"params": {
"url": "https://myserver.com/context-provider",
"title": "http",
"description": "Custom HTTP Context Provider",
"displayTitle": "My Custom Context"
}
}
Luego, cree un servidor que responda a solicitudes como las que se realizan desde HttpContextProvider.ts. Vea el punto final hello
en context_provider_server.py para obtener un ejemplo que utiliza FastAPI.
API de Extensión para VSCode
Continue expone una API para registrar proveedores de contexto desde una extensión de VSCode de terceros. Esto es útil si tiene una extensión de VSCode que proporciona algún contexto adicional que le gustaría usar en Continue. Para usar esta API, agregue lo siguiente a su package.json
:
{
"extensionDependencies": ["continue.continue"]
}
O copie ~/.continue/type/core/index.d.ts
a su repositorio de extensiones.
Luego, puede usar la función registerCustomContextProvider
para registrar su proveedor de contexto. Su proveedor de contexto personalizado debe implementar la interfaz IContextProvider
.
Aquí hay un ejemplo:
import * as vscode from "vscode";
class MyCustomProvider implements IContextProvider {
get description(): ContextProviderDescription {
return {
title: "custom",
displayTitle: "Custom",
description: "Custom description",
type: "normal",
};
}
async getContextItems(
query: string,
extras: ContextProviderExtras
): Promise<ContextItem[]> {
return [
{
name: "Custom",
description: "Custom description",
content: "Custom content",
},
];
}
async loadSubmenuItems(
args: LoadSubmenuItemsArgs
): Promise<ContextSubmenuItem[]> {
return [];
}
}
// crea una instancia de tu proveedor personalizado
const customProvider = new MyCustomProvider();
// obtiene la extensión Continue usando la API de vscode
const continueExt = vscode.extensions.getExtension("continue.continue");
// obtiene la API de la extensión
const continueApi = continueExt?.exports;
// registra tu proveedor personalizado
continueApi?.registerCustomContextProvider(customProvider);
Detalles Importantes
-
Dependencias de Extensión: Asegúrese de que su
package.json
incluyacontinue.continue
enextensionDependencies
para garantizar que la extensión Continue esté instalada cuando se use su extensión. -
Implementación de
IContextProvider
: Su proveedor personalizado debe implementar la interfazIContextProvider
, lo que implica proporcionar los métodosgetContextItems
yloadSubmenuItems
(si es aplicable). -
Uso de la API de VSCode: Use
vscode.extensions.getExtension
para obtener la extensión Continue y luego acceda a su API para registrar su proveedor personalizado. -
Submenús (Opcional): Si su proveedor necesita submenús, implemente
loadSubmenuItems
para devolver los elementos del submenú.
Este enfoque permite integrar fácilmente nuevas fuentes de contexto personalizadas en Continue, aprovechando la funcionalidad extendida de VSCode.