feat(forge): M16 skills + M18 subagents in-process + fix read_file cap - #29
feat(forge): M16 skills + M18 subagents in-process + fix read_file cap#29turbillon50 wants to merge 3 commits into
Conversation
V ahora elige modelo según task kind y costo, cae automáticamente al
siguiente del cascade si el provider falla (402/429/5xx), y expone su
consumo en tiempo real. Cubre lo que Luis pidió: "mezclar gratuitas
con paga, que vea consumo en vForge en tiempo real, que se auto-analize
si OpenRouter va".
NUEVO:
lib/forge/models.ts (registry):
Catálogo TS de 8 modelos OpenRouter con tier, kind, costo per 1M,
context window, soporta tools, y fallback_chain ordenado por
conveniencia. Source of truth para routing + costo.
- Premium: anthropic/claude-opus-4.7
- Balanced: anthropic/claude-sonnet-4.6, google/gemini-2.5-pro, openai/gpt-5
- Cheap (paid): anthropic/claude-haiku-4.5, google/gemini-2.5-flash
- Free: minimax/minimax-m2.5:free, google/gemma-4-31b-it:free
normalizeSlug() resuelve los slugs versionados que devuelve OR
(ej. 'anthropic/claude-4.6-sonnet-20260217' → 'anthropic/claude-sonnet-4.6').
lib/forge/routing.ts (policy):
routeFor(task, { costPreference?, excludeSlugs?, forceSlug? }) →
{ primary, cascade, reason }. TASK_PREFERENCES table mapea kind →
modelos preferidos en orden. costPreference: cheapest | balanced |
premium | free-only. suggestTierForBudget() sugiere tier según
saldo restante (M9.5 lo usará para self-throttle automático).
app/api/forge/cost/route.ts (NUEVO):
GET /api/forge/cost?period=today|24h|this_month|last_7d|last_30d
Agrega conversations.cost_usd + tokens + by_model + by_day +
fallback_events count. Cero auth en MVP (Clerk M11).
app/api/admin/health/route.ts (NUEVO):
GET /api/admin/health → { db, vault (con self-test del pepper),
openrouter (balance, usage, latency, status) }. Responde 503 si
alguno está roto. Activity dashboard + futura cron Trigger.dev.
MODIFICADO:
app/api/forge/run/route.ts:
- Importa routeFor + estimateCostForModel + normalizeSlug.
- Reemplaza LEGACY_MODEL_MAP por routeFor("chat-main", { forceSlug })
cuando system_config.default_model está en la registry; si no,
free-form override + cascade del task default.
- Inner retry loop: try create() → si error 402/429/5xx + hay cascade
siguiente, emit "model_fallback" event + retry con next slug.
Non-recoverable bubble out.
- audit_events.payload incluye cascade_tried, fallbacks[], routing_reason.
- Cost calc unificado vía estimateCostForModel (elimina PRICING
duplicado al final del archivo).
- errorStatus() helper que extrae status code de OpenAI APIError o
del prefix "402 ..." en err.message.
lib/forge/tools.ts:
- import routeFor + MODELS.
- Tool nueva: model_recommend(task, cost_preference?) → devuelve
{ primary, cascade, reason, primary_info }. Para que V tome
decisiones de modelo informadas antes de openrouter_query.
- Tool nueva: forge_cost_report(period?) → query agregado en
conversations + audit_events; devuelve totales, by_model top 8,
fallback_events count. Para que V responda "cuánto vas gastando"
con datos reales, no inventados.
Smoke local en /api/forge/cost?period=this_month: $25.20 / 175 turns
across 3 models (Sonnet via OR $18.85, legacy claude-sonnet-4-6 $6.25,
MiniMax free $0.10). Health: db 57ms, vault round-trip OK,
OpenRouter balance $20 usage $19.61 latency 235ms.
NO cambia el contract SSE hacia el frontend. NO cambia tools existentes.
NO agrega deps.
https://claude.ai/code/session_01Parr3CGTU4ucH6xReyNJ2G
V ya puede descubrir y "instalar" habilidades reusables al vuelo. Cada
skill es un paquete autodescriptivo: system prompt fragment + lista de
tools requeridas + ring level + tags. Cuando Luis describe una tarea,
V invoca skill_search → skill_install y opera con instrucciones
específicas durante el resto del turno.
NUEVO:
migrations/005_skills.sql:
- Tabla skills con id, name, description, system_prompt, required_tools,
examples, ring_max, source, tags, invocation_count.
- Tabla skill_invocations para audit (skill_id, session_id, outcome).
- pg_trgm + índices GIN sobre name/description/tags para ILIKE rápido.
- Sin embeddings (coherente con "solo OpenRouter" — OR no vende
embeddings). Si el catálogo crece, agregamos pgvector + OpenAI
text-embedding-3-small en M16.5.
migrations/006_skills_builtin.sql:
Seeds: 7 skills cubriendo los flujos canónicos de vForge.
- repo-rescue (ring 1) protocolo RESCATE
- new-project-bootstrap (ring 1) protocolo NUEVO
- dns-vercel-namecom (ring 1) apuntar dominio
- github-pr-author (ring 1) cambio en repo via PR
- vercel-deploy-debug (ring 1) diagnóstico build fallido
- code-review (ring 0) review sin escribir
- bulk-categorizer (ring 1) clasificar repos en masa
lib/forge/skills.ts:
- tokenize(query): split en palabras + strip de acentos + stopwords
ES+EN para que "rescatar" matche "rescate" y "vercel" matche
"Vercel" sin importar acentos.
- searchSkills(query, topK): WITH tokens AS (...) + score híbrido
(tag exacto > name substring > tag substring > desc substring).
- getSkillBody(id): full skill + bump invocation_count + insert en
skill_invocations. Fire-and-forget para no bloquear.
- listSkills() para futuros /modules dashboards.
lib/forge/tools.ts:
- skill_search (Ring 0): { query, top_k } → top matches resumidos.
- skill_install (Ring 0): { skill_id } → full body con
system_prompt + required_tools + instrucciones explícitas para V.
Smoke test contra Neon production: los 6 queries naturales devuelven
el skill correcto en top 1 con scores 75-565.
NO cambia tools existentes. NO requiere deploy de Vercel para que las
migrations apliquen (ya las apliqué directo en Neon).
Pendiente próxima tanda: M18 subagentes paralelos in-process.
https://claude.ai/code/session_01Parr3CGTU4ucH6xReyNJ2G
…ile cap
V puede ahora despachar tareas a sub-agentes especializados que corren
en paralelo dentro del mismo turno. Sin Trigger.dev (M9 lo upgrade a
durable), pero suficiente para descargar 5-50 tareas cortas a la vez:
clasificar repos, sumarizar dumps, reviewer múltiples archivos.
NUEVO:
lib/forge/subagents.ts:
8 roles built-in con system prompt + modelo default optimizado:
- researcher → google/gemini-2.5-flash
- reviewer → anthropic/claude-sonnet-4.6
- coder → anthropic/claude-sonnet-4.6
- tester → anthropic/claude-haiku-4.5
- categorizer → google/gemini-2.5-flash
- summarizer → anthropic/claude-haiku-4.5
- extractor → anthropic/claude-haiku-4.5
- translator → google/gemini-2.5-flash
runSubagent({ role, task, model?, maxTokens?, signal? }) → llama
openRouterAdapter.execute() con system prompt del rol. Devuelve
{ role, model, content, tokens_in, tokens_out, cost_usd,
duration_ms, finish_reason }.
recordSubagentRun() persiste a conversations + audit_events para
que el cost dashboard agregue. Fire-and-forget. Cada run aparece
con session_id = parent + ':subagent:' + role.
lib/forge/tools.ts:
Tools nuevas (M18):
- spawn_subagent(role, task, model?, max_tokens?) — Ring 0.
V puede llamar N en paralelo en una sola tool round; el
dispatcher las ejecuta con Promise.all (ya existente).
- list_subagent_roles() — Ring 0. V consulta qué roles existen
antes de spawn si no recuerda.
Fix bug crítico (V reportó hoy):
github_read_file YA NO trunca a 5KB. Default 50KB. max_bytes
hasta 500KB. offset para paginar archivos enormes. Devuelve
total_bytes + next_offset para que V sepa cuándo seguir leyendo
el siguiente chunk. Resuelve "V ciega en archivos grandes" —
tools.ts pesa 58KB, era invisible al modelo.
Smoke test PASS contra producción:
3 subagents en paralelo (summarizer + categorizer + translator),
wall-clock 3673ms vs serial sum 9100ms → speedup 2.48x.
Total cost: \$0.000442 (Haiku + 2x Flash).
V puede ahora orquestar: "audita los 52 repos del catálogo" →
spawn_subagent('categorizer', ...) x52 en una sola round → resultados
en ~5-10s wall-clock vs ~4 minutos serial.
https://claude.ai/code/session_01Parr3CGTU4ucH6xReyNJ2G
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 02f044196d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const cascade = isKnownSlug | ||
| ? routing.cascade | ||
| : [configuredModel, ...routing.cascade]; |
There was a problem hiding this comment.
Map legacy default_model slugs before building cascade
This path now prepends unknown system_config.default_model values directly into the model cascade, but seeded installs still use legacy values like claude-sonnet-4-6 (see existing migrations), which are not valid OpenRouter slugs. Because fallback only retries for 402/429/5xx, the first call fails with a non-recoverable 4xx and the chat turn aborts instead of reaching valid fallback models, effectively breaking default deployments until config is manually edited.
Useful? React with 👍 / 👎.
| case "this_month": | ||
| since = new Date(now.getUTCFullYear(), now.getUTCMonth(), 1); | ||
| break; |
There was a problem hiding this comment.
Compute this_month boundary in UTC consistently
this_month mixes UTC getters with the local-time Date(year, month, day) constructor, so in non-UTC runtimes the window starts at local midnight (shifted in UTC) instead of 00:00:00Z on day 1. That skews month-to-date spend/tokens by several hours and makes this period inconsistent with the explicit UTC handling already used for today.
Useful? React with 👍 / 👎.
Resumen
Tres avances en un PR. V ahora descubre skills relevantes, los aplica, y delega trabajo paralelo a sub-agentes especializados. Plus un bug fix crítico: V dejaba de ver archivos > 5KB.
M16 — Skills registry (commit
5925c1c)V tiene un catálogo de 7 habilidades reusables que puede buscar por texto natural y "instalar" al vuelo:
repo-rescuenew-project-bootstrapdns-vercel-namecomgithub-pr-authorvercel-deploy-debugcode-reviewbulk-categorizerTools:
skill_search(query, top_k)+skill_install(skill_id). Search por trigram ILIKE + tokenize ES+EN + stopwords. Cada query natural devuelve el skill correcto en top 1 (smoke contra Neon production con 6 queries PASS).M18 light — Subagentes paralelos in-process (commit
02f0441)V puede invocar N sub-agentes en una sola tool round → el dispatcher los corre con
Promise.all. Smoke test 3 subagents en paralelo → speedup 2.48x (3.67s vs 9.1s serial), costo total $0.000442.8 roles built-in con modelo optimizado:
researcherreviewercodertestercategorizersummarizerextractortranslatorTools:
spawn_subagent(role, task, model?, max_tokens?)+list_subagent_roles(). Persistencia automática aconversations+audit_eventscon session_id = parent + ':subagent:' + role para que el cost dashboard agregue.Sin Trigger.dev todavía (M9 lo upgrade a durable). Si el SSE cierra, results se pierden. Suficiente para tareas < 60s totales.
Fix bug crítico:
github_read_filecapV reportó hoy: "Mi tool github_read_file trunca a 5KB y el repo tiene archivos de 58KB+. No puedo ver el código completo — estoy ciega en archivos grandes."
max_bytes(hasta 500KB)offsetpara paginar archivos enormestotal_bytes+next_offsetpara que V sepa cuándo seguirArchivos
migrations/005_skills.sqlmigrations/006_skills_builtin.sqllib/forge/skills.tslib/forge/subagents.tslib/forge/tools.tsTest plan
tsc --noEmitpasaLo que NO incluye
Pendiente próxima tanda
https://claude.ai/code/session_01Parr3CGTU4ucH6xReyNJ2G
Generated by Claude Code