Skills Framework (Español)
Agent Skills frente a Omni Skills
Sección titulada «Agent Skills frente a Omni Skills»OmniRoute tiene dos sistemas de skills distintos pero complementarios:
| Dimensión | Omni Skills (este documento) | Agent Skills |
|---|---|---|
| Propósito | Inyección de herramientas LLM + ejecución en entorno aislado | Catálogo SKILL.md para que agentes externos lo descubran y utilicen |
| Fuente de referencia | src/lib/skills/ + marketplace |
src/lib/agentSkills/ + directorio skills/ |
| Modo de ejecución | Se inyectan en solicitudes salientes y se ejecutan en eventos de llamada a herramientas | Catálogo Markdown estático + endpoints de descubrimiento REST/MCP/A2A |
| Quién lo utiliza | El propio OmniRoute (enrutamiento combinado, llamadas LLM entrantes) | Agentes externos, clientes MCP, orquestadores A2A |
| Cantidad | Variable (determinada por el marketplace) | 45 entradas de catálogo (23 de API + 21 de CLI + 1 de configuración) |
| Formato | SkillDefinition con esquema de herramienta + controlador |
Frontmatter de SKILL.md + cuerpo en Markdown |
| Descubrimiento | REST /api/skills/* + herramientas MCP omniroute_skills_* |
REST /api/agent-skills/* + herramientas MCP omniroute_agent_skills_* + list-capabilities de A2A |
Las Omni Skills son el motor de ejecución: definen lo que OmniRoute puede hacer cuando un LLM invoca una herramienta.
Las Agent Skills son el catálogo de documentación: explican a los agentes externos cómo utilizar la API REST y la CLI de OmniRoute mediante archivos SKILL.md estructurados que pueden incorporarse directamente a los prompts de los agentes.
Para obtener información sobre el catálogo de Agent Skills, el generador, las herramientas MCP y la skill A2A, consulta docs/frameworks/AGENT-SKILLS.md.
Conceptos
Sección titulada «Conceptos»Fuentes de skills
Sección titulada «Fuentes de skills»En el mismo registro coexisten tres fuentes de skills:
- Skills integradas (
src/lib/skills/builtins.ts) — incluidas con OmniRoute. Cubren los casos habituales:file_read,file_write— espacio de trabajo aislado por clave de API en<DATA_DIR>/skills/workspaces/<hashed-key>/http_request— HTTP saliente mediantesafeOutboundFetchconguard: "public-only"web_search— proveedor de búsqueda conectable con almacenamiento en caché (executeWebSearch)eval_code— ejecución denodeopythonen un entorno aislado de Dockerexecute_command— comando de shell ejecutado en un entorno aislado de Dockerbrowser— estructura basada en Playwright, deshabilitada de forma predeterminada (builtin/browser.ts)
- SkillsMP (el marketplace de OmniRoute) — obtenidas de
https://skillsmp.com/api/v1/skills/search. RequiereskillsmpApiKeyen Configuración. - SkillsSH (catálogo comunitario de
skills.sh) — obtenidas dehttps://skills.sh/api/search. No requiere autenticación; el contenido de SKILL.md se obtiene directamente desde GitHub raw.
Un único «proveedor activo» controla desde qué catálogo realiza las instalaciones el panel (src/lib/skills/providerSettings.ts). Cámbialo en Configuración → Memoria y skills. Valor predeterminado: skillsmp.
Identidad de las skills
Sección titulada «Identidad de las skills»Las skills se identifican mediante name@version en el registro en memoria (src/lib/skills/registry.ts). La versión debe seguir semver (^\d+\.\d+\.\d+$). resolveVersion() reconoce las restricciones ^, ~, >, >=, <, <=, == y de coincidencia exacta.
Modo de las skills
Sección titulada «Modo de las skills»Cada skill tiene un modo de ejecución que controla cuándo se inyecta:
| Modo | Comportamiento |
|---|---|
on |
Siempre se inyecta como definición de herramienta |
off |
Nunca se inyecta ni se puede ejecutar |
auto |
Se puntúa con respecto a la solicitud entrante; solo se inyecta si la puntuación ≥ AUTO_MIN_SCORE (valor predeterminado: 3) |
auto es el valor predeterminado para las skills instaladas desde el marketplace. enabled=true y mode="off" juntos significan «registrada pero inactiva»; cambiar enabled mediante la columna heredada también actualiza mode para que las rutas de código antiguas sigan siendo coherentes (src/app/api/skills/[id]/route.ts).
Estado (ejecuciones)
Sección titulada «Estado (ejecuciones)»Las ejecuciones de skills se registran en la tabla skill_executions con los siguientes estados (src/lib/skills/types.ts):
enum SkillStatus { PENDING = "pending", RUNNING = "running", SUCCESS = "success", ERROR = "error", TIMEOUT = "timeout",}Caché del registro
Sección titulada «Caché del registro»SkillRegistry es un singleton con una caché TTL de 60 segundos (registry.ts:14). loadFromDatabase() es idempotente y elimina las llamadas simultáneas duplicadas mediante pendingLoad. Cualquier escritura (register/unregister/unregisterById) invalida la caché. Consulta las versiones mediante getSkillVersions(name) y resolveVersion(name, constraint).
Inyección específica del proveedor
Sección titulada «Inyección específica del proveedor»injectSkills() en src/lib/skills/injection.ts es el punto de entrada que convierte las skills registradas en definiciones de herramientas específicas del proveedor:
- OpenAI —
{ type: "function", function: { name, description, parameters } } - Anthropic —
{ name, description, input_schema } - Google (Gemini) —
{ name, description, parameters }
El nombre de la herramienta se codifica como name@version para que el controlador pueda seleccionar la versión correcta cuando el modelo vuelva a invocarla.
Puntuación AUTO
Sección titulada «Puntuación AUTO»Cuando mode="auto", cada habilidad candidata se puntúa en función del contexto de la solicitud (scoreAutoSkill() en injection.ts):
| Señal | Puntos |
|---|---|
| El nombre de la habilidad aparece literalmente en el contexto | +6 |
| Cada token del nombre coincide con un token del contexto | +2 |
| Cada subcadena de etiqueta coincide con el contexto | +3 |
| Cada token de la descripción coincide con el contexto | +1 |
| El motivo en segundo plano coincide con un token del nombre | +2 por token |
| El motivo en segundo plano coincide con una etiqueta | +2 por token |
| La sugerencia de proveedor en las etiquetas coincide con el proveedor de la solicitud | +2 / −2 |
Se inyectan las AUTO_MAX_SKILLS = 5 habilidades principales con score >= AUTO_MIN_SCORE = 3. Los empates se resuelven por installCount (descendente) y, después, por el nombre en orden alfabético (injection.ts:225-235).
Interceptación de llamadas a herramientas
Sección titulada «Interceptación de llamadas a herramientas»El controlador de chat invoca handleToolCallExecution() en src/lib/skills/interception.ts después de que el proveedor ascendente devuelve una respuesta con una llamada a una herramienta:
extractToolCalls()lee los formatos específicos de cada proveedor (OpenAItool_calls/ Responsesfunction_call, Anthropictool_use, GeminifunctionCalls).- Primero se resuelven los alias de herramientas integradas (p. ej.,
omniroute_web_search→web_search). Los controladores integrados se ejecutan en línea. - Todo lo demás se enruta mediante
skillExecutor.execute(name@version, args, { apiKeyId, sessionId }). - Los resultados se vuelven a insertar en la respuesta: elementos
tool_results,function_call_outputo bloquestool_resultde Anthropic, según corresponda.
customSkillExecutionEnabled en el contexto de ejecución puede establecerse en false para permitir únicamente la interceptación integrada (se utiliza en rutas de solicitud que deshabilitan explícitamente los controladores definidos por el usuario).
Entorno aislado de Docker
Sección titulada «Entorno aislado de Docker»Las rutas de código no integradas (eval_code, execute_command) se ejecutan dentro de Docker mediante SandboxRunner (src/lib/skills/sandbox.ts). Cada contenedor se inicia con:
--rm --network none|bridge --cap-drop ALL--security-opt no-new-privileges --pids-limit 100--cpus <cpuLimit/1000> --memory <memoryLimit>m--tmpfs /tmp:rw,noexec,nosuid,size=64m--tmpfs /workspace:rw,noexec,nosuid,size=64m--read-only (cuando readOnly=true)Valores predeterminados (SandboxRunner.DEFAULT_CONFIG):
| Campo | Valor predeterminado | Notas |
|---|---|---|
cpuLimit |
100 (= 0.1 CPU) | Se divide por 1000 antes de pasarlo a --cpus |
memoryLimit |
256 MB | Límite estricto |
timeout |
30000 ms | Terminación suave mediante SIGTERM + docker kill |
networkEnabled |
false |
Se convierte en --network none |
readOnly |
true |
FS raíz de solo lectura; /tmp y /workspace son tmpfs |
SandboxRunner.kill(id) y killAll() están disponibles para el apagado; los contenedores en ejecución se registran en runningContainers: Map<string, ChildProcess>.
Variables de entorno del entorno aislado
Sección titulada «Variables de entorno del entorno aislado»Configuradas mediante process.env en src/lib/skills/builtins.ts:
| Variable de entorno | Valor predeterminado | Propósito |
|---|---|---|
SKILLS_MAX_FILE_BYTES |
1048576 (1 MB) |
Límite para file_read y file_write |
SKILLS_MAX_HTTP_RESPONSE_BYTES |
256000 |
Límite para el cuerpo de la respuesta de http_request |
SKILLS_MAX_SANDBOX_OUTPUT_CHARS |
100000 |
Límite para stdout/stderr devueltos al invocador |
SKILLS_SANDBOX_TIMEOUT_MS |
10000 |
Tiempo de espera predeterminado para comandos aislados; limitado a 60 s |
SKILLS_SANDBOX_NETWORK_ENABLED |
false |
Control maestro para la salida. Establezca 1 o true para permitir la activación por llamada |
SKILLS_ALLOWED_SANDBOX_IMAGES |
(véase abajo) | Lista separada por comas de imágenes de Docker permitidas |
Imágenes permitidas de forma predeterminada: alpine:3.20, node:22-alpine, python:3.12-alpine. Cualquier adición mediante SKILLS_ALLOWED_SANDBOX_IMAGES se combina con los valores predeterminados; normalizeImage() rechaza las imágenes desconocidas.
Nota: no existe una variable de entorno
SKILLS_EXECUTION_TIMEOUT_MSindependiente. El tiempo de espera del controlador no aislado está fijado en 30 s enSkillExecutor(executor.ts:13), pero puede sobrescribirse en tiempo de ejecución medianteskillExecutor.setTimeout(ms).
Aislamiento del espacio de trabajo
Sección titulada «Aislamiento del espacio de trabajo»file_read y file_write resuelven cada ruta con respecto a un espacio de trabajo por clave de API ubicado en <DATA_DIR>/skills/workspaces/<sha256(apiKeyId).slice(0,24)>/. El recorrido de rutas (..) y los segmentos prohibidos (.env, .git, .ssh, .omniroute, .codex, secrets) se rechazan antes de cualquier operación de E/S en disco.
Refuerzo de HTTP
Sección titulada «Refuerzo de HTTP»http_request (builtins.ts:257):
- Lista de métodos permitidos:
GET, HEAD, POST, PUT, PATCH, DELETE - Encabezados salientes bloqueados:
host, connection, content-length, cookie, set-cookie, authorization, proxy-authorization - Redirecciones deshabilitadas (
allowRedirect: false) - Enrutado mediante
safeOutboundFetchconguard: "public-only"(se bloquean los rangos privados/de bucle invertido) - La respuesta se trunca en
SKILLS_MAX_HTTP_RESPONSE_BYTES; el cliente vetruncated: true
Ejecutor híbrido (vista previa)
Sección titulada «Ejecutor híbrido (vista previa)»src/lib/skills/hybrid.ts define un HybridExecutor que decide entre la ejecución direct (en proceso) y sandbox para cada llamada, con una ruta de reintento autoUpgrade en caso de errores de tiempo de espera o memoria. Las implementaciones integradas directExecutor / sandboxRunner son stubs (executeDirect, executeInSandbox devuelven objetos provisionales); considere este módulo como un contrato en construcción. La ejecución real aún se realiza mediante skillExecutor + SandboxRunner.
Almacenamiento
Sección titulada «Almacenamiento»El esquema se encuentra en dos migraciones:
src/lib/db/migrations/016_create_skills.sql: tablas baseskillsyskill_executions, con índices en(api_key_id, name)y(skill_id, status, created_at).src/lib/db/migrations/027_skill_mode_and_metadata.sql: agregamode,source_provider,tags(JSON) einstall_countaskills.
skill_executions.status está restringido en el nivel de la base de datos: CHECK(status IN ('pending', 'running', 'success', 'error', 'timeout')).
API REST
Sección titulada «API REST»Todos los endpoints se encuentran en src/app/api/skills/. Los endpoints de administración (/api/skills, /api/skills/[id], /api/skills/install) requieren autenticación de administración mediante requireManagementAuth(). Los flujos del marketplace y de instalación utilizan el método más ligero isAuthenticated() (sesión o clave de API).
| Endpoint | Método | Propósito |
| ——————————— | —— | ———————————————————————— | — | ———————— | –––– | —————— |
| /api/skills | GET | Enumera las skills registradas. Admite ?q=, ?mode=on | off | auto, ?source=skillsmp | skillssh | local, paginación |
| /api/skills/[id] | PUT | Actualiza enabled o mode |
| /api/skills/[id] | DELETE | Anula el registro por id |
| /api/skills/install | POST | Instala una skill personalizada (código del controlador + esquema) |
| /api/skills/marketplace | GET | Busca en el catálogo de SkillsMP (devuelve opciones populares predeterminadas cuando q está vacío) |
| /api/skills/marketplace/install | POST | Instala una skill de SkillsMP (requiere que el proveedor activo sea skillsmp) |
| /api/skills/skillssh | GET | Busca en el catálogo de skills.sh (?q=&limit=, con un máximo de 100) |
| /api/skills/skillssh/install | POST | Instala una skill de skills.sh (requiere que el proveedor activo sea skillssh) |
| /api/skills/executions | GET | Historial de ejecuciones paginado (?apiKeyId=) |
| /api/skills/executions | POST | Ejecuta una skill registrada de forma ad hoc |
El endpoint POST /api/skills/executions devuelve HTTP 503 con { error: "Skills execution is disabled..." } cuando settings.skillsEnabled === false (executor.ts:42-45). Los operadores pueden cambiar el interruptor maestro desde Configuración → IA.
Ejemplo: instalar una skill personalizada
Sección titulada «Ejemplo: instalar una skill personalizada»curl -X POST http://localhost:20128/api/skills/install \ -H "Authorization: Bearer $OMNIROUTE_MGMT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "reverse-text", "version": "1.0.0", "description": "Reverses a string", "schema": { "input": { "type": "object", "properties": { "text": { "type": "string" } }, "required": ["text"] }, "output": { "type": "object", "properties": { "reversed": { "type": "string" } } } }, "handlerCode": "echo-handler", "apiKeyId": "your-api-key-id" }'La cadena handlerCode es una búsqueda por nombre del controlador, no código ejecutable. El ejecutor la asigna mediante skillExecutor.registerHandler(name, fn) (executor.ts:25). Las instalaciones desde el marketplace almacenan el texto de SKILL.md en este campo como documentación y dirigen la ejecución mediante llamadas a herramientas generadas por el modelo. El código fuente arbitrario proporcionado por el usuario no se evalúa mediante eval.
Herramientas MCP
Sección titulada «Herramientas MCP»Cuatro herramientas MCP encapsulan la interfaz de skills (open-sse/mcp-server/tools/skillTools.ts). Se registran automáticamente cuando se inicia el servidor MCP.
| Herramienta | Descripción |
|---|---|
omniroute_skills_list |
Enumera skills; filtros opcionales: apiKeyId, name, enabled |
omniroute_skills_enable |
Habilita o deshabilita una skill mediante skillId |
omniroute_skills_execute |
Ejecuta una skill con una carga útil de entrada |
omniroute_skills_executions |
Historial de ejecuciones recientes (50 de forma predeterminada, máximo 100) |
Consulta MCP-SERVER.md para obtener información sobre la configuración del transporte y las asignaciones de alcance.
Integración A2A
Sección titulada «Integración A2A»src/lib/skills/a2a.ts exporta el descriptor de la skill A2A memory_aware_routing y una función auxiliar registerA2ASkill(registry). Las skills A2A personalizadas se encuentran en src/lib/a2a/skills/ y se despachan mediante A2A_SKILL_HANDLERS (src/lib/a2a/taskExecution.ts). Consulta A2A-SERVER.md para conocer el ciclo de vida completo de las tareas.
Añadir una nueva skill integrada
Sección titulada «Añadir una nueva skill integrada»- Define el manejador en
src/lib/skills/builtins.ts(o en un archivo relacionado dentro desrc/lib/skills/builtin/). Firma:(input, { apiKeyId, sessionId }) => Promise<output>. - ¿Ruta de código en entorno aislado? Llama a
sandboxRunner.run(image, command, env, sandboxConfig({...})). UsanormalizeImage()con la lista de permitidos. - ¿Ruta del sistema de archivos? Pásala siempre por
resolveWorkspacePath(input, context)antes de acceder al disco. - ¿Llamada de red? Usa
safeOutboundFetchconguard: "public-only"; sanea los encabezados mediantesanitizeHeaders(). - Regístrala añadiendo la entrada a
builtinSkills(o llamando a algo comoregisterBrowserSkill(executor)durante el arranque). - Configura los alias de herramientas integradas (opcional) en
BUILTIN_TOOL_ALIASES(interception.ts:23) si el modelo ascendente emite un nombre diferente. - Pruebas en
src/lib/skills/__tests__/(Vitest).
Añadir una skill personalizada (no integrada)
Sección titulada «Añadir una skill personalizada (no integrada)»- Registra el manejador al iniciar el proceso:
skillExecutor.registerHandler("my-handler", async (input, ctx) => { ... });
- Inserta la skill mediante
POST /api/skills/install(el campohandlerCodedebe coincidir con el nombre del manejador registrado). - Cambia
modeaonoautomediantePUT /api/skills/[id].
Consejos operativos
Sección titulada «Consejos operativos»- Interruptor maestro:
settings.skillsEnabled = falsebloquea todas las ejecuciones y devuelve HTTP503en/api/skills/executions. El registro continúa cargándose. - Restringe el tráfico saliente: mantén
SKILLS_SANDBOX_NETWORK_ENABLEDsin definir (valor predeterminado) para que el entorno aislado no tenga ningún acceso a la red. El valornetworkEnabled: truepor llamada sigue requiriendo la habilitación del control maestro. - Permite imágenes específicas: establece
SKILLS_ALLOWED_SANDBOX_IMAGES="myorg/sandbox:1.0,node:22-alpine"para ampliar la lista de permitidos. - Audita las ejecuciones: tanto
/dashboard/skills/executionscomoomniroute_skills_executionsconsultanskill_executions. Las ejecuciones correctas incluyendurationMs; los errores incluyenerrorMessage. - Invalidación de caché: llama a
skillRegistry.invalidateCache()después de editar manualmente la base de datos; de lo contrario, espera 60 s. - Espacio de trabajo anónimo: cuando
apiKeyIdestá vacío, todas las llamadas generan un hash que apunta al mismo espacio de trabajo"anonymous"; el código que gestione recursos compartidos siempre debe proporcionar una clave real.
Ciclo de vida de la ejecución (v3.8.16+)
Sección titulada «Ciclo de vida de la ejecución (v3.8.16+)»El SkillExecutor (src/lib/skills/executor.ts) es un singleton que gestiona cada invocación de una habilidad. Comprender su ciclo de vida es fundamental para depurar tiempos de espera, reintentos y el estado de ejecución.
El ciclo de vida de 5 etapas
Sección titulada «El ciclo de vida de 5 etapas» execute() llamado │ ▼ ┌─────────────┐ │ PENDING │ ← en cola, aún no iniciado (fila de la BD creada) └──────┬──────┘ │ iniciar controlador ▼ ┌─────────────┐ │ RUNNING │ ← controlador invocado con tiempo de espera └──────┬──────┘ │ ┌────┴────┬──────────┬──────────┐ │ │ │ │ ▼ ▼ ▼ ▼ SUCCESS ERROR TIMEOUT (ninguna otra ruta — terminado por el proceso padre) │ │ │ └────┬────┴──────────┘ │ ▼ Fila de la BD actualizada con estado, salida y durationMsConfiguración predeterminada
Sección titulada «Configuración predeterminada»| Ajuste | Valor predeterminado | Configurable mediante |
|---|---|---|
timeout |
30000 (30s) |
skillExecutor.setTimeout(ms) |
maxRetries |
3 |
skillExecutor.setMaxRetries(count) |
Importante: El ejecutor es un singleton; llamar a
setTimeout()afecta globalmente a todas las invocaciones posteriores. Actualmente no se admiten tiempos de espera por habilidad; si necesita diferentes tiempos de espera para cada habilidad, envíe procesos separados o cree una bifurcación del ejecutor.
Valores de estado
Sección titulada «Valores de estado»De src/lib/skills/types.ts:
enum SkillStatus { PENDING = "pending", // En cola, aún no iniciado RUNNING = "running", // Controlador invocado SUCCESS = "success", // El controlador devolvió una salida válida ERROR = "error", // El controlador lanzó una excepción TIMEOUT = "timeout", // Se superó el tiempo de espera del ejecutor}Nota: El estado
TIMEOUTestá definido en el enum, pero la implementación actual del ejecutor no lo escribe realmente en la BD; los tiempos de espera se muestran comoERRORcon el mensaje"Skill execution timed out". El enum de estado está reservado para uso futuro.
Inspección de ejecuciones
Sección titulada «Inspección de ejecuciones»import { skillExecutor } from "omniroute/skills/executor";
// Obtener una ejecución específica por IDconst exec = skillExecutor.getExecution("exec-uuid-123");if (exec) { console.log(`${exec.skillName}: ${exec.status} en ${exec.durationMs}ms`);}
// Enumerar las ejecuciones recientes de una clave de APIconst recent = skillExecutor.listExecutions("api-key-id", 50, 0);for (const e of recent) { console.log(`${e.skillName} → ${e.status} (${e.durationMs}ms)`);}
// Contar el total de ejecucionesconst total = skillExecutor.countExecutions("api-key-id");Comportamiento de los reintentos
Sección titulada «Comportamiento de los reintentos»El ajuste maxRetries se almacena, pero el método execute() del ejecutor no lo utiliza actualmente: solo realiza un único intento. El valor maxRetries se expone para una implementación futura y para los hooks que quieran leerlo.
Por ahora, los reintentos deben implementarse dentro del propio controlador de la habilidad. Las habilidades
integradas se registran en el ejecutor (p. ej., registerBuiltinSkills(executor)
/ registerBrowserSkill(executor) en src/lib/skills/builtin/); cualquier controlador
que registre puede envolver su propio bucle de reintentos:
// dentro de un controlador de habilidadasync function handler(input, ctx) { const maxRetries = 3; let lastError: Error | null = null;
for (let attempt = 1; attempt <= maxRetries; attempt++) { try { return await fetchSomething(input); } catch (err) { lastError = err as Error; if (attempt < maxRetries) { await new Promise((r) => setTimeout(r, 1000 * attempt)); } } } throw lastError;}SkillMode en detalle
Sección titulada «SkillMode en detalle»La enumeración SkillMode (src/lib/skills/types.ts) controla cuándo y cómo se invocan las habilidades:
enum SkillMode { AUTO = "auto", // El LLM decide cuándo llamar a la habilidad MANUAL = "manual", // Solo se invoca mediante una solicitud explícita del usuario HYBRID = "hybrid", // Puntuación AUTO + anulación manual}Nota: El código base define
SkillMode(AUTO/MANUAL/HYBRID), mientras que el campoSkill.modeutiliza una forma diferente ("on" | "off" | "auto"). Están relacionados, pero no son idénticos:SkillModecorresponde a la política del ejecutor, mientras queSkill.modecontrola la habilitación de cada habilidad.
Cuándo usar cada modo
Sección titulada «Cuándo usar cada modo»| Modo | Comportamiento del LLM | Caso de uso |
|---|---|---|
AUTO |
El LLM puede llamar a la habilidad cuando lo considere necesario | Habilidades de propósito general (lectura de archivos, solicitudes HTTP) |
MANUAL |
El LLM no puede llamar a la habilidad; solo la invoca una llamada explícita a la API executeSkill |
Operaciones sensibles (escrituras en bases de datos, pagos) |
HYBRID |
El LLM puede sugerir la habilidad; el usuario debe confirmarlo | Habilidades que tienen efectos secundarios, pero no son peligrosas |
Puntuación AUTO
Sección titulada «Puntuación AUTO»Cuando el modo AUTO está activo, cada habilidad candidata se puntúa en función del contexto
de la solicitud mediante scoreAutoSkill() en src/lib/skills/injection.ts: un sistema aditivo
de puntos enteros (coincidencia con el nombre de la habilidad, solapamiento de tokens de nombre/etiqueta/descripción,
indicios del motivo en segundo plano, bonificación/penalización por indicios del proveedor). Las
AUTO_MAX_SKILLS = 5 habilidades principales con score >= AUTO_MIN_SCORE = 3 se inyectan como
herramientas invocables; los empates se resuelven primero por installCount y luego por nombre. Consulte la tabla
completa de puntos en Generación del esquema de herramientas → Puntuación AUTO, anteriormente en este
documento; no existe ningún umbral decimal al estilo de 0.6 ni puntuación en registry.ts.
Catálogo de habilidades integradas
Sección titulada «Catálogo de habilidades integradas»OmniRoute incluye un conjunto seleccionado de habilidades integradas en src/lib/skills/builtin/. Las más comunes son:
Habilidad de automatización del navegador
Sección titulada «Habilidad de automatización del navegador»La habilidad del navegador (src/lib/skills/builtin/browser.ts) proporciona automatización de navegador sin interfaz gráfica mediante Playwright/Puppeteer. Está implementada, pero no se incluye en el catálogo de habilidades predeterminado; para usarla, instale por separado el complemento de extensión del navegador.
// Habilitar en la configuraciónconst config: SkillConfig = { enabled: true, mode: SkillMode.MANUAL, // Exigir siempre una invocación explícita allowedSkills: ["browser"], timeout: 60000, // 60 s para la carga de páginas maxRetries: 1,};Otras categorías integradas
Sección titulada «Otras categorías integradas»| Categoría | Habilidades | Modo |
|---|---|---|
| E/S de archivos | file_read, file_write |
AUTO |
| HTTP | http_request |
AUTO |
| Búsqueda | web_search |
AUTO |
| Ejecución de código | eval_code (JavaScript/Python en entorno aislado) |
HYBRID |
| Sistema | execute_command (ejecución de CLI en entorno aislado) |
MANUAL |
Añadir una habilidad personalizada
Sección titulada «Añadir una habilidad personalizada»Consulte SDK de complementos e integración de habilidades para saber cómo añadir una habilidad personalizada mediante el sistema de complementos.
Véase también
Sección titulada «Véase también»- MCP-SERVER.md — registro de herramientas MCP y transportes
- A2A-SERVER.md — ciclo de vida de tareas A2A y despacho de habilidades
- USER_GUIDE.md — introducción para usuarios
- ARCHITECTURE.md — canalización de solicitudes y mapa de componentes
- Código fuente:
src/lib/skills/,src/app/api/skills/,open-sse/mcp-server/tools/skillTools.ts - Pruebas:
src/lib/skills/__tests__/integration.test.ts
HagiCode
HagiCode es un espacio de trabajo de programación con agentes, flujos estructurados, ejecución multiagente y vistas de Hero Dungeon.
Convierte ideas en software útil con un flujo de trabajo con agentes más inteligente, rápido y ameno.

- SmartLos flujos estructurados convierten la intención en un itinerario ejecutable desde la idea hasta la entrega.
- EfficientLos flujos multiagente permiten avanzar en paralelo con la investigación, implementación y revisión.
- FunHero Dungeon hace que las largas sesiones de programación sean visuales y colaborativas.