1,104 mirrors rewritten over five passes of run-translation on the 22-source core set: the 14 sources edited since their translation, the 322 mirrors that were still English copies, and the frontmatter the old extractor leaked into the newer locales' bodies. The pipeline now caches per-`## `-section hashes and retranslates only changed sections, never reuses a section that is still English, rebuilds English-copy / leaked mirrors even when the source is unchanged, merges the state on save (parallel runs), and the drift gate (scoped to the core set) is blocking. Final audit: 0 stale, 0 English copies, 0 leaked frontmatter across 1,430 core mirrors. ⚠️ base-red inherited: #12732
85 KiB
OmniRoute Codebase Documentation (Español)
🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
Versión: v3.8.51 Última actualización: 2026-06-28 Audiencia: Ingenieros que contribuyen a OmniRoute o desarrollan integraciones sobre él.
Para consultar diagramas de arquitectura de alto nivel y el razonamiento detrás de cada subsistema, lea ARCHITECTURE.md. Para análisis detallados de subsistemas individuales (Auto Combo, servidor MCP, servidor A2A, Skills, Memory, Cloud Agents, Resilience, Compression, etc.), consulte sus archivos específicos en este directorio
docs/.
Este archivo describe lo que existe actualmente en el repositorio para que un nuevo ingeniero pueda navegar por el árbol, comprender las capas del entorno de ejecución y saber dónde añadir código sin inventar módulos nuevos.
1. Stack tecnológico
| Área | Elección |
|---|---|
| Framework web | Next.js 16 (App Router, salida independiente, sin middleware global) |
| Lenguaje | TypeScript 6.0+ — objetivo ES2022, module: esnext, moduleResolution: bundler, strict: false |
| Entorno | Node.js >=22.22.2 <23 o >=24.0.0 <27 (aplicado mediante engines + SUPPORTED_NODE_RANGE) |
| Base de datos | SQLite mediante better-sqlite3 (singleton, registro por diario WAL) |
| Escritorio | Electron 41 + electron-builder 26.10 (espacio de trabajo independiente en electron/) |
| Pruebas | Ejecutor de pruebas nativo de Node (unitarias/integración), Vitest (MCP, autoCombo, caché), Playwright (e2e + protocols-e2e) |
| Compilación | Next.js independiente mediante scripts/build/build-next-isolated.mjs |
| Lint/formato | Configuración plana de ESLint + Prettier (lint-staged mediante pre-commit de Husky) |
| Sist. módulos | ESM en todas partes ("type": "module") |
| Esp. trabajo | Espacio de trabajo npm — open-sse es el único subespacio de trabajo |
Alias de rutas (tsconfig.json):
@/*→src/*@omniroute/open-sse→open-sse/index.ts@omniroute/open-sse/*→open-sse/*
Puerto HTTP predeterminado: 20128 (la API y el panel comparten el mismo proceso). El directorio
de datos es la variable de entorno DATA_DIR, cuyo valor predeterminado es ~/.omniroute/.
2. Estructura del repositorio
OmniRoute/
├── src/ Aplicación Next.js (App Router, bibliotecas, dominio, servidor, código compartido)
├── open-sse/ Espacio de trabajo del motor de streaming (@omniroute/open-sse)
├── electron/ Contenedor de escritorio (proceso principal + precarga de Electron 41)
├── bin/ Puntos de entrada de la CLI (omniroute, reset-password)
├── tests/ Pruebas unitarias, de integración, e2e, protocols-e2e, de traductor, de seguridad y fixtures
├── scripts/ Scripts auxiliares de compilación, sincronización, comprobación, migración y ejecución
├── docs/ Documentación pública (este directorio)
├── public/ Recursos estáticos, manifiesto PWA, service worker
├── config/ Ejemplos de configuración del entorno de ejecución
├── images/ Recursos de marketing/capturas de pantalla
├── _ideia/, _references/, _mono_repo/, _tasks/ Borradores/planificación internos (no se distribuyen)
├── CLAUDE.md Reglas del repositorio para Claude Code
├── AGENTS.md Referencia de arquitectura más detallada para agentes
├── package.json v3.8.51, raíz del espacio de trabajo
└── tsconfig.json Alias de rutas + opciones principales del compilador
3. src/ — Aplicación Next.js
src/
├── app/ Páginas del App Router + rutas de API
├── lib/ Bibliotecas principales (BD, autenticación, OAuth, habilidades, memoria, …)
├── domain/ Capa de dominio pura (políticas, respaldo, costes, bloqueo, …)
├── server/ Módulos exclusivos del servidor (autorización, CORS, autenticación)
├── shared/ Tipos, constantes, validación, contratos y utilidades (seguros entre límites)
├── mitm/ Utilidades de proxy de intermediario para la integración con la CLI
├── models/ Metadatos y alias de modelos locales
├── sse/ Controladores SSE heredados que aún residen en src/ (no en open-sse/)
├── store/ Almacenes de estado del lado del cliente
├── middleware/ Utilidades de middleware a nivel de ruta (no middleware global de Next.js)
├── scripts/ Scripts internos del árbol importables por el código de la aplicación
├── types/ Tipos TS globales y compartidos
├── i18n/ Paquetes de configuración regional
├── instrumentation.ts Hook de instrumentación de Next.js
├── instrumentation-node.ts
└── proxy.ts Utilidad de arranque del proxy de nivel superior
3.1 src/app/ — App Router
El App Router expone tanto la interfaz del panel como la API HTTP pública y de administración. No hay middleware global; la interceptación se realiza por ruta.
Segmentos de nivel superior en src/app/:
| Ruta | Propósito |
|---|---|
api/ |
Todas las rutas de la API HTTP (véase el desglose a continuación) |
a2a/ |
Endpoint A2A JSON-RPC 2.0 (POST /a2a) |
.well-known/agent.json/ |
Documento de descubrimiento Agent Card de A2A |
(dashboard)/ |
Interfaz del panel (grupo de rutas, sin prefijo URL) |
auth/, login/, forgot-password/, callback/ |
Flujos de autenticación |
landing/ |
Página promocional/de destino |
docs/ |
Visor integrado de documentación de la API |
status/, maintenance/, offline/ |
Páginas operativas |
privacy/, terms/ |
Páginas legales |
400/, 401/, 403/, 408/, 429/, 500/, 502/, 503/ |
Páginas de error estáticas |
error.tsx, global-error.tsx, not-found.tsx, forbidden/, loading.tsx |
Límites de error y carga del framework |
layout.tsx, page.tsx, globals.css, manifest.ts |
Estructura raíz |
3.1.1 src/app/(dashboard)/dashboard/ — Páginas de la interfaz
agents, analytics, api-manager, audit, auto-combo, batch, cache,
changelog, cli-tools, cloud-agents, combos, compression, context,
costs, endpoint, health, limits, logs, memory, onboarding,
playground, providers, search-tools, settings, skills, system,
translator, usage, webhooks, además de los archivos raíz page.tsx, HomePageClient.tsx,
BootstrapBanner.tsx.
3.1.2 src/app/api/ — Grupos de API de nivel superior
src/app/api/
├── a2a/{status, tasks}
├── acp/
├── admin/
├── analytics/
├── assess/
├── auth/
├── batches/
├── cache/
├── cli-tools/
├── cloud/{codex-responses-ws}
├── combos/
├── compliance/
├── compression/
├── context/
├── db/, db-backups/
├── evals/
├── fallback/
├── files/
├── health/
├── init/
├── internal/{concurrency}
├── keys/
├── logs/
├── mcp/{audit, sse, status, stream, tools}
├── memory/{health, [id]/, route.ts}
├── model-combo-mappings/
├── models/
├── monitoring/
├── oauth/
├── openapi/
├── policies/
├── pricing/
├── provider-metrics/, provider-models/, provider-nodes/
├── providers/
├── rate-limit/, rate-limits/
├── resilience/
├── restart/, shutdown/
├── search/
├── sessions/
├── settings/
├── skills/{executions, [id], install, marketplace, route.ts, skillssh}
├── storage/
├── sync/, synced-available-models/
├── system/
├── tags/
├── telemetry/
├── token-health/
├── translator/
├── tunnels/
├── services/ Gestión de servicios integrados (9router, cliproxy) — LOCAL_ONLY
├── upstream-proxy/
├── usage/
├── v1/ API pública compatible con OpenAI
├── v1beta/ Compatibilidad de estilo Gemini
├── version-manager/
└── webhooks/
3.1.2a src/app/api/services/ — Gestión de servicios integrados
Rutas para instalar, iniciar, detener y supervisar 9Router y CLIProxyAPI.
Todas las rutas están clasificadas como LOCAL_ONLY (solo loopback, regla estricta n.º 17) porque
pueden ejecutar npm install e iniciar procesos secundarios.
src/app/api/services/
├── 9router/
│ ├── _lib.ts helper getOrInitSupervisor()
│ ├── install/route.ts POST — npm install mediante execFile
│ ├── start/route.ts POST — supervisor.start()
│ ├── stop/route.ts POST — supervisor.stop()
│ ├── restart/route.ts POST — supervisor.restart()
│ ├── update/route.ts POST — npm install de una versión más reciente
│ ├── rotate-key/route.ts POST — generar una nueva clave de API + reiniciar
│ ├── status/route.ts GET — estado en vivo + estado de la BD + metadatos de versión
│ └── auto-start/route.ts POST — alternar el indicador auto_start
├── cliproxy/
│ ├── _lib.ts helper getOrInitSupervisor()
│ ├── install/route.ts POST — npm install
│ ├── start/route.ts POST — supervisor.start()
│ ├── stop/route.ts POST — supervisor.stop()
│ ├── restart/route.ts POST — supervisor.restart()
│ ├── update/route.ts POST — npm install de una versión más reciente
│ ├── status/route.ts GET — estado en vivo + estado de la BD + metadatos de versión
│ └── auto-start/route.ts POST — alternar el indicador auto_start
└── [name]/
└── logs/route.ts GET — seguimiento de registros mediante SSE (compartido por todos los servicios)
Interfaz de usuario correspondiente del panel:
src/app/(dashboard)/dashboard/providers/services/ — página con dos pestañas (CLIProxyAPI + 9Router).
Proxy inverso para la interfaz de usuario integrada de 9Router:
src/app/(dashboard)/dashboard/providers/services/[name]/embed/[[...path]]/route.ts
Análisis detallado: docs/frameworks/EMBEDDED-SERVICES.md
3.1.3 src/app/api/v1/ — API pública compatible con OpenAI
v1/
├── accounts/[id]/ búsqueda de cuentas
├── agents/tasks/[id]/, agents/tasks/ endpoints de tareas con estilo A2A
├── api/ helpers internos de la API expuestos bajo v1/api
├── audio/{speech, transcriptions}/ TTS + STT
├── batches/[id]/{cancel}, batches/ API de lotes de OpenAI
├── chat/completions/ Finalizaciones de chat (el endpoint principal)
├── completions/ Finalizaciones de texto heredadas
├── embeddings/ Embeddings
├── files/[id]/, files/ API de archivos
├── _helpers/ Helpers compartidos de rutas (sin URL pública)
├── images/{edits, generations}/ Generación + edición de imágenes
├── issues/ Endpoints auxiliares de triaje
├── management/{proxies}/ Rutas con ámbito de administración dentro de v1
├── messages/{count_tokens}/ Compatibilidad con mensajes al estilo Anthropic
├── models/ Listado de modelos (`route.ts`, `catalog.ts`)
├── moderations/ Moderación
├── music/ Generación de música
├── providers/[provider]/ Operaciones por proveedor
├── quotas/{check} Sondeos de cuota
├── registered-keys/ Administración de claves registradas
├── rerank/ Reclasificación
├── responses/[...path]/ API Responses de OpenAI (captura todas las rutas)
├── search/ Búsqueda web
├── videos/ Generación de vídeo
├── ws/ Puente WebSocket
└── route.ts Controlador del índice
Cada archivo de ruta sigue el mismo patrón:
Ruta → solicitud preliminar CORS → validación del cuerpo con Zod → autenticación opcional
→ aplicación de políticas de claves de API → delegación al controlador (open-sse)
v1beta/ es la superficie de compatibilidad al estilo Gemini (un envoltorio ligero que traduce al
mismo flujo de procesamiento de open-sse/handlers/).
3.2 src/lib/ — Bibliotecas principales
Importa siempre los datos, la sincronización, OAuth, las habilidades, la memoria, etc. mediante estos módulos. La tabla agrupa los directorios reales y los archivos de nivel superior destacados.
| Módulo | Propósito |
|---|---|
a2a/ |
Servidor del protocolo A2A: taskManager.ts, streaming.ts, taskExecution.ts, routingLogger.ts, skills/ (6 habilidades: análisis de costes, informe de estado, detección de proveedores, gestión de cuotas, enrutamiento inteligente, listado de capacidades) |
acp/ |
Protocolo de control de agentes: index.ts, manager.ts, registry.ts |
api/ |
Utilidades de la API interna: requireManagementAuth.ts, requireCliToolsAuth.ts, errorResponse.ts |
auth/ |
managementPassword.ts (restablecimiento de contraseña / hashing) |
batches/ |
Servicio de la API de lotes de OpenAI (service.ts) |
catalog/ |
Sincronización del catálogo de OpenRouter (openrouterCatalog.ts) |
cloudAgent/ |
Registro de agentes en la nube: api.ts, baseAgent.ts, db.ts, index.ts, registry.ts, types.ts, agents/{codex, devin, jules}.ts |
combos/ |
Utilidades de resolución de combinaciones |
compliance/ |
Auditoría + auditoría de proveedores: index.ts, providerAudit.ts |
config/ |
Integración de la configuración en tiempo de ejecución |
db/ |
Módulos de dominio de SQLite (consulte §3.2.1) |
display/ |
Utilidades de interfaz/visualización usadas por las respuestas de la API |
embeddings/ |
Registro del servicio de embeddings |
env/ |
Carga + introspección del entorno |
evals/ |
Entorno de ejecución de evaluaciones |
guardrails/ |
piiMasker.ts, promptInjection.ts, visionBridge.ts, visionBridgeHelpers.ts, registry.ts, base.ts |
jobs/ |
Trabajos en segundo plano (autoUpdate.ts, …) |
memory/ |
Memoria persistente: store.ts, cache.ts, retrieval.ts, summarization.ts, extraction.ts, injection.ts, qdrant.ts, settings.ts, verify.ts, schemas.ts, types.ts |
monitoring/ |
observability.ts |
oauth/ |
Módulos de OAuth/importación de proveedores (22): agy, antigravity, claude, cline, codebuddy-cn, codex, cursor, devin-desktop, ghe-copilot, github, gitlab-duo, grok-cli-oauth, grok-cli, kilocode, kimi-coding, kiro, openference, qoder, trae, xai-oauth, zed-hosted, zed, además de services/, utils/ y constants/oauth.ts |
plugins/ |
Cargador de complementos (index.ts) |
promptCache/ |
prefixAnalyzer.ts, index.ts |
providerModels/ |
Ciclo de vida de modelos gestionados: modelDiscovery.ts, managedModelImport.ts, managedAvailableModels.ts, cursorAgent.ts |
providers/ |
Utilidades de proveedores: catalog.ts, validation.ts, imageValidation.ts, claudeExtraUsage.ts, codexConnectionDefaults.ts, codexFastTier.ts, webCookieAuth.ts, managedAvailableModels.ts, requestDefaults.ts |
resilience/ |
settings.ts — configuración del disyuntor, el periodo de espera y el bloqueo |
runtime/ |
Detección de funcionalidades en tiempo de ejecución |
search/ |
executeWebSearch.ts |
services/ |
Marco de servicios integrados: ServiceSupervisor.ts (supervisor genérico de procesos secundarios con bloqueo de operaciones, búfer circular y verificador de estado), bootstrap.ts (registro a nivel de proceso e inicio automático), registry.ts (mapa de herramienta → supervisor), apiKey.ts (almacén de claves AES-256-GCM), modelSync.ts (sincronización periódica de modelos), ringBuffer.ts (búfer circular de registros de 5 MB), healthCheck.ts (sondeo HTTP de estado), types.ts, embedWsProxy.ts (proxy WebSocket), installers/{ninerouter,cliproxy}.ts. Consulte docs/frameworks/EMBEDDED-SERVICES.md |
agentSkills/ |
Catálogo + generador de habilidades de agentes: catalog.ts (getCatalog/getSkillById/filterCatalog/computeCoverage), generator.ts (generateAgentSkills → escribe skills/{id}/SKILL.md), openapiParser.ts (extrae endpoints REST de la especificación OpenAPI), cliRegistryParser.ts (extrae subcomandos de la CLI de bin/cli-registry), schemas.ts (Zod: AgentSkillSchema, SkillCoverageSchema, ListQuerySchema, GenerateBodySchema), types.ts (AgentSkill, SkillCoverage, SkillMarkdown, GeneratorReport). Utilizado por las rutas REST (/api/agent-skills/*), las herramientas MCP (omniroute_agent_skills_*) y la habilidad A2A list-capabilities. Consulte AGENT-SKILLS.md. |
skills/ |
Marco de habilidades: registry.ts, executor.ts, interception.ts, injection.ts, sandbox.ts, custom.ts, hybrid.ts, builtins.ts, a2a.ts, providerSettings.ts, schemas.ts, skillssh.ts, types.ts, además de builtin/browser.ts |
spend/ |
batchWriter.ts (búfer de escritura diferida) |
sync/ |
bundle.ts, tokens.ts (sincronización con la nube) |
system/ |
Utilidades a nivel del sistema |
translator/ |
Integración de nivel superior del traductor (delega en open-sse/translator/) |
usage/ |
Contabilidad de uso: costCalculator.ts, tokenAccounting.ts, usageHistory.ts, aggregateHistory.ts, usageStats.ts, callLogs.ts, callLogArtifacts.ts, fetcher.ts, providerLimits.ts, migrations.ts |
versionManager/ |
Actualización automática + manifiesto de versiones |
ws/ |
Puente WebSocket |
zed-oauth/ |
Flujo OAuth del editor Zed |
Archivos de nivel superior en src/lib/:
- El antiguo barrel
localDb.tsfue eliminado; los consumidores importan directamente módulos específicos desrc/lib/db/*. proxyHealth.ts,proxyLogger.ts,tokenHealthCheck.ts,localHealthCheck.tsapiBridgeServer.ts,cacheLayer.ts,semanticCache.ts,settingsCache.tscloudSync.ts,initCloudSync.tscloudflaredTunnel.ts,ngrokTunnel.ts,tailscaleTunnel.tsconsoleInterceptor.ts,container.ts,gracefulShutdown.ts,idempotencyLayer.tsipUtils.ts,logEnv.ts,logPayloads.ts,logRotation.tsmodelAliasSeed.ts,modelCapabilities.ts,modelMetadataRegistry.ts,modelsDevSync.tspiiSanitizer.ts,pricingSync.tsapiKeyExposure.ts,cacheControlSettings.ts,dataPaths.ts,toolPolicy.tstranslatorEvents.ts,usageDb.ts,usageAnalytics.ts,webhookDispatcher.ts
3.2.1 src/lib/db/
Base de datos SQLite singleton (getDbInstance() en core.ts, registro WAL).
Nunca escribas SQL sin procesar en rutas ni manejadores; utiliza estos módulos.
Fuente: diagrams/db-schema-overview.mmd
Módulos de dominio (cada uno administra una o más tablas): apiKeys.ts, backup.ts,
batches.ts, cleanup.ts, cliToolState.ts, combos.ts,
commandCodeAuth.ts, compression.ts, compressionAnalytics.ts,
compressionCacheStats.ts, compressionCombos.ts, compressionScheduler.ts,
contextHandoffs.ts, core.ts, creditBalance.ts, databaseSettings.ts,
detailedLogs.ts, domainState.ts, encryption.ts, evals.ts, files.ts,
healthCheck.ts, jsonMigration.ts, migrationRunner.ts,
modelComboMappings.ts, models.ts, oneproxy.ts, prompts.ts,
providers.ts, providerLimits.ts, proxies.ts, quotaSnapshots.ts,
readCache.ts, reasoningCache.ts, registeredKeys.ts, secrets.ts,
sessionAccountAffinity.ts, settings.ts, stateReset.ts, stats.ts,
syncTokens.ts, tierConfig.ts, upstreamProxy.ts, versionManager.ts,
webhooks.ts.
migrations/ contiene 168 archivos .sql versionados (idempotentes y transaccionales) que
migrationRunner.ts ejecuta durante el arranque.
Tablas creadas mediante las migraciones (123 en total):
a, account_key_limits, api_keys, batches, call_logs,
combo_adaptation_state, combos, command_code_auth_sessions,
compression_analytics, compression_cache_stats,
compression_combo_assignments, compression_combos, context_handoffs,
daily_usage_summary, db_meta, domain_budgets, domain_circuit_breakers,
domain_cost_history, domain_fallback_chains, domain_lockout_state,
eval_cases, eval_runs, eval_suites, files, hourly_usage_summary,
key_value, mcp_tool_audit, memories, model_combo_mappings,
provider_connections, provider_key_limits, provider_nodes,
proxy_assignments, proxy_logs, proxy_registry, quota_snapshots,
reasoning_cache, registered_keys, request_detail_logs,
routing_decisions, semantic_cache, session_account_affinity,
skill_executions, skills, sync_tokens, tier_assignments,
tier_config, upstream_proxy_config, usage_history, version_manager,
webhooks (además de tablas virtuales FTS5 para la búsqueda en memoria).
3.3 src/domain/ — Capa de dominio
Lógica empresarial pura, sin E/S. Las rutas y los manejadores la importan.
| Archivo | Propósito |
|---|---|
policyEngine.ts |
Resolutor de políticas de nivel superior |
fallbackPolicy.ts |
Árbol de decisiones de respaldo |
costRules.ts |
Reglas de cálculo de costes |
lockoutPolicy.ts |
Decisiones de bloqueo de modelos |
tagRouter.ts |
Enrutamiento basado en etiquetas |
comboResolver.ts |
Resolución de combinaciones de solicitud → lista de destinos |
connectionModelRules.ts |
Filtros de modelos por conexión |
modelAvailability.ts |
Comprobación de disponibilidad del modelo |
degradation.ts |
Transiciones del modo degradado |
providerExpiration.ts |
Detección de cuentas/claves caducadas |
quotaCache.ts |
Decisiones de cuota almacenadas en caché |
responses.ts, omnirouteResponseMeta.ts |
Utilidades para la estructura de respuestas |
configAudit.ts |
Auditoría de cambios de configuración |
assessment/ |
Evaluación de modelos (según RFC, parcialmente implementada) |
types.ts |
Tipos de dominio compartidos |
3.4 src/server/ — Solo para el servidor
No se puede importar desde componentes de cliente.
server/
├── auth/loginGuard.ts
├── authz/
│ ├── classify.ts Clasifica las rutas como públicas o de administración
│ ├── assertAuth.ts Utilidad de aserción
│ ├── context.ts Contexto de autorización por solicitud
│ ├── headers.ts
│ ├── pipeline.ts Canalización de autorización
│ ├── policies/ Políticas concretas
│ └── types.ts
└── cors/origins.ts Lista de orígenes permitidos por CORS
3.5 src/shared/ — Seguro para compartir
Dividido en subdirectorios específicos:
constants/—providers.ts(catálogo de proveedores validado con Zod),models.ts,modelSpecs.ts,modelCompat.ts,pricing.ts,cliTools.ts,cliCompatProviders.ts,routingStrategies.ts,comboConfigMode.ts,headers.ts,upstreamHeaders.ts(lista de denegación),mcpScopes.ts,errorCodes.ts,publicApiRoutes.ts,batch.ts,batchEndpoints.ts,bodySize.ts,colors.ts,appConfig.ts,config.ts,sidebarVisibility.ts,visionBridgeDefaults.ts.validation/—schemas.ts(~80 esquemas de Zod),compressionConfigSchemas.ts,providerSchema.ts,settingsSchemas.ts,helpers.ts.contracts/— contratos de API pública publicados en npm.types/— tipos de TS compartidos.utils/—circuitBreaker.ts,apiAuth.ts,apiKey.ts,apiKeyPolicy.ts,api.ts,classify429.ts,cliCompat.ts,clipboard.ts,cloud.ts,cn.ts,cors.ts,featureFlags.ts,fetchTimeout.ts,formatting.ts,inputSanitizer.ts,logger.ts,machine.ts,machineId.ts,maskEmail.ts,modelCatalogSearch.ts,nodeRuntimeSupport.ts,parseApiKeys.ts,providerHints.ts,providerModelAliases.ts,rateLimiter.ts,releaseNotes.ts,a11yAudit.ts, además de hooks/componentes del panel enservices/,network/,middleware/,schemas/,hooks/,components/.
4. open-sse/ — Espacio de trabajo del motor de streaming
Espacio de trabajo npm independiente publicado como @omniroute/open-sse. Se encarga del procesamiento
de solicitudes, ejecutores, traductores, servicios, transformador y el servidor MCP.
open-sse/
├── index.ts Exportaciones públicas
├── package.json Manifiesto del espacio de trabajo
├── tsconfig.json
├── types.d.ts
├── config/ Registros de proveedores, perfiles de cabeceras, identidad, …
├── handlers/ Manejadores de solicitudes (chat, embeddings, audio, imagen, …)
├── executors/ 108 ejecutores HTTP específicos de proveedores
├── translator/ Conversión de formatos (OpenAI ↔ Claude ↔ Gemini ↔ Cursor ↔ Kiro)
├── transformer/ Transformador de streams de Responses API ↔ Chat Completions
├── services/ Más de 80 módulos de servicio (combinaciones, respaldo, cuotas, identidad, …)
├── utils/ Utilidades de streaming, cliente TLS, AWS SigV4, proxy fetch, …
└── mcp-server/ Servidor MCP (3 transportes, 33 ámbitos, 110 herramientas)
4.1 open-sse/handlers/
| Manejador | Propósito |
|---|---|
chatCore.ts |
Flujo principal del chat (caché, límite de tasa, enrutamiento combinado, despacho de ejecutores) |
responsesHandler.ts |
Punto de entrada de OpenAI Responses API |
embeddings.ts |
Embeddings |
imageGeneration.ts |
Generación de imágenes |
audioSpeech.ts |
Texto a voz |
audioTranscription.ts |
Voz a texto |
videoGeneration.ts |
Generación de vídeo |
musicGeneration.ts |
Generación de música |
rerank.ts |
Reordenamiento |
moderations.ts |
Moderación |
search.ts |
Búsqueda web |
sseParser.ts |
Analizador de eventos SSE |
usageExtractor.ts |
Extrae los recuentos de tokens de los streams de origen |
responseSanitizer.ts |
Elimina el ruido específico del proveedor |
responseTranslator.ts |
Enlace entre la respuesta del proveedor y la capa de traducción |
4.2 open-sse/executors/
108 ejecutores de proveedores, cada uno de los cuales extiende BaseExecutor (base.ts):
antigravity, azure-openai, blackbox-web, cliproxyapi,
chatgpt-web-codex, cloudflare-ai, codex, commandCode, cursor, default, devin-cli,
muse-spark-web, nlpcloud, opencode, perplexity-web, petals,
pollinations, qoder, vertex, devin-desktop, además de claudeIdentity.ts
(utilidad compartida de identidad) e index.ts (registro).
Nota: los proveedores que no aparecen aquí se atienden mediante
default.tsusando el ejecutor genérico compatible con OpenAI. El catálogo completo de proveedores (355 proveedores) se encuentra ensrc/shared/constants/providers.ts.
4.3 open-sse/translator/
Traducción mediante una arquitectura de eje y radios (OpenAI es el eje).
- 9 traductores de solicitudes (
translator/request/):antigravity-to-openai,claude-to-gemini,claude-to-openai,gemini-to-openai,openai-responses,openai-to-claude,openai-to-cursor,openai-to-gemini,openai-to-kiro. - 9 traductores de respuestas (
translator/response/):claude-to-openai,cursor-to-openai,gemini-to-claude,gemini-to-openai,kiro-to-openai,openai-responses,openai-to-antigravity,openai-to-claude. - 9 utilidades (
translator/helpers/):claudeHelper,geminiHelper,geminiToolsSanitizer,maxTokensHelper,openaiHelper,responsesApiHelper,schemaCoercion,toolCallHelper, además de pruebas de utilidades. - Utilidades de imagen (
translator/image/sizeMapper.ts). - Nivel superior:
bootstrap.ts,formats.ts,registry.ts,index.ts.
4.4 open-sse/transformer/
responsesTransformer.ts— Convertidor basado enTransformStreamentre Responses API ↔ Chat Completions (utilizado por la ruta comodínresponses/).
4.5 open-sse/services/
Aspectos destacados (lista completa en open-sse/services/):
| Área | Archivos |
|---|---|
| Enrutamiento Combo | combo.ts (19 estrategias), comboConfig.ts, comboMetrics.ts, comboManifestMetrics.ts, comboAgentMiddleware.ts |
| Motor Auto Combo | autoCombo/ — engine.ts, scoring.ts, taskFitness.ts, virtualFactory.ts, modePacks.ts, autoPrefix.ts, persistence.ts, providerDiversity.ts, providerRegistryAccessor.ts, routerStrategy.ts, selfHealing.ts, index.ts |
| Resiliencia | accountFallback.ts (enfriamiento + bloqueo), errorClassifier.ts, emergencyFallback.ts, rateLimitManager.ts, rateLimitSemaphore.ts, accountSemaphore.ts, accountSelector.ts |
| Cuotas | quotaMonitor.ts, quotaPreflight.ts, bailianQuotaFetcher.ts, codexQuotaFetcher.ts, deepseekQuotaFetcher.ts, openrouterQuotaFetcher.ts, openrouterFreeWindow.ts, crofUsageFetcher.ts, antigravityCredits.ts |
| Caché | reasoningCache.ts, searchCache.ts, signatureCache.ts, requestDedup.ts |
| Inteligencia de enrutamiento | intentClassifier.ts, taskAwareRouter.ts, backgroundTaskDetector.ts, volumeDetector.ts, wildcardRouter.ts, workflowFSM.ts, specificityDetector.ts, specificityRules.ts, specificityTypes.ts |
| Gestión de modelos | modelCapabilities.ts, modelDeprecation.ts, modelFamilyFallback.ts, modelStrip.ts, model.ts, provider.ts, providerRequestDefaults.ts, providerCostData.ts, payloadRules.ts |
| Compresión | compression/ — integración completa del motor de compresión |
| Tokens + sesión | tokenRefresh.ts, sessionManager.ts, apiKeyRotator.ts, contextManager.ts, contextHandoff.ts, systemPrompt.ts, roleNormalizer.ts, responsesInputSanitizer.ts, toolSchemaSanitizer.ts, toolLimitDetector.ts, thinkingBudget.ts |
| Nivel / manifiesto | tierResolver.ts, tierConfig.ts, tierDefaults.json, tierTypes.ts, manifestAdapter.ts |
| IP / red | ipFilter.ts, webSearchFallback.ts |
| Lotes | batchProcessor.ts |
| Uso | usage.ts |
4.6 open-sse/mcp-server/
- 110 herramientas únicas integradas en
server.ts(45 canónicas enschemas/tools.ts+ módulos de memoria, habilidades, habilidades de GitHub, pool, gamificación, plugins, Notion, Obsidian, corpus local y compresión; la unión se cuenta mediantecountUniqueMcpTools). - 3 transportes: stdio, HTTP Streamable, SSE.
- 33 ámbitos aplicados en tiempo de ejecución — la lista base está en
src/shared/constants/mcpScopes.ts; el conjunto completo es la unión de los ámbitos declarados por cada módulo de herramientas. - Tabla de auditoría:
mcp_tool_audit(rellenada poraudit.ts). - Archivos:
server.ts,index.ts,httpTransport.ts,audit.ts,scopeEnforcement.ts,runtimeHeartbeat.ts,descriptionCompressor.ts,schemas/{tools, a2a, audit, index}.ts,tools/{advancedTools, compressionTools, memoryTools, skillTools}.ts, además de las pruebas en__tests__/. - Consulta MCP-SERVER.md para ver el catálogo completo de herramientas.
4.7 open-sse/config/
Registros de proveedores (providerRegistry.ts, providerModels.ts,
providerHeaderProfiles.ts), registros de modelos por formato (audioRegistry.ts,
embeddingRegistry.ts, imageRegistry.ts, moderationRegistry.ts,
musicRegistry.ts, rerankRegistry.ts, searchRegistry.ts, videoRegistry.ts),
utilidades de identidad (codexIdentity.ts, codexInstructions.ts,
anthropicHeaders.ts, antigravityUpstream.ts, antigravityModelAliases.ts,
cliFingerprints.ts, toolCloaking.ts, defaultThinkingSignature.ts),
utilidades de credenciales (credentialLoader.ts, codexClient.ts) y adaptadores
de nube (azureAi.ts, bedrock.ts, datarobot.ts, glmProvider.ts,
maritalk.ts, oci.ts, petals.ts, runway.ts, sap.ts, watsonx.ts,
ollamaModels.ts, errorConfig.ts, constants.ts, registryUtils.ts).
4.8 open-sse/utils/
Primitivas de streaming y utilidades de proveedores: stream.ts, streamHandler.ts,
streamHelpers.ts, streamPayloadCollector.ts, streamReadiness.ts,
sseHeartbeat.ts, proxyFetch.ts, proxyDispatcher.ts, tlsClient.ts,
networkProxy.ts, awsSigV4.ts, cacheControlPolicy.ts,
cursorChecksum.ts, cursorAgentProtobuf.ts, cursorVersionDetector.ts,
comfyuiClient.ts, kieTask.ts, bypassHandler.ts, aiSdkCompat.ts,
thinkTagParser.ts, urlSanitize.ts, usageTracking.ts, requestLogger.ts,
progressTracker.ts, cors.ts, error.ts, logger.ts, sleep.ts,
ollamaTransform.ts.
5. electron/ — Contenedor de escritorio
electron/
├── main.js Proceso principal de Electron
├── preload.js Puente de precarga (contextIsolation habilitado)
├── types.d.ts
├── package.json Configuración de electron-builder, versión 3.8.51
├── README.md
├── assets/ Recursos de compilación (iconos, permisos, …)
├── node_modules/ node_modules dedicado (better-sqlite3, electron-updater)
└── dist-electron/ Salida de compilación (no incluida en el repositorio)
Cinco scripts de npm en la raíz del espacio de trabajo: electron:dev, electron:build,
electron:build:{win,mac,linux}, electron:smoke:packaged. La actualización automática se realiza mediante
electron-updater, que apunta al canal de versiones de GitHub.
6. bin/ — CLI
bin/
├── omniroute.mjs Punto de entrada principal de la CLI (Node ESM)
├── reset-password.mjs Restablece la contraseña de administración desde la CLI
├── mcp-server.mjs Iniciador del servidor MCP (stdio)
├── nodeRuntimeSupport.mjs Comprobación de la versión de Node
└── cli/
├── program.mjs Constructor del programa Commander
├── runtime.mjs Función auxiliar withRuntime (primero servidor/respaldo en base de datos)
├── output.mjs Formateadores de salida (json/jsonl/table/csv)
├── i18n.mjs Función auxiliar t() con configuraciones regionales
├── api.mjs Función auxiliar para solicitudes a la API
├── data-dir.mjs
├── encryption.mjs
├── sqlite.mjs
└── commands/
├── registry.mjs Registro de comandos
├── setup.mjs
├── doctor.mjs
├── providers.mjs
└── ... (un archivo por comando/grupo)
Se exponen dos binarios en package.json → bin:
omniroute→bin/omniroute.mjsomniroute-reset-password→bin/reset-password.mjs
7. tests/
| Directorio | Tipo |
|---|---|
tests/unit/ |
Pruebas unitarias mediante el ejecutor de pruebas nativo de Node (1821 archivos, más los subdirectorios api/, auth/ y authz/) |
tests/integration/ |
Pruebas entre módulos y del estado de la base de datos |
tests/e2e/ |
Pruebas de interfaz de usuario con Playwright |
tests/e2e/protocol-clients.test.ts |
Pruebas e2e de los protocolos MCP/A2A |
tests/translator/ |
Pruebas específicas del traductor |
tests/security/ |
Regresiones de seguridad |
tests/load/ |
Pruebas de carga y estrés |
tests/golden-set/ |
Salidas de referencia para regresiones del traductor |
tests/helpers/, tests/fixtures/, tests/manual/ |
Soporte |
Comandos habituales:
| Comando | Qué ejecuta |
|---|---|
npm run test:unit |
Todos los archivos tests/unit/*.test.ts mediante el ejecutor de pruebas de Node (concurrencia 10) |
npm run test:vitest |
Conjunto de pruebas de Vitest (MCP, autoCombo, caché) |
npm run test:e2e |
Conjunto de pruebas de interfaz de usuario de Playwright |
npm run test:protocols:e2e |
Pruebas e2e de los protocolos MCP + A2A |
npm run test:coverage |
Umbral de cobertura (≥60 % de líneas/sentencias/funciones/ramas) |
node --import tsx/esm --test tests/unit/<file>.test.ts |
Ejecución de un único archivo |
8. scripts/
Organizado en 6 subcarpetas según su propósito.
scripts/build/—build-next-isolated.mjs,prepublish.ts,prepare-electron-standalone.mjs,pack-artifact-policy.ts,validate-pack-artifact.ts,postinstall.mjs,postinstallSupport.mjs,uninstall.mjs,bootstrap-env.mjs,runtime-env.mjs,native-binary-compat.mjs.scripts/dev/—run-next.mjs,run-next-playwright.mjs,run-standalone.mjs,standalone-server-ws.mjs,responses-ws-proxy.mjs,v1-ws-bridge.mjs,smoke-electron-packaged.mjs,run-playwright-tests.mjs,run-ecosystem-tests.mjs,run-protocol-clients-tests.mjs,sync-env.mjs,healthcheck.mjs,system-info.mjs.scripts/check/—check-cycles.mjs,check-docs-sync.mjs,check-docs-counts-sync.mjs,check-env-doc-sync.mjs,check-deprecated-versions.mjs,check-route-validation.mjs,check-t11-any-budget.mjs,check-pr-test-policy.mjs,check-supported-node-runtime.ts,test-report-summary.mjs.scripts/docs/—generate-docs-index.mjs,gen-provider-reference.ts.scripts/i18n/—generate-multilang.mjs,run-visual-qa.mjs,generate-qa-checklist.mjs,apply-priority-overrides.mjs,validate_translation.py,check_translations.py,i18n_autotranslate.py,untranslatable-keys.json.scripts/ad-hoc/—cursor-tap.cjs,sync-cursor-models.mjs,migrate-env.mjs,dbsetup.js.
9. Canalización de solicitudes (resumen)
Fuente: diagrams/request-pipeline.mmd
Solicitud del cliente
→ /v1/chat/completions (route.ts)
Comprobación de solicitud de verificación previa CORS
Validación de Zod (chatCompletionsSchema en shared/validation/schemas.ts)
Autenticación (extractApiKey + isValidApiKey O requireManagementAuth)
Motor de políticas (src/server/authz/pipeline.ts)
Medidas de protección (enmascarador de PII, inyección de prompts, puente de visión)
→ handleChatCore() (open-sse/handlers/chatCore.ts)
Comprobación de caché (caché semántica + caché de lectura)
Límite de tasa (rateLimitManager, accountSemaphore)
Enrutamiento combinado (si el modelo se resuelve como una combinación)
comboResolver → bucle por cada destino → handleSingleModel()
translateRequest() (open-sse/translator/request/*)
getExecutor(providerId).execute() (open-sse/executors/*)
solicitud fetch al servidor ascendente → reintento/espera exponencial mediante accountFallback
translateResponse() (open-sse/translator/response/*)
Flujo SSE O respuesta JSON
Si es la API Responses: TransformStream mediante open-sse/transformer/responsesTransformer.ts
→ Auditoría de cumplimiento (src/lib/compliance/)
→ Respuesta al cliente
Estado de ejecución de resiliencia (tres mecanismos)
| Mecanismo | Ámbito | Ubicación |
|---|---|---|
| Disyuntor del proveedor | Proveedor completo | src/shared/utils/circuitBreaker.ts, persistido en domain_circuit_breakers |
| Tiempo de espera de conexión | Una cuenta/clave | markAccountUnavailable() en src/sse/services/auth.ts; utilizado por accountFallback.checkFallbackError() |
| Bloqueo de modelo | Proveedor + conexión + modelo | open-sse/services/accountFallback.ts, persistido en domain_lockout_state |
Consulte RESILIENCE_GUIDE.md y la sección específica en CLAUDE.md.
10. Cómo contribuir
Añadir un nuevo proveedor
- Regístralo en
src/shared/constants/providers.ts(validado con Zod al cargar). - Añade un ejecutor en
open-sse/executors/si se requiere lógica personalizada (extiendeBaseExecutor). - Añade un traductor en
open-sse/translator/si no utiliza el formato de OpenAI. - Si se basa en OAuth, añade la configuración en
src/lib/oauth/providers/ysrc/lib/oauth/services/. - Registra los modelos en
open-sse/config/providerRegistry.ts(o en el registro específico del formato dentro deopen-sse/config/). - Escribe pruebas en
tests/unit/.
Añadir una nueva ruta de API
- Crea
src/app/api/your-route/route.ts. - Sigue el patrón: CORS → validación del cuerpo con Zod → autenticación → delegación al manejador.
- Si la solicitud tiene una estructura nueva: añade el esquema de Zod en
src/shared/validation/schemas.ts. - Si es solo para administración: añade la ruta a
src/shared/constants/publicApiRoutes.ts(lista de exclusión para la superficie de la API pública). - Añade pruebas en
tests/unit/. - Actualiza
docs/reference/API_REFERENCE.mdydocs/openapi.yaml.
Añadir un nuevo módulo de base de datos
- Crea
src/lib/db/yourModule.tse importagetDbInstance()desde./core.ts. - Exporta funciones CRUD para tu dominio.
- Si hay tablas nuevas: añade una migración en
src/lib/db/migrations/, numerada secuencialmente, idempotente y transaccional. - Los módulos que lo importen deben usar importaciones directas desde
@/lib/db/yourModule(sin archivo de barril: se eliminó la antigua capa de reexportaciónlocalDb.ts). - Añade pruebas en
tests/unit/.
Añadir una nueva herramienta MCP
- Añade la definición de la herramienta en
open-sse/mcp-server/tools/(o amplíaopen-sse/mcp-server/schemas/tools.ts). - Asigna los ámbitos adecuados en
src/shared/constants/mcpScopes.ts. - Registra la herramienta en
open-sse/mcp-server/server.ts. - Añade pruebas en
open-sse/mcp-server/__tests__/. - Actualiza MCP-SERVER.md.
Añadir una nueva habilidad A2A
Consulta A2A-SERVER.md § Añadir una nueva habilidad. Las habilidades se encuentran en
src/lib/a2a/skills/ y se registran mediante el gestor de tareas A2A.
11. Convenciones
- Estilo de código: sangría de 2 espacios, comillas dobles, ancho de 100 caracteres, punto y coma,
comas finales
es5; Prettier lo aplica mediantelint-staged. - Importaciones: externas → internas (
@/,@omniroute/open-sse) → relativas. - Nomenclatura: archivos en
camelCaseokebab-case, componentes enPascalCase, constantes enUPPER_SNAKE. - ESLint:
no-eval,no-implied-eval,no-new-func=erroren todas partes;no-explicit-any=warnenopen-sse/ytests/, y error en el resto. - TypeScript:
strict: false(postura heredada). Prefiere tipos explícitos en lugar de inferencia en los límites entre módulos. - Base de datos: nunca escribas SQL sin procesar en rutas o manejadores; utiliza siempre
los módulos de
src/lib/db/. Nunca importes desde un archivo de barril: utiliza directamente módulos específicos desrc/lib/db/*. - Tipado de entidades de base de datos (#3512): una función que escriba o lea la
estructura de una fila de una tabla de base de datos debe aceptar/devolver una interfaz de TS con nombre que refleje
las columnas de esa tabla en una relación 1:1, no
anyni un tipo anónimo en línea en el punto de llamada. Coloca la interfaz junto a la función (p. ej.,export interface UsageEntryensrc/lib/usage/usageHistory.ts, encima desaveRequestUsage), mantén los campos individuales como opcionales/anulables cuando distintos escritores rellenen la fila progresivamente y prefiereunknownen lugar deanypara un campo cuya estructura varíe entre llamadas (documentado en el campo; p. ej.,UsageEntry.tokensacepta tanto los datos de uso sin procesar con la estructura del proveedor como la estructura normalizada). Una vez que el recuento deanyde un archivo llegue a cero de esta forma, añádelo a la lista de permitidos decheck:any-budget:t11(scripts/check/check-t11-any-budget.mjs,maxAny: 0) para evitar regresiones. Esta es una convención inicial de alcance limitado; la eliminación más amplia de "anyanónimos" se realiza de forma iterativa en el resto de la base de código. - Errores: usa try/catch con tipos de error específicos y registra con contexto de pino. Nunca ignores silenciosamente errores en flujos SSE; utiliza señales de cancelación para la limpieza.
- Seguridad: nunca uses
eval()/new Function()/ evaluación implícita. Valida todas las entradas con Zod. Cifra las credenciales en reposo (AES-256-GCM). Mantén la lista de exclusiónsrc/shared/constants/upstreamHeaders.tsalineada con la capa de saneamiento/validación. - Commits: Conventional Commits —
feat(scope): subject. Ámbitos permitidos:db,sse,oauth,dashboard,api,cli,docker,ci,mcp,a2a,memory,skills. - Ramas: prefijos
feat/,fix/,refactor/,docs/,test/,chore/. Nunca hagas commits directamente enmain. - Husky: antes de cada commit se ejecutan
lint-staged+check:docs-sync+check:any-budget:t11; antes de cada push se ejecutancheck:any-budget:t11+check:tracked-artifacts(comprobaciones rápidas; excluyentest:unit).
12. Reglas estrictas (de CLAUDE.md)
- Nunca hagas commit de secretos ni credenciales.
- Nunca uses importaciones de barril; utiliza directamente los módulos específicos de
src/lib/db/*. - Nunca uses
eval()/new Function()/ eval implícito. - Nunca hagas commit directamente en
main. - Nunca escribas SQL sin procesar en las rutas; utiliza siempre los módulos de
src/lib/db/. - Nunca ignores silenciosamente los errores en los flujos SSE.
- Valida siempre las entradas con esquemas de Zod.
- Incluye siempre pruebas al modificar código de producción.
- La cobertura debe mantenerse ≥ 60 % (sentencias, líneas, funciones y ramas).
13. Véase también
- ARCHITECTURE.md — arquitectura de alto nivel y responsabilidades de los módulos.
- API_REFERENCE.md — referencia de las API públicas y de gestión.
- FEATURES.md — matriz de funcionalidades y aspectos destacados de las versiones.
- RESILIENCE_GUIDE.md — análisis detallado del disyuntor, el periodo de espera y el bloqueo.
- AUTO-COMBO.md — puntuación y estrategias de Auto Combo.
- MCP-SERVER.md — catálogo completo de herramientas MCP y transportes.
- A2A-SERVER.md — capacidades y descubrimiento del protocolo A2A.
- COMPRESSION_GUIDE.md — compresión RTK + Caveman.
- CLI-TOOLS.md — integraciones de CLI.
- ELECTRON_GUIDE.md (si está presente), DOCKER_GUIDE.md, FLY_IO_DEPLOYMENT_GUIDE.md, VM_DEPLOYMENT_GUIDE.md, TERMUX_GUIDE.md, PWA_GUIDE.md — destinos de despliegue.
- TROUBLESHOOTING.md — problemas operativos comunes.
- CONTRIBUTING.md — flujo de trabajo para colaboradores.
- CLAUDE.md — reglas del repositorio para Claude Code (la fuente de referencia para muchas de las convenciones anteriores).
- AGENTS.md — referencia de arquitectura más detallada utilizada por los agentes.