diff --git a/.agent/agents/README.md b/.agent/agents/README.md index b5b95eb7..23e09d93 100644 --- a/.agent/agents/README.md +++ b/.agent/agents/README.md @@ -16,7 +16,8 @@ Estos agentes vinculan la planificación (`.agent/PLANS.md`), la configuración - Configuración en `docs/ai/CONFIGURACION_API_KEYS.md` (`ANTHROPIC_API_KEY`). - ExecPlan vivo: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. - Scripts: `scripts/coding/ai/generators/llm_generator.py` (`llm_provider="anthropic"`) y `scripts/coding/ai/orchestrators/codex_mcp_workflow.py`. - - Guías: `docs/ai/SDLC_AGENTS_GUIDE.md` y `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md`. + - Guías: `docs/ai/SDLC_AGENTS_GUIDE.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md` y `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`. + - Código reutilizable: `scripts/coding/ai/shared/context_sessions.py` para trimming/summarizing multi-LLM. #### ChatGPTAgent @@ -26,7 +27,8 @@ Estos agentes vinculan la planificación (`.agent/PLANS.md`), la configuración - Configuración en `docs/ai/CONFIGURACION_API_KEYS.md` (`OPENAI_API_KEY`). - ExecPlan: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. - Scripts: `scripts/coding/ai/generators/llm_generator.py` (`llm_provider="openai"`) y `scripts/coding/ai/orchestrators/codex_mcp_workflow.py`. - - Guías: `docs/ai/SDLC_AGENTS_GUIDE.md` y `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md`. + - Guías: `docs/ai/SDLC_AGENTS_GUIDE.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md` y `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`. + - Código reutilizable: `scripts/coding/ai/shared/context_sessions.py` para trimming/summarizing multi-LLM. #### HuggingFaceAgent @@ -36,7 +38,8 @@ Estos agentes vinculan la planificación (`.agent/PLANS.md`), la configuración - Configuración en `docs/ai/CONFIGURACION_API_KEYS.md` (`HF_LOCAL_MODEL_PATH`, `HF_MODEL_ID`, `HUGGINGFACEHUB_API_TOKEN`). - ExecPlan: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. - Scripts: `scripts/coding/ai/generators/llm_generator.py` (`llm_provider="huggingface"`) y `scripts/coding/ai/orchestrators/codex_mcp_workflow.py`. - - Guías: `docs/ai/SDLC_AGENTS_GUIDE.md`, `docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md` y `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md`. + - Guías: `docs/ai/SDLC_AGENTS_GUIDE.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`, `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md` y `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`. + - Código reutilizable: `scripts/coding/ai/shared/context_sessions.py` para trimming/summarizing multi-LLM. ### Agentes por dominio @@ -46,31 +49,31 @@ Los siguientes agentes conectan la estructura del repositorio (api, ui, infrastr - **Archivo**: `api_agent.md` - **Directorio base**: `api/` -- **Relaciones clave**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/ai/SDLC_AGENTS_GUIDE.md`, `scripts/coding/ai/orchestrators/codex_mcp_workflow.py`. +- **Relaciones clave**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/ai/SDLC_AGENTS_GUIDE.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`, `scripts/coding/ai/shared/context_sessions.py`, `scripts/coding/ai/orchestrators/codex_mcp_workflow.py`. #### UiAgent (Frontend) - **Archivo**: `ui_agent.md` - **Directorio base**: `ui/` -- **Relaciones clave**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/ai_capabilities/prompting/CODE_GENERATION_GUIDE.md`, `docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`. +- **Relaciones clave**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/prompting/CODE_GENERATION_GUIDE.md`, `docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`, `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`, `scripts/coding/ai/shared/context_sessions.py`. #### InfrastructureAgent - **Archivo**: `infrastructure_agent.md` - **Directorio base**: `infrastructure/` -- **Relaciones clave**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/gobernanza/metodologias/agentes_automatizacion.md`, planes `SPEC_INFRA_*`. +- **Relaciones clave**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`, `docs/gobernanza/metodologias/agentes_automatizacion.md`, `scripts/coding/ai/shared/context_sessions.py`, planes `SPEC_INFRA_*`. #### DocsAgent - **Archivo**: `docs_agent.md` - **Directorio base**: `docs/` -- **Relaciones clave**: `docs/analisis/AGENTS.md`, `scripts/coding/ai/agents/documentation/eta_codex_agent.py`, `docs/testing/test_documentation_alignment.py`. +- **Relaciones clave**: `docs/analisis/AGENTS.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`, `scripts/coding/ai/shared/context_sessions.py`, `scripts/coding/ai/agents/documentation/eta_codex_agent.py`, `docs/testing/test_documentation_alignment.py`. #### ScriptsAgent - **Archivo**: `scripts_agent.md` - **Directorio base**: `scripts/` -- **Relaciones clave**: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`, `docs/scripts/README.md`, `scripts/coding/ai/generators/llm_generator.py`. +- **Relaciones clave**: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`, `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`, `docs/scripts/README.md`, `scripts/coding/ai/shared/context_sessions.py`, `scripts/coding/ai/generators/llm_generator.py`. ### 1. GitOpsAgent diff --git a/.agent/agents/api_agent.md b/.agent/agents/api_agent.md index 5909121b..1c4cc2c6 100644 --- a/.agent/agents/api_agent.md +++ b/.agent/agents/api_agent.md @@ -7,6 +7,8 @@ Guiar cualquier automatización relacionada con el backend (`api/`) asegurando q ## Integraciones Clave - **ExecPlans**: `docs/plans/EXECPLAN_agents_domain_alignment.md` (relación dominio ↔ agentes) y `docs/plans/EXECPLAN_codex_mcp_multi_llm.md` (estrategia multi-LLM). +- **Catálogo de prompts**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` indica qué técnicas aplicar con Claude, ChatGPT u Hugging Face antes de generar especificaciones para la API. +- **Gestión de contexto**: `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` y `scripts/coding/ai/shared/context_sessions.py` coordinan trimming/summarization para flujos prolongados de soporte o incidentes. - **Guías SDLC**: `docs/ai/SDLC_AGENTS_GUIDE.md` y `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md` para coordinación multi-agente. - **Scripts**: `scripts/coding/ai/orchestrators/codex_mcp_workflow.py` (briefs de trabajo) y `scripts/coding/ai/generators/llm_generator.py` (TDD asistido). - **Config**: variables en `.env` gestionadas por `scripts/coding/ai/shared/env_loader.py` (autodetección de `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `HUGGINGFACEHUB_API_TOKEN`). diff --git a/.agent/agents/chatgpt_agent.md b/.agent/agents/chatgpt_agent.md index dbea33bd..6ef864fe 100644 --- a/.agent/agents/chatgpt_agent.md +++ b/.agent/agents/chatgpt_agent.md @@ -8,6 +8,8 @@ Centralizar el uso de modelos ChatGPT/OpenAI dentro de los flujos de automatizac - **Configuración de credenciales**: `docs/ai/CONFIGURACION_API_KEYS.md` incluye los pasos para definir `OPENAI_API_KEY` y habilitar modos híbridos. - **ExecPlan vivo**: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md` mantiene la estrategia multi-LLM y debe actualizarse cuando cambien las capacidades o defaults de OpenAI. +- **Catálogo de prompts**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` consolida las técnicas multi-LLM antes de personalizar prompts para ChatGPT. +- **Gestión de contexto**: `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` y `scripts/coding/ai/shared/context_sessions.py` definen trimming y summarization compatibles con OpenAI. - **Agente generador de tests**: `scripts/coding/ai/generators/llm_generator.py` soporta `llm_provider="openai"` para generar pruebas o documentación asistida con ChatGPT. - **Builder MCP**: `scripts/coding/ai/orchestrators/codex_mcp_workflow.py` emite briefs con banderas MCP y modelos recomendados (por ejemplo `gpt-5`) para OpenAI. - **Guía operativa**: `docs/ai/SDLC_AGENTS_GUIDE.md` detalla cuándo alternar entre modos heurísticos y LLM. diff --git a/.agent/agents/claude_agent.md b/.agent/agents/claude_agent.md index ec6d54e7..35f330b8 100644 --- a/.agent/agents/claude_agent.md +++ b/.agent/agents/claude_agent.md @@ -8,6 +8,8 @@ Orquestar las integraciones con modelos Claude (Anthropic) dentro del flujo SDLC - **Configuración de credenciales**: `docs/ai/CONFIGURACION_API_KEYS.md` describe cómo declarar `ANTHROPIC_API_KEY` en `.env` y validar la detección automática del proveedor. - **ExecPlan vivo**: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md` resume la estrategia multi-LLM y mantiene el historial de decisiones para Codex MCP. +- **Catálogo de prompts**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` reúne las técnicas multi-LLM recomendadas antes de diseñar prompts especializados para Claude. +- **Gestión de contexto**: `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` y `scripts/coding/ai/shared/context_sessions.py` definen trimming y summarization compartidos entre proveedores. - **Agente generador de tests**: `scripts/coding/ai/generators/llm_generator.py` soporta `llm_provider="anthropic"` y usa Claude como backend por defecto. - **Builder MCP**: `scripts/coding/ai/orchestrators/codex_mcp_workflow.py` genera briefs single/multi-agent asegurando banderas MCP correctas cuando el proveedor es Anthropic. - **Guía operativa**: `docs/ai/SDLC_AGENTS_GUIDE.md` contiene los lineamientos de uso y compara el modo LLM vs heurístico. diff --git a/.agent/agents/docs_agent.md b/.agent/agents/docs_agent.md index 9fb538e1..e7ed15f9 100644 --- a/.agent/agents/docs_agent.md +++ b/.agent/agents/docs_agent.md @@ -9,7 +9,8 @@ Garantizar que los cambios en `docs/` sigan la gobernanza del ETA-AGENTE CODEX y - **Agente rector**: `docs/analisis/AGENTS.md` (ETA-AGENTE CODEX) y `scripts/coding/ai/agents/documentation/eta_codex_agent.py`. - **ExecPlans**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. - **Pruebas**: `docs/testing/test_documentation_alignment.py` asegura consistencia de enlaces y ubicación. -- **Playbooks**: `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md`, `docs/ai_capabilities/prompting/CODE_GENERATION_GUIDE.md`. +- **Playbooks**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md`, `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`, `docs/ai_capabilities/prompting/CODE_GENERATION_GUIDE.md`. +- **Sesiones de contexto**: `scripts/coding/ai/shared/context_sessions.py` para mantener resúmenes consistentes en revisiones prolongadas. ## Procedimiento Recomendado diff --git a/.agent/agents/huggingface_agent.md b/.agent/agents/huggingface_agent.md index ffbcd08c..36a1a84a 100644 --- a/.agent/agents/huggingface_agent.md +++ b/.agent/agents/huggingface_agent.md @@ -8,6 +8,8 @@ Guiar el uso de modelos Hugging Face (locales o alojados) dentro de los pipeline - **Configuración de entorno**: `docs/ai/CONFIGURACION_API_KEYS.md` detalla cómo definir rutas locales (`HF_LOCAL_MODEL_PATH`) o `HF_MODEL_ID` y cuándo se requiere `HUGGINGFACEHUB_API_TOKEN`. - **ExecPlan vivo**: `docs/plans/EXECPLAN_codex_mcp_multi_llm.md` mantiene la estrategia para balancear los tres proveedores y debe reflejar cualquier cambio en modelos Hugging Face. +- **Catálogo de prompts**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` consolida las técnicas multi-LLM que deben adaptarse antes de aplicar prompt engineering específico (p. ej. TinyLlama o Phi-3). +- **Gestión de contexto**: `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` y `scripts/coding/ai/shared/context_sessions.py` cubren trimming/summarization para sesiones largas en modelos locales. - **Agente generador de tests**: `scripts/coding/ai/generators/llm_generator.py` soporta `llm_provider="huggingface"` y permite reutilizar modelos QLoRA o checkpoints locales. - **Builder MCP**: `scripts/coding/ai/orchestrators/codex_mcp_workflow.py` expone defaults y banderas MCP al usar el proveedor `huggingface`. - **Guías de capacidad**: diff --git a/.agent/agents/infrastructure_agent.md b/.agent/agents/infrastructure_agent.md index 8739fc11..b8d88b3f 100644 --- a/.agent/agents/infrastructure_agent.md +++ b/.agent/agents/infrastructure_agent.md @@ -7,6 +7,8 @@ Coordinar automatizaciones relacionadas con `infrastructure/`, incluyendo IaC, p ## Integraciones Clave - **ExecPlans**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/plans/EXECPLAN_codex_mcp_multi_llm.md` y los planes específicos de infraestructura (`docs/plans/SPEC_INFRA_*.md`). +- **Catálogo de prompts**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` sirve como guía para seleccionar técnicas multi-LLM cuando la automatización afecta pipelines o servicios usados por los modelos. +- **Gestión de contexto**: `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` y `scripts/coding/ai/shared/context_sessions.py` documentan la memoria compartida entre incidentes prolongados y runbooks de infraestructura. - **Gobernanza**: `docs/gobernanza/metodologias/agentes_automatizacion.md` y runbooks en `docs/operaciones/`. - **Agentes complementarios**: `DependencyAgent` para escaneos de paquetes, `ReleaseAgent` para coordinaciones de despliegue, `SecurityAgent` (si aplica) para hardening. - **Scripts**: `scripts/infrastructure/` (si existe) y pipelines en `infrastructure/`. diff --git a/.agent/agents/scripts_agent.md b/.agent/agents/scripts_agent.md index a4e28b04..4737ef94 100644 --- a/.agent/agents/scripts_agent.md +++ b/.agent/agents/scripts_agent.md @@ -7,6 +7,8 @@ Orquestar cambios en `scripts/` garantizando que las automatizaciones, generador ## Integraciones Clave - **ExecPlans**: `docs/plans/EXECPLAN_agents_domain_alignment.md`, `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. +- **Catálogo de prompts**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` para seleccionar estrategias multi-LLM antes de automatizar generadores o validadores. +- **Memoria de contexto**: `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` y `scripts/coding/ai/shared/context_sessions.py` habilitan sesiones compartidas en herramientas que atienden hilos extensos. - **Código**: `scripts/coding/ai/` (generators, orchestrators, shared utilities) y `scripts/tests/`. - **Pruebas**: `pytest scripts/coding/tests/...` y `pytest scripts/tests/...`. - **Documentación**: `docs/scripts/README.md`, `docs/scripts/SCRIPTS_MATRIX.md` y `docs/operaciones/verificar_servicios.md`. diff --git a/.agent/agents/ui_agent.md b/.agent/agents/ui_agent.md index 760b8195..901fc2f6 100644 --- a/.agent/agents/ui_agent.md +++ b/.agent/agents/ui_agent.md @@ -7,7 +7,8 @@ Alinear el trabajo automatizado sobre el frontend (`ui/`) con las prácticas de ## Integraciones Clave - **ExecPlans**: `docs/plans/EXECPLAN_agents_domain_alignment.md` y `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. -- **Playbooks**: `docs/ai_capabilities/prompting/CODE_GENERATION_GUIDE.md` y `docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`. +- **Playbooks**: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, `docs/ai_capabilities/prompting/CODE_GENERATION_GUIDE.md`, `docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md` y `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` (memoria de contexto compartida con backend/infrastructure). +- **Sesiones de contexto**: `scripts/coding/ai/shared/context_sessions.py` para trimming/summarization cuando los flujos UX requieren iteraciones largas. - **Orquestación**: `scripts/coding/ai/orchestrators/codex_mcp_workflow.py` (multi-agente) y `scripts/coding/ai/generators/llm_generator.py` (generación guiada por TDD). - **Documentación UX**: briefs y wireframes creados por el Designer Agent se ubican en `docs/` o `design/` según el ExecPlan activo. diff --git a/README.md b/README.md index 746af456..8afa3306 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,11 @@ DB_IVR_PASSWORD=django_pass > documentado en [`docs/ai/FINE_TUNING_TINYLLAMA.md`](docs/ai/FINE_TUNING_TINYLLAMA.md), y > revisa el playbook de prompting con Phi-3 en > [`docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`](docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md). +> Para técnicas de prompting transversales a todos los proveedores revisa el catálogo +> multi-LLM en [`docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`](docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md). +> Para memoria de contexto y manejo de sesiones largas (trimming/summarization), consulta +> [`docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`](docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md) +> y reutiliza las clases disponibles en [`scripts/coding/ai/shared/context_sessions.py`](scripts/coding/ai/shared/context_sessions.py). ### 2. Ejecutar migraciones diff --git a/docs/ai/SDLC_AGENTS_GUIDE.md b/docs/ai/SDLC_AGENTS_GUIDE.md index 89e6f661..a7b60e1e 100644 --- a/docs/ai/SDLC_AGENTS_GUIDE.md +++ b/docs/ai/SDLC_AGENTS_GUIDE.md @@ -128,9 +128,9 @@ config = { Para asegurar coherencia entre planificación, credenciales y herramientas, consulta las fichas específicas en `.agent/agents/`: -- **ClaudeAgent** (`.agent/agents/claude_agent.md`): describe el flujo completo cuando `llm_provider="anthropic"`, incluyendo configuración de `ANTHROPIC_API_KEY`, uso del `LLMGenerator` y orquestaciones Codex MCP documentadas en `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. -- **ChatGPTAgent** (`.agent/agents/chatgpt_agent.md`): guía las integraciones con modelos GPT/OpenAI, detalla el uso de `OPENAI_API_KEY` y enlaza con `scripts/coding/ai/orchestrators/codex_mcp_workflow.py`. -- **HuggingFaceAgent** (`.agent/agents/huggingface_agent.md`): centraliza el trabajo con modelos locales o alojados en Hugging Face, indicando rutas (`HF_LOCAL_MODEL_PATH`, `HF_MODEL_ID`) y las guías complementarias (`docs/ai_capabilities/prompting/PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`). +- **ClaudeAgent** (`.agent/agents/claude_agent.md`): describe el flujo completo cuando `llm_provider="anthropic"`, enlazando el catálogo `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md`, la configuración de `ANTHROPIC_API_KEY`, el uso del `LLMGenerator`, la memoria de contexto documentada en `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md` y las orquestaciones Codex MCP de `docs/plans/EXECPLAN_codex_mcp_multi_llm.md`. +- **ChatGPTAgent** (`.agent/agents/chatgpt_agent.md`): guía las integraciones con modelos GPT/OpenAI, combina el catálogo `PROMPT_TECHNIQUES_CATALOG.md`, el playbook de contexto multi-LLM (`CONTEXT_MANAGEMENT_PLAYBOOK.md`), `OPENAI_API_KEY` y referencia `scripts/coding/ai/orchestrators/codex_mcp_workflow.py` junto a `scripts/coding/ai/shared/context_sessions.py`. +- **HuggingFaceAgent** (`.agent/agents/huggingface_agent.md`): centraliza el trabajo con modelos locales o alojados en Hugging Face, relacionando `PROMPT_TECHNIQUES_CATALOG.md`, rutas (`HF_LOCAL_MODEL_PATH`, `HF_MODEL_ID`), el playbook `PHI3_PROMPT_ENGINEERING_PLAYBOOK.md` y la guía de contexto compartido `CONTEXT_MANAGEMENT_PLAYBOOK.md`. Estas fichas son complementarias a esta guía y deben revisarse antes de ejecutar tareas multi-LLM. @@ -138,11 +138,11 @@ Estas fichas son complementarias a esta guía y deben revisarse antes de ejecuta Para alinear la arquitectura del repositorio con los agentes automatizados, consulta también las fichas por dominio en `.agent/agents/`: -- **ApiAgent** (`api_agent.md`): centraliza la coordinación del backend (`api/`) con los ExecPlans `EXECPLAN_agents_domain_alignment.md` y `EXECPLAN_codex_mcp_multi_llm.md`, además de los briefs generados por `CodexMCPWorkflowBuilder`. -- **UiAgent** (`ui_agent.md`): une los entregables del Designer Agent con la implementación en `ui/`, reutilizando los playbooks de prompting (`CODE_GENERATION_GUIDE.md`, `PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`). -- **InfrastructureAgent** (`infrastructure_agent.md`): orquesta cambios en `infrastructure/` en conjunto con los agentes operativos (Dependency, Release, Security) y los planes `SPEC_INFRA_*`. -- **DocsAgent** (`docs_agent.md`): asegura que toda modificación en `docs/` respete al ETA-AGENTE CODEX y a los validadores de documentación. -- **ScriptsAgent** (`scripts_agent.md`): gobierna la evolución de `scripts/` manteniendo el enfoque TDD y sincronización con los generadores/orquestadores LLM. +- **ApiAgent** (`api_agent.md`): centraliza la coordinación del backend (`api/`) con los ExecPlans `EXECPLAN_agents_domain_alignment.md`, `EXECPLAN_codex_mcp_multi_llm.md`, el catálogo `PROMPT_TECHNIQUES_CATALOG.md`, el playbook `CONTEXT_MANAGEMENT_PLAYBOOK.md` y los briefs generados por `CodexMCPWorkflowBuilder`. +- **UiAgent** (`ui_agent.md`): une los entregables del Designer Agent con la implementación en `ui/`, reutilizando los playbooks de prompting (`PROMPT_TECHNIQUES_CATALOG.md`, `CODE_GENERATION_GUIDE.md`, `PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`) y las sesiones de contexto descritas en `CONTEXT_MANAGEMENT_PLAYBOOK.md`. +- **InfrastructureAgent** (`infrastructure_agent.md`): orquesta cambios en `infrastructure/` en conjunto con los agentes operativos (Dependency, Release, Security), el catálogo `PROMPT_TECHNIQUES_CATALOG.md`, el playbook `CONTEXT_MANAGEMENT_PLAYBOOK.md` y los planes `SPEC_INFRA_*`. +- **DocsAgent** (`docs_agent.md`): asegura que toda modificación en `docs/` respete al ETA-AGENTE CODEX, el catálogo `PROMPT_TECHNIQUES_CATALOG.md`, la guía de contexto multi-LLM y los validadores de documentación. +- **ScriptsAgent** (`scripts_agent.md`): gobierna la evolución de `scripts/` manteniendo el enfoque TDD, el catálogo `PROMPT_TECHNIQUES_CATALOG.md`, el playbook `CONTEXT_MANAGEMENT_PLAYBOOK.md` y la sincronización con los generadores/orquestadores LLM. Cada vez que inicies un ExecPlan nuevo, referencia tanto la ficha del proveedor LLM como la del dominio involucrado para mantener la trazabilidad completa. diff --git a/docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md b/docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md new file mode 100644 index 00000000..0fd087a9 --- /dev/null +++ b/docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md @@ -0,0 +1,132 @@ +# Context Management Playbook + +Esta guía describe cómo gestionar memoria de contexto en agentes largos utilizando las sesiones `TrimmingSession` y `SummarizingSession` incluidas en `scripts/coding/ai/shared/context_sessions.py`. El objetivo es ofrecer una estrategia uniforme para Claude (Anthropic), ChatGPT (OpenAI) y los modelos operados desde Hugging Face, asegurando coherencia, costos predecibles y trazas auditables en cualquier dominio (`api/`, `ui/`, `infrastructure/`, `docs/`, `scripts/`). + +## 1. Por qué importa el contexto + +- **Coherencia sostenida**: los agentes mantienen el objetivo actual sin reciclar historiales desactualizados. +- **Precisión en llamadas a herramientas**: un contexto curado reduce reintentos, tiempos de espera y errores de parámetros. +- **Latencia y costos controlados**: menos tokens por turno implican tiempos de respuesta y facturación estables. +- **Mitigación de alucinaciones**: los resúmenes sirven como “cuartos limpios” que corrigen hechos dudosos antes de seguir iterando. +- **Observabilidad**: historiales acotados facilitan diffs de sesiones, reproducen fallos y habilitan evaluaciones comparables. + +## 2. Relación con los agentes del repositorio + +- `ClaudeAgent`, `ChatGPTAgent` y `HuggingFaceAgent` (en `.agent/agents/`) referencian este playbook como política oficial de memoria. +- Los agentes de dominio (`ApiAgent`, `UiAgent`, `InfrastructureAgent`, `DocsAgent`, `ScriptsAgent`) delegan en estas sesiones cuando ejecutan planes desde sus ExecPlans. +- `CodexMCPWorkflowBuilder` puede envolver cualquiera de las sesiones para mantener threads extensos generados por Codex MCP. + +## 3. Preparativos y dependencias + +1. Configura las claves descritas en `docs/ai/CONFIGURACION_API_KEYS.md` para el proveedor que vayas a usar. +2. Instala el SDK correspondiente: + ```bash + pip install openai-agents openai + ``` +3. Opcional: registra claves adicionales (`ANTHROPIC_API_KEY`, `HUGGINGFACEHUB_API_TOKEN`) si alternas entre proveedores. +4. Estructura tu `.env` siguiendo `docs/ai_capabilities/orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md` si ejecutas agentes MCP. + +## 4. Sesiones con recorte (`TrimmingSession`) + +`TrimmingSession` conserva únicamente los últimos *N* turnos reales del usuario (un turno = mensaje del usuario + respuestas y herramientas hasta el siguiente usuario). Se recomienda para flujos operativos donde cada paso es independiente. + +```python +from scripts.coding.ai.shared.context_sessions import TrimmingSession + +session = TrimmingSession("customer-support", max_turns=3) +await session.add_items([ + {"role": "user", "content": "Primer problema"}, + {"role": "assistant", "content": "Respuesta"}, +]) +# ... +recent_items = await session.get_items() +``` + +**Ventajas** +- Determinismo total: sin resúmenes ni llamadas adicionales. +- Sin latencia extra: no se invocan modelos adicionales para resumir. +- Ideal para automatizaciones de soporte, CRM o scripts internos de infraestructura. + +**Limitaciones** +- Olvida de forma abrupta cualquier restricción o identificador anterior a *N* turnos. +- Historiales recientes muy extensos (por ejemplo, respuestas de herramientas pesadas) aún pueden saturar la ventana. + +## 5. Sesiones con resumen (`SummarizingSession`) + +`SummarizingSession` mantiene verbatim los últimos turnos y comprime el resto en un bloque sintético usuario→assistant. El resumen se realiza mediante un componente asíncrono que puedes implementar con cualquier modelo compatible. + +```python +from scripts.coding.ai.shared.context_sessions import SummarizingSession + +class SupportSummarizer: + async def summarize(self, messages): + shadow_prompt = "Summarize the conversation we had so far." + summary_text = "\n".join( + f"- {msg['role']}: {msg['content']}" for msg in messages + ) + return shadow_prompt, summary_text + +session = SummarizingSession( + keep_last_n_turns=2, + context_limit=4, + summarizer=SupportSummarizer(), + session_id="enterprise-case-001", +) +await session.add_items([...]) +current_context = await session.get_items() +``` + +**Ventajas** +- Conserva decisiones, identificadores y restricciones más allá de *N* turnos. +- Experiencia fluida para el usuario: el agente “recuerda” acuerdos previos. +- Costos predecibles en sesiones prolongadas (el resumen reemplaza cientos de mensajes). + +**Limitaciones** +- Riesgo de “resumen sesgado” si el modelo omite detalles críticos. +- Incremento de latencia/costos cuando se recalcula el resumen. +- Se debe auditar la salida para evitar “context poisoning”. + +### 5.1 Sugerencias para prompts de resumen + +- Resalta hitos (problema reportado, solución probada, estado actual). +- Integra comprobaciones de contradicciones o políticas antes de resumir. +- Incluye secciones bien delimitadas (`Product & Environment`, `Steps Tried`, `Blockers`, etc.). +- Marca datos dudosos como `UNVERIFIED` para no promover su uso automático. + +## 6. Comparativa rápida + +| Dimensión | TrimmingSession | SummarizingSession | +|-----------|-----------------|--------------------| +| Latencia/costo | Muy bajo | Moderado (dependiendo del resumen) | +| Memoria a largo plazo | Baja | Alta | +| Riesgo principal | Pérdida de contexto | Distorsión del contexto | +| Escenarios ideales | Automatizaciones cortas, tareas independientes | Casos analíticos, coaching, soporte premium | + +## 7. Observabilidad y registros + +- `SummarizingSession.get_full_history()` entrega mensajes y metadatos (`synthetic`, `kind`, `summary_for_turns`) útiles para trazas y dashboards. +- Registra las salidas de los resúmenes para auditar cambios en evaluaciones. +- Al integrar con `agents` SDK, complementa con `set_tracing_disabled(False)` para utilizar los tableros de Traces cuando estén habilitados. + +## 8. Evaluaciones recomendadas + +1. **Baseline vs. Delta**: ejecuta tus suites de regresión antes y después de aplicar la política de contexto. +2. **LLM-as-Judge**: evalúa resúmenes con un prompt que compare contra la conversación original. +3. **Replay de transcripciones**: reproduce threads largos y valida si el agente recuerda IDs, acuerdos o restricciones. +4. **Token Pressure Checks**: monitorea la longitud total enviada al modelo para evitar truncamientos inesperados. + +## 9. Integración por dominio + +- **Backend (`api/`)**: utilice sesiones para pipelines de soporte o diagnósticos de microservicios. +- **Frontend (`ui/`)**: combine resúmenes con análisis de UX para guiar mejoras graduales. +- **Infrastructure**: aplica trimming para runbooks automatizados y summarization en incidentes largos. +- **Docs**: usa resúmenes para consolidar hallazgos antes de archivarlos en `docs/analisis/`. +- **Scripts**: `scripts/coding/ai/orchestrators/codex_mcp_workflow.py` puede recibir una sesión vía composición para mantener el estado cuando delega en múltiples agentes. + +## 10. Recursos relacionados + +- Implementación de referencia: `scripts/coding/ai/shared/context_sessions.py`. +- Pruebas de TDD: `scripts/coding/tests/ai/shared/test_context_sessions.py`. +- ExecPlan que gobierna esta guía: `docs/plans/EXECPLAN_context_memory_management.md`. +- Plantillas de agentes: `.agent/agents/`. +- Prueba de alineación documental: `docs/testing/test_documentation_alignment.py`. diff --git a/docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md b/docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md new file mode 100644 index 00000000..6cea7193 --- /dev/null +++ b/docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md @@ -0,0 +1,219 @@ +# Catálogo Completo de Técnicas de Prompts multi-LLM + +Este catálogo unifica las técnicas de prompting aplicables a los tres proveedores soportados por el proyecto (Claude, ChatGPT y Hugging Face) y funciona como referencia canónica para los agentes descritos en `.agent/agents/` y los planes activos `docs/plans/EXECPLAN_codex_mcp_multi_llm.md` y `docs/plans/EXECPLAN_agents_domain_alignment.md`. Cada sección indica cómo reutilizar la técnica dentro del flujo SDLC y enlaza con los dominios Backend (API), Frontend (UI), Infrastructure, Docs y Scripts cuando existen lineamientos específicos. + +> **Uso operativo:** Los agentes de dominio (ApiAgent, UiAgent, InfrastructureAgent, DocsAgent, ScriptsAgent) y los agentes por proveedor (ClaudeAgent, ChatGPTAgent, HuggingFaceAgent) deben enlazar a este catálogo para seleccionar la estrategia de prompting adecuada antes de invocar los orquestadores (`scripts/coding/ai/orchestrators/codex_mcp_workflow.py`) o los generadores (`scripts/coding/ai/generators/llm_generator.py`). + +## 1. Técnicas de In-Context Learning (ICL) + +### 1.1 Few-Shot Prompting +- **Few-Shot Prompting**: paradigma donde el LLM aprende la tarea con pocos ejemplos. +- **K-Nearest Neighbor (KNN)**: selecciona ejemplos similares al caso actual. +- **Vote-K**: preserva diversidad mientras se eligen ejemplos parecidos. +- **Self-Generated In-Context Learning (SG-ICL)**: genera ejemplos automáticamente. +- **Prompt Mining**: descubre formulaciones intermedias óptimas a partir de corpus. +- **LENS**: aplica filtrado iterativo para refinar ejemplos. +- **UDR**: combina embeddings y recuperación. +- **Active Example Selection**: usa refuerzo para escoger ejemplos. + +### 1.2 Zero-Shot Prompting +- **Role Prompting**: asigna un rol o persona al modelo. +- **Style Prompting**: controla estilo, tono o género del resultado. +- **Emotion Prompting**: incorpora frases con carga emocional. +- **System 2 Attention (S2A)**: elimina información irrelevante del prompt. +- **SimToM**: restringe el conocimiento usado por el modelo. +- **Rephrase and Respond (RaR)**: obliga a reformular y luego responder. +- **Re-reading (RE2)**: añade instrucciones para releer la pregunta. +- **Self-Ask**: decide si es necesario pedir información adicional. + +## 2. Técnicas de Generación de Pensamientos + +### 2.1 Chain-of-Thought (CoT) +- **Chain-of-Thought Prompting**: fomenta la explicitación del razonamiento paso a paso. + +### 2.2 Zero-Shot CoT +- **Zero-Shot Chain-of-Thought**: CoT sin ejemplos. +- **Step-Back Prompting**: primero formula una pregunta de alto nivel. +- **Analogical Prompting**: genera ejemplos análogos con cadenas de pensamiento. +- **Thread-of-Thought (ThoT)**: mejora el inductor de pensamiento para CoT. +- **Tabular Chain-of-Thought (Tab-CoT)**: representa razonamiento en tablas Markdown. + +### 2.3 Few-Shot CoT +- **Contrastive CoT Prompting**: combina explicaciones correctas e incorrectas. +- **Uncertainty-Routed CoT**: muestrea múltiples rutas de razonamiento. +- **Complexity-based Prompting**: usa ejemplos complejos como entrenamiento. +- **Active Prompting**: solicita a humanos reescribir ejemplos inciertos. +- **Memory-of-Thought**: reutiliza datos no etiquetados. +- **Automatic Chain-of-Thought (Auto-CoT)**: genera cadenas de pensamiento automáticamente. + +## 3. Técnicas de Descomposición + +- **Least-to-Most Prompting**: divide un problema en subproblemas. +- **Decomposed Prompting (DECOMP)**: muestra cómo usar funciones específicas. +- **Plan-and-Solve Prompting**: versión mejorada de Zero-Shot CoT. +- **Tree-of-Thought (ToT)**: explora soluciones como un árbol. +- **Recursion-of-Thought**: delega subproblemas complejos a otros prompts. +- **Program-of-Thoughts**: traduce el problema a código ejecutable. +- **Faithful Chain-of-Thought**: mezcla razonamiento natural con símbolos. +- **Skeleton-of-Thought**: acelera mediante paralelización. +- **Metacognitive Prompting**: simula procesos metacognitivos humanos. + +## 4. Técnicas de Ensembling + +- **Demonstration Ensembling (DENSE)**: crea múltiples prompts few-shot. +- **Mixture of Reasoning Experts (MoRE)**: agrupa expertos de razonamiento diversos. +- **Max Mutual Information Method**: combina plantillas y ejemplos variados. +- **Self-Consistency**: genera varias rutas y escoge la respuesta coherente. +- **Universal Self-Consistency**: usa prompting para elegir la respuesta mayoritaria. +- **Meta-Reasoning over Multiple CoTs**: agrega múltiples cadenas de razonamiento. +- **DiVeRSe**: produce varios prompts para el mismo problema. +- **Consistency-based Self-adaptive Prompting (COSP)**: genera prompts Few-Shot CoT. +- **Universal Self-Adaptive Prompting (USP)**: generaliza COSP. +- **Prompt Paraphrasing**: reescribe el prompt original para variar formulaciones. + +## 5. Técnicas de Auto-Crítica + +- **Self-Calibration**: pregunta al modelo si su respuesta es correcta. +- **Self-Refine**: itera respuesta y retroalimentación. +- **Reversing Chain-of-Thought (RCoT)**: reconstruye el problema desde la respuesta. +- **Self-Verification**: genera múltiples soluciones candidatas. +- **Chain-of-Verification (COVE)**: crea preguntas de verificación. +- **Cumulative Reasoning**: acumula pasos potenciales antes de resolver. + +## 6. Técnicas Multilingües + +### 6.1 Prompting General Multilingüe +- **Translate First Prompting**: traduce primero al inglés. + +### 6.2 Chain-of-Thought Multilingüe +- **XLT (Cross-Lingual Thought) Prompting**: seis instrucciones coordinadas. +- **Cross-Lingual Self Consistent Prompting (CLSP)**: ensemble multilingüe. + +### 6.3 In-Context Learning Multilingüe +- **X-InSTA Prompting**: alinea ejemplos en contexto. +- **In-CLT (Cross-lingual Transfer) Prompting**: usa idioma fuente y destino. + +### 6.4 Selección de Ejemplos en Contexto +- **PARC**: recupera ejemplos desde un idioma de alto recurso. +- **Semantically-Aligned Examples**: elige ejemplos cercanos semánticamente. +- **Semantically-Distant Examples**: usa ejemplos disímiles para robustez. + +### 6.5 Traducción Automática +- **Multi-Aspect Prompting and Selection (MAPS)**: imita traducción humana. +- **Chain-of-Dictionary (CoD)**: lista significados de palabras clave. +- **Dictionary-based Prompting for MT (DiPMT)**: enfoque basado en diccionarios. +- **Decomposed Prompting for MT (DecoMT)**: divide el texto en fragmentos. +- **Interactive-Chain-Prompting (ICP)**: maneja ambigüedades mediante diálogo. +- **Iterative Prompting**: involucra humanos durante la traducción. + +## 7. Técnicas Multimodales + +### 7.1 Prompting de Imágenes +- **Prompt Modifiers**: modificadores que alteran la imagen generada. +- **Negative Prompting**: pondera términos a evitar. +- **Paired-Image Prompting**: compara imágenes antes/después. +- **Image-as-Text Prompting**: describe una imagen como texto. +- **Duty Distinct Chain-of-Thought (DDCoT)**: extiende Least-to-Most a entornos multimodales. +- **Multimodal Graph-of-Thought**: extiende Graph-of-Thought. +- **Chain-of-Images (CoI)**: cadena de pensamiento en imágenes. + +### 7.2 Otras Modalidades +- **Audio Prompting**: técnicas aplicadas a audio. +- **Video Prompting**: prompting para video. +- **Segmentation Prompting**: segmentación guiada por prompt. +- **3D Prompting**: prompting para entornos tridimensionales. + +## 8. Técnicas de Agentes + +### 8.1 Agentes de Uso de Herramientas +- **MRKL System**: integración modular de razonamiento y herramientas. +- **Self-Correcting with Tool-Interactive Critiquing (CRITIC)**: usa herramientas para auto-corregirse. + +### 8.2 Agentes de Generación de Código +- **Program-aided Language Model (PAL)**: traduce a código. +- **Tool-Integrated Reasoning Agent (ToRA)**: alterna razonamiento y código. +- **TaskWeaver**: usa plugins definidos por el usuario. + +### 8.3 Agentes Basados en Observación +- **Reasoning and Acting (ReAct)**: combina pensamiento, acción y observación. +- **Reflexion**: añade introspección al patrón ReAct. +- **Voyager**: aprendizaje continuo con tres componentes. +- **Ghost in the Minecraft (GITM)**: descompone objetivos en subobjetivos. + +### 8.4 Generación Aumentada por Recuperación (RAG) +- **Verify-and-Edit**: mejora la consistencia generando múltiples CoTs. +- **Demonstrate-Search-Predict**: descompone en subpreguntas. +- **Interleaved Retrieval guided by Chain-of-Thought (IRCoT)**: recupera información en múltiples pasos. +- **Iterative Retrieval Augmentation**: realiza recuperación iterativa. + +## 9. Técnicas de Evaluación + +### 9.1 Prompting para Evaluación +- **In-Context Learning para Evaluación**: usa ejemplos para evaluar. +- **Role-based Evaluation**: roles distintos para ampliar cobertura. +- **Chain-of-Thought para Evaluación**: mejora la calidad evaluativa. +- **Model-Generated Guidelines**: el modelo genera pautas de evaluación. + +### 9.2 Formatos de Salida +- **Binary Score**: respuesta binaria. +- **Linear Scale**: escala lineal simple. +- **Likert Scale**: escala Likert. +- **Styling**: salidas formateadas (XML, JSON, etc.). + +### 9.3 Marcos de Prompting +- **LLM-EVAL**: marco básico de evaluación. +- **G-EVAL**: incorpora Auto-CoT en la evaluación. +- **ChatEval**: usa debate multi-agente. + +### 9.4 Otras Metodologías +- **Batch Prompting**: evalúa múltiples instancias a la vez. +- **Pairwise Evaluation**: compara dos respuestas directamente. + +## 10. Técnicas de Ingeniería de Prompts + +- **Meta Prompting**: el modelo mejora el prompt. +- **AutoPrompt**: usa tokens disparadores en un LLM congelado. +- **Automatic Prompt Engineer (APE)**: genera prompts zero-shot. +- **Gradientfree Instructional Prompt Search (GrIPS)**: busca prompts sin gradientes. +- **Prompt Optimization with Textual Gradients (ProTeGi)**: optimiza con gradientes textuales. +- **RLPrompt**: agrega un módulo de refuerzo. +- **Dialogue-comprised Policy-gradient-based Discrete Prompt Optimization (DP2O)**: optimización avanzada basada en diálogos. + +## 11. Ingeniería de Respuestas + +### 11.1 Componentes +- **Answer Shape**: formato de la respuesta. +- **Answer Space**: dominio de valores permitidos. +- **Answer Extractor**: regla para extraer la respuesta final. + +### 11.2 Técnicas +- **Verbalizer**: asigna tokens a etiquetas. +- **Regex**: usa expresiones regulares para extraer respuestas. +- **Separate LLM**: un modelo evalúa la salida de otro. + +## 12. Técnicas Especializadas por Dominio + +### 12.1 Seguridad +- **Prompt-based Defenses**: instrucciones defensivas explícitas. +- **Detectors**: detectores de entradas maliciosas. +- **Guardrails**: reglas para guiar la salida. + +### 12.2 Alineación +- **Vanilla Prompting**: instrucción imparcial. +- **Selecting Balanced Demonstrations**: equilibra ejemplos según métricas de equidad. +- **Cultural Awareness**: adapta culturalmente las respuestas. +- **AttrPrompt**: reduce sesgos en texto generado. +- **Ambiguous Demonstrations**: usa ejemplos con etiquetas ambiguas. +- **Question Clarification**: identifica preguntas ambiguas. + +### 12.3 Calibración +- **Verbalized Score**: genera puntuación de confianza. +- **Sycophancy**: considera tendencia a complacer al usuario. + +## Notas Importantes + +- Las técnicas pueden combinarse para mejorar resultados. +- La efectividad depende del modelo (Claude, ChatGPT, Hugging Face), la tarea y el contexto. +- Algunas técnicas requieren ajustes específicos por dominio (API, UI, Infrastructure, Docs, Scripts). +- La investigación evoluciona rápidamente; validar empíricamente antes de estandarizar. +- Registrar hallazgos y variantes en `docs/ai/SDLC_AGENTS_GUIDE.md` cuando se descubran nuevas combinaciones. diff --git a/docs/ai_capabilities/prompting/README.md b/docs/ai_capabilities/prompting/README.md index bce4b706..cb1fad4c 100644 --- a/docs/ai_capabilities/prompting/README.md +++ b/docs/ai_capabilities/prompting/README.md @@ -22,6 +22,12 @@ Estas técnicas son **generales y transversales**, no específicas a un módulo --- +### Prompt Techniques Catalog (multi-LLM) + +Para una cobertura exhaustiva de técnicas aplicables a Claude, ChatGPT y Hugging Face, consulta el [PROMPT_TECHNIQUES_CATALOG.md](./PROMPT_TECHNIQUES_CATALOG.md). Este catálogo enlaza directamente con los agentes por proveedor y con los agentes de dominio descritos en `.agent/agents/`, asegurando que Backend (API), Frontend (UI), Infrastructure, Docs y Scripts trabajen con el mismo inventario de estrategias. + +--- + ## Implemented Techniques (38 Total) ### Core Techniques (32) @@ -62,6 +68,10 @@ El compendio de patrones agenticos observados en producción—desde LLMs aument Para estandarizar la orquestación Codex MCP en todos los proveedores soportados, consulta [../orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md](../orchestration/CODEX_MCP_MULTI_AGENT_GUIDE.md). Describe cómo inicializar el servidor MCP, ensamblar flujos single-agent y multi-agent, habilitar trazas y enlazar el `CodexMCPWorkflowBuilder` con la gobernanza `.agent`. +### Context Management Playbook + +El manejo de memoria en sesiones largas se detalla en [../orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md](../orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md). Explica cómo aplicar `TrimmingSession` y `SummarizingSession` en Claude, ChatGPT y Hugging Face reutilizando `scripts/coding/ai/shared/context_sessions.py`. + ### Phi-3 Prompt Engineering Playbook Para alinear el tercer proveedor soportado (Hugging Face) con prácticas de prompting reproducibles, consulta [PHI3_PROMPT_ENGINEERING_PLAYBOOK.md](./PHI3_PROMPT_ENGINEERING_PLAYBOOK.md). Resume la configuración del modelo `microsoft/Phi-3-mini-4k-instruct`, patrones como Chain-of-Thought/Tree-of-Thought y recomendaciones para interoperar con Claude y ChatGPT. diff --git a/docs/index.md b/docs/index.md index 12b4e34a..7c3eb58a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -84,6 +84,7 @@ Este índice combina lo implementado con la visión futura del proyecto, clarame - **Test runner**: [`scripts/run_all_tests.sh`](../scripts/run_all_tests.sh) - **Métricas DORA**: [`scripts/dora_metrics.py`](../scripts/dora_metrics.py) - **Templates**: [`scripts/templates/`](../scripts/templates/) +- **Gestión de contexto multi-LLM**: [`ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`](ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md) y módulo reutilizable [`scripts/coding/ai/shared/context_sessions.py`](../scripts/coding/ai/shared/context_sessions.py). #### [PLANIFICADO] Planificados (ver [`docs/scripts/README.md`](scripts/README.md)) - `scripts/sdlc_agent.py` - CLI SDLC diff --git a/docs/plans/EXECPLAN_context_memory_management.md b/docs/plans/EXECPLAN_context_memory_management.md new file mode 100644 index 00000000..b801f253 --- /dev/null +++ b/docs/plans/EXECPLAN_context_memory_management.md @@ -0,0 +1,73 @@ +# Integrar gestión de contexto multi-LLM en agentes y documentación + +Este ExecPlan es un documento vivo. Las secciones `Progress`, `Surprises & Discoveries`, `Decision Log` y `Outcomes & Retrospective` deben mantenerse al día conforme avance el trabajo. + +Este documento se mantiene según `.agent/PLANS.md` y gobierna las integraciones de memoria de contexto para todos los modelos LLM en el repositorio. + +## Purpose / Big Picture + +Permitir que cualquier agente basado en Claude, ChatGPT u otros LLMs ejecute flujos prolongados sin perder coherencia ni desperdiciar tokens, incorporando sesiones con recorte y resumen de contexto dentro de los scripts y documentando el procedimiento oficial en la guía de capacidades. Al finalizar, los equipos podrán reutilizar la misma política de memoria desde scripts Python probados y seguir un manual unificado dentro de `docs/`. + +## Progress + +- [x] (2025-11-13 06:54Z) Redactar especificaciones de sesiones de contexto (trimming y summarizing) con API pública en `scripts/coding/ai/shared/`. +- [x] (2025-11-13 06:54Z) Implementar pruebas TDD en `scripts/coding/tests/ai/` que cubran recorte de turnos, resúmenes sintéticos y metadata. +- [x] (2025-11-13 06:54Z) Implementar módulos de sesiones y asegurarse de que las pruebas pasen. +- [x] (2025-11-13 06:57Z) Documentar el cookbook de gestión de contexto en `docs/ai_capabilities/orchestration/` y enlazarlo desde los índices y fichas de agentes. +- [x] (2025-11-13 06:57Z) Actualizar catálogos/README/SDLC para reflejar disponibilidad de la nueva política de contexto. +- [x] (2025-11-13 06:57Z) Ejecutar pytest relevante y actualizar esta sección con el resultado. + +## Surprises & Discoveries + +- Pending. + +## Decision Log + +- Pending. + +## Outcomes & Retrospective + +- Pending. + +## Context and Orientation + +El proyecto separa responsabilidades en `api/`, `ui/`, `infrastructure/`, `docs/` y `scripts/`. Las automatizaciones de agentes viven en `scripts/coding/ai/` y las guías en `docs/ai_capabilities/`. Actualmente no existe un módulo centralizado que maneje trimming/summarizing con sesiones compatibles con el Agents SDK; el usuario entregó un cookbook detallado que debemos adaptar a nuestras convenciones, manteniendo compatibilidad multi-LLM y con la política de ExecPlans. + +## Plan of Work + +1. Revisar los lineamientos del cookbook y diseñar la API Python que expondrá clases `TrimmingSession` y `SummarizingSession` bajo `scripts/coding/ai/shared/context_sessions.py`, incluyendo opciones de turnos y resúmenes. +2. Definir antes del código los casos de prueba unitarios que cubran recorte de turnos, preservación de metadatos y reemplazo por resúmenes, ubicándolos en `scripts/coding/tests/ai/shared/test_context_sessions.py`. +3. Implementar las clases siguiendo TDD, asegurando que se integren con `agents` SDK de OpenAI (sin dependencia directa cuando no esté instalado) mediante abstracciones claras. +4. Documentar el flujo completo en un nuevo manual `docs/ai_capabilities/orchestration/CONTEXT_MANAGEMENT_PLAYBOOK.md`, incorporando trimming y summarization para todos los modelos, con requisitos previos, comparativas y tablas. +5. Actualizar índices (`docs/ai_capabilities/orchestration/README.md`, `docs/ai_capabilities/prompting/README.md` si aplica) y fichas de agentes multi-LLM en `.agent/agents/` para enlazar el playbook. +6. Ajustar pruebas de alineación documental en `docs/testing/test_documentation_alignment.py` para exigir referencias cruzadas al nuevo playbook. +7. Ejecutar la batería de pruebas relevante (`pytest scripts/coding/tests/ai/shared/test_context_sessions.py` y `pytest docs/testing/test_documentation_alignment.py`) y registrar resultados. + +## Concrete Steps + +1. Crear archivo de pruebas unitarias con los escenarios TDD descritos. +2. Implementar módulo `context_sessions.py` con clases y helpers necesarios hasta que las pruebas pasen. +3. Redactar el playbook en `docs/ai_capabilities/orchestration/` utilizando el contenido proporcionado por el usuario, adaptado a nuestras convenciones (sin emojis, con secciones claras y referencias multi-LLM). +4. Enlazar el nuevo playbook desde los índices, README y fichas, además de actualizar la prueba de alineación documental. +5. Ejecutar `pytest` para las rutas afectadas. + +## Validation and Acceptance + +- `pytest scripts/coding/tests/ai/shared/test_context_sessions.py` debe pasar al final. +- `pytest docs/testing/test_documentation_alignment.py` debe pasar y validar los nuevos enlaces. +- El README y las fichas de agentes deben mencionar explícitamente la política de contexto multi-LLM. +- El playbook debe describir trimming y summarization, incluir pros/contras y comparativas, y proveer instrucciones reproducibles. + +## Idempotence and Recovery + +- Las pruebas unitarias pueden ejecutarse repetidamente sin modificar el entorno. +- El playbook y los enlaces son aditivos; en caso de error, revertir commits parciales y volver a correr `pytest`. + +## Artifacts and Notes + +- Pending. + +## Interfaces and Dependencies + +- El módulo `context_sessions` expondrá clases `TrimmingSession` y `SummarizingSession` con métodos `get_items`, `add_items`, `pop_item`, `clear_session`, `get_full_history` y configuraciones `max_turns`, `keep_last_n_turns`. +- Las pruebas importarán desde `scripts.coding.ai.shared.context_sessions` y simularán mensajes en formato dict compatible con Agents SDK (`{"role": "user", "content": "..."}` y metadatos opcionales). diff --git a/docs/plans/EXECPLAN_prompt_techniques_catalog.md b/docs/plans/EXECPLAN_prompt_techniques_catalog.md new file mode 100644 index 00000000..3c44ce7b --- /dev/null +++ b/docs/plans/EXECPLAN_prompt_techniques_catalog.md @@ -0,0 +1,70 @@ +# Integrar catálogo completo de técnicas de prompts multi-LLM + +Este ExecPlan es un documento vivo. Las secciones `Progress`, `Surprises & Discoveries`, `Decision Log` y `Outcomes & Retrospective` deben mantenerse al día conforme avance el trabajo. + +Si el archivo PLANS.md está en el repositorio, referencia su ruta: `.agent/PLANS.md`. Este documento debe mantenerse en conformidad con dicha guía. + +## Purpose / Big Picture + +Unificar el catálogo completo de técnicas de prompting para que los equipos de Backend (API), Frontend (UI), Infrastructure, Docs y Scripts dispongan de una referencia homogénea aplicable a Claude, ChatGPT y Hugging Face. Tras la implementación, cualquier colaborador podrá ubicar las técnicas según el flujo SDLC y vincularlas con los agentes y orquestadores multi-LLM existentes. + +## Progress + +- [x] (2025-02-14 12:00Z) Redactar prueba de alineación documental que asegure la existencia y el enlace del nuevo catálogo. +- [x] (2025-02-14 12:05Z) Incorporar el catálogo completo de técnicas en `docs/ai_capabilities/prompting/` con referencias cruzadas hacia los agentes por proveedor y dominios. +- [x] (2025-02-14 12:06Z) Actualizar README y guías de agentes para reflejar la nueva fuente canónica. +- [x] (2025-02-14 12:07Z) Ejecutar la batería de pruebas (`pytest docs/testing/test_documentation_alignment.py`). + +## Surprises & Discoveries + +- No se identificaron descubrimientos imprevistos; la estructura existente de agentes ya contemplaba puntos de enlace. + +## Decision Log + +- Decision: Centralizar el catálogo en `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` y referenciarlo desde todas las fichas de agentes y guías SDLC. + Rationale: Evitar duplicación de técnicas y asegurar consistencia multi-LLM para los dominios Backend/UI/Infrastructure/Docs/Scripts. + Date/Author: 2025-02-14 / Automatización. + +## Outcomes & Retrospective + +- Catálogo multi-LLM publicado y enlazado desde README, prompting index, agentes por proveedor y por dominio. +- Las pruebas de alineación documental fueron extendidas para proteger la presencia del catálogo y pasaron exitosamente (`pytest docs/testing/test_documentation_alignment.py`). + +## Context and Orientation + +El repositorio ya contiene guías de prompting específicas (`CODE_GENERATION_GUIDE.md`, `PHI3_PROMPT_ENGINEERING_PLAYBOOK.md`, etc.) y catálogos de agentes en `.agent/agents/`. La política exige que nuevas piezas documentales se integren con los agentes de dominio (ApiAgent, UiAgent, etc.) y con los agentes por proveedor (Claude, ChatGPT, Hugging Face). Las pruebas automáticas de documentación residen en `docs/testing/test_documentation_alignment.py` y deben extenderse para incluir cualquier documento nuevo. + +## Plan of Work + +1. Extender `docs/testing/test_documentation_alignment.py` para exigir la presencia del catálogo de técnicas de prompting y sus enlaces desde el índice de prompting y desde los agentes pertinentes. +2. Crear `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` incorporando el contenido proporcionado, organizándolo para todos los modelos LLM y añadiendo referencias cruzadas hacia ExecPlans y agentes relevantes. +3. Actualizar `docs/ai_capabilities/prompting/README.md`, `.agent/agents/README.md`, y las fichas de agentes por proveedor para enlazar el nuevo catálogo. +4. Revisar `docs/ai/SDLC_AGENTS_GUIDE.md` y cualquier guía de dominio que requiera citar el catálogo, asegurando consistencia con el mapeo Backend/UI/Infrastructure/Docs/Scripts. +5. Ejecutar pruebas (`pytest docs/testing/test_documentation_alignment.py`) y documentar resultados. + +## Concrete Steps + +- Trabajar desde la raíz del repositorio (`/workspace/IACT---project`). +- Ejecutar `pytest docs/testing/test_documentation_alignment.py` tras implementar los cambios. +- Si es necesario validar cobertura adicional, reutilizar suites existentes bajo `scripts/coding/tests/`. + +## Validation and Acceptance + +- `pytest docs/testing/test_documentation_alignment.py` debe pasar y confirmar que el catálogo está enlazado correctamente. +- Los README y fichas de agentes deben contener referencias explícitas al catálogo. +- La documentación debe mencionar que el catálogo es aplicable a Claude, ChatGPT y Hugging Face. + +## Idempotence and Recovery + +- Las modificaciones son aditivas. Si una prueba falla por enlaces rotos, corregir los paths y reejecutar la suite. +- Para revertir, restaurar los archivos modificados con `git checkout -- `. + +## Artifacts and Notes + +- Se adjuntarán fragmentos relevantes de pruebas exitosas en la sección de resultados. + +## Interfaces and Dependencies + +- Documentación principal: `docs/ai_capabilities/prompting/PROMPT_TECHNIQUES_CATALOG.md` (nuevo). +- Índices y catálogos: `.agent/agents/README.md`, `docs/ai_capabilities/prompting/README.md`, `docs/ai/SDLC_AGENTS_GUIDE.md`. +- Validadores: `docs/testing/test_documentation_alignment.py`. diff --git a/docs/testing/test_documentation_alignment.py b/docs/testing/test_documentation_alignment.py index 1997dd85..d3ca4d85 100644 --- a/docs/testing/test_documentation_alignment.py +++ b/docs/testing/test_documentation_alignment.py @@ -217,3 +217,80 @@ def test_domain_agents_are_documented_and_linked(): assert label in root_readme assert label in sdlc_guide + +def test_prompt_techniques_catalog_is_linked_across_agents(): + catalog_path = REPO_ROOT / "docs" / "ai_capabilities" / "prompting" / "PROMPT_TECHNIQUES_CATALOG.md" + assert catalog_path.exists(), "Falta el catálogo de técnicas de prompting" + + catalog_contents = _read(catalog_path) + assert "Catálogo Completo de Técnicas de Prompts" in catalog_contents + + prompting_index = _read(REPO_ROOT / "docs" / "ai_capabilities" / "prompting" / "README.md") + assert "PROMPT_TECHNIQUES_CATALOG.md" in prompting_index + + root_readme = _read(REPO_ROOT / "README.md") + assert "PROMPT_TECHNIQUES_CATALOG.md" in root_readme + + agent_catalog = _read(REPO_ROOT / ".agent" / "agents" / "README.md") + assert "PROMPT_TECHNIQUES_CATALOG.md" in agent_catalog + + provider_agents = [ + "claude_agent.md", + "chatgpt_agent.md", + "huggingface_agent.md", + ] + + domain_agents = [ + "api_agent.md", + "ui_agent.md", + "infrastructure_agent.md", + "docs_agent.md", + "scripts_agent.md", + ] + + agents_dir = REPO_ROOT / ".agent" / "agents" + + for filename in provider_agents + domain_agents: + contents = _read(agents_dir / filename) + assert "PROMPT_TECHNIQUES_CATALOG.md" in contents + + sdlc_guide = _read(REPO_ROOT / "docs" / "ai" / "SDLC_AGENTS_GUIDE.md") + assert "PROMPT_TECHNIQUES_CATALOG.md" in sdlc_guide + + +def test_context_management_playbook_is_linked_across_guides(): + playbook_path = REPO_ROOT / "docs" / "ai_capabilities" / "orchestration" / "CONTEXT_MANAGEMENT_PLAYBOOK.md" + assert playbook_path.exists(), "Debe existir el playbook de gestión de contexto" + + playbook_contents = _read(playbook_path) + assert "Context Management Playbook" in playbook_contents + assert "TrimmingSession" in playbook_contents + assert "SummarizingSession" in playbook_contents + + context_module = REPO_ROOT / "scripts" / "coding" / "ai" / "shared" / "context_sessions.py" + assert context_module.exists(), "Falta el módulo reutilizable de sesiones de contexto" + + readme_root = _read(REPO_ROOT / "README.md") + assert "CONTEXT_MANAGEMENT_PLAYBOOK" in readme_root + + docs_index = _read(REPO_ROOT / "docs" / "index.md") + assert "CONTEXT_MANAGEMENT_PLAYBOOK" in docs_index + + prompting_index = _read(REPO_ROOT / "docs" / "ai_capabilities" / "prompting" / "README.md") + assert "Context Management Playbook" in prompting_index + + agent_catalog = _read(REPO_ROOT / ".agent" / "agents" / "README.md") + assert "CONTEXT_MANAGEMENT_PLAYBOOK" in agent_catalog + + agents_dir = REPO_ROOT / ".agent" / "agents" + provider_agents = ["claude_agent.md", "chatgpt_agent.md", "huggingface_agent.md"] + domain_agents = ["api_agent.md", "ui_agent.md", "infrastructure_agent.md", "docs_agent.md", "scripts_agent.md"] + + for filename in provider_agents + domain_agents: + contents = _read(agents_dir / filename) + assert "CONTEXT_MANAGEMENT_PLAYBOOK" in contents + assert "context_sessions.py" in contents + + sdlc_guide = _read(REPO_ROOT / "docs" / "ai" / "SDLC_AGENTS_GUIDE.md") + assert "CONTEXT_MANAGEMENT_PLAYBOOK" in sdlc_guide + assert "context_sessions.py" in sdlc_guide diff --git a/scripts/coding/ai/shared/context_sessions.py b/scripts/coding/ai/shared/context_sessions.py new file mode 100644 index 00000000..e7d6a268 --- /dev/null +++ b/scripts/coding/ai/shared/context_sessions.py @@ -0,0 +1,270 @@ +"""Context session utilities for multi-LLM agents.""" + +from __future__ import annotations + +import asyncio +from collections import deque +from typing import Any, Deque, Dict, Iterable, List, Optional, Tuple + +ROLE_USER = "user" +ALLOWED_MSG_KEYS = {"role", "content", "name"} + + +def _is_user_msg(item: Dict[str, Any]) -> bool: + """Return ``True`` if the payload represents a user authored message.""" + if not isinstance(item, dict): + role = getattr(item, "role", None) + return role == ROLE_USER + + role = item.get("role") + if role is not None: + return role == ROLE_USER + + if item.get("type") == "message": + return item.get("role") == ROLE_USER + + return False + + +class TrimmingSession: + """Maintain only the last ``max_turns`` user turns in memory.""" + + def __init__(self, session_id: str, max_turns: int = 8): + self.session_id = session_id + self.max_turns = max(1, int(max_turns)) + self._items: Deque[Dict[str, Any]] = deque() + self._lock = asyncio.Lock() + + async def get_items(self, limit: Optional[int] = None) -> List[Dict[str, Any]]: + async with self._lock: + trimmed = self._trim_to_last_turns(list(self._items)) + if limit is not None and limit >= 0: + return trimmed[-limit:] + return trimmed + + async def add_items(self, items: Iterable[Dict[str, Any]]) -> None: + payload = list(items) + if not payload: + return + async with self._lock: + self._items.extend(payload) + trimmed = self._trim_to_last_turns(list(self._items)) + self._items.clear() + self._items.extend(trimmed) + + async def pop_item(self) -> Optional[Dict[str, Any]]: + async with self._lock: + if not self._items: + return None + return self._items.pop() + + async def clear_session(self) -> None: + async with self._lock: + self._items.clear() + + async def set_max_turns(self, max_turns: int) -> None: + async with self._lock: + self.max_turns = max(1, int(max_turns)) + trimmed = self._trim_to_last_turns(list(self._items)) + self._items.clear() + self._items.extend(trimmed) + + async def raw_items(self) -> List[Dict[str, Any]]: + async with self._lock: + return list(self._items) + + def _trim_to_last_turns(self, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + if not items: + return items + + count = 0 + start_idx = 0 + for index in range(len(items) - 1, -1, -1): + if _is_user_msg(items[index]): + count += 1 + if count == self.max_turns: + start_idx = index + break + + return items[start_idx:] + + +class SummarizingSession: + """Session that summarizes older turns once the context limit is exceeded.""" + + def __init__( + self, + keep_last_n_turns: int = 3, + context_limit: int = 3, + summarizer: Optional[Any] = None, + session_id: Optional[str] = None, + ): + if context_limit < 1: + raise ValueError("context_limit must be >= 1") + if keep_last_n_turns < 0: + raise ValueError("keep_last_n_turns must be >= 0") + if keep_last_n_turns > context_limit: + raise ValueError("keep_last_n_turns cannot exceed context_limit") + + self.keep_last_n_turns = keep_last_n_turns + self.context_limit = context_limit + self.summarizer = summarizer + self.session_id = session_id or "default" + + self._records: Deque[Dict[str, Dict[str, Any]]] = deque() + self._lock = asyncio.Lock() + + async def get_items(self, limit: Optional[int] = None) -> List[Dict[str, Any]]: + async with self._lock: + data = [dict(record["msg"]) for record in self._records] + return self._apply_limit([self._sanitize_for_model(msg) for msg in data], limit) + + async def add_items(self, items: Iterable[Dict[str, Any]]) -> None: + payload = list(items) + if not payload: + return + + async with self._lock: + for item in payload: + msg, metadata = self._split_msg_and_meta(item) + self._records.append({"msg": msg, "metadata": metadata}) + need_summary, boundary = self._summarize_decision_locked() + + if not need_summary: + async with self._lock: + self._normalize_synthetic_flags_locked() + return + + async with self._lock: + snapshot = list(self._records) + prefix_msgs = [record["msg"] for record in snapshot[:boundary]] + + shadow, summary = await self._summarize(prefix_msgs) + + async with self._lock: + still_need, new_boundary = self._summarize_decision_locked() + if not still_need: + self._normalize_synthetic_flags_locked() + return + + snapshot = list(self._records) + suffix = snapshot[new_boundary:] + + self._records.clear() + self._records.extend( + [ + { + "msg": {"role": ROLE_USER, "content": shadow}, + "metadata": { + "synthetic": True, + "kind": "history_summary_prompt", + "summary_for_turns": f"< all before idx {new_boundary} >", + }, + }, + { + "msg": {"role": "assistant", "content": summary}, + "metadata": { + "synthetic": True, + "kind": "history_summary", + "summary_for_turns": f"< all before idx {new_boundary} >", + }, + }, + ] + ) + self._records.extend(suffix) + self._normalize_synthetic_flags_locked() + + async def pop_item(self) -> Optional[Dict[str, Any]]: + async with self._lock: + if not self._records: + return None + record = self._records.pop() + return dict(record["msg"]) + + async def clear_session(self) -> None: + async with self._lock: + self._records.clear() + + def set_max_turns(self, n: int) -> None: + if n < 1: + raise ValueError("n must be >= 1") + self.context_limit = n + if self.keep_last_n_turns > self.context_limit: + self.keep_last_n_turns = self.context_limit + + async def get_full_history(self, limit: Optional[int] = None) -> List[Dict[str, Any]]: + async with self._lock: + data = [ + {"message": dict(record["msg"]), "metadata": dict(record["metadata"])} + for record in self._records + ] + return self._apply_limit(data, limit) + + async def get_items_with_metadata(self, limit: Optional[int] = None) -> List[Dict[str, Any]]: + return await self.get_full_history(limit) + + def _apply_limit(self, items: List[Dict[str, Any]], limit: Optional[int]) -> List[Dict[str, Any]]: + if limit is not None and limit >= 0: + return items[-limit:] + return items + + def _split_msg_and_meta(self, item: Dict[str, Any]) -> Tuple[Dict[str, Any], Dict[str, Any]]: + msg = {k: item.get(k) for k in ALLOWED_MSG_KEYS if k in item} + extra = {k: v for k, v in item.items() if k not in ALLOWED_MSG_KEYS} + metadata = dict(extra.pop("metadata", {})) + metadata.update(extra) + + msg.setdefault("role", ROLE_USER) + msg.setdefault("content", str(item)) + + role = msg.get("role") + if role in (ROLE_USER, "assistant") and "synthetic" not in metadata: + metadata["synthetic"] = False + return msg, metadata + + def _sanitize_for_model(self, msg: Dict[str, Any]) -> Dict[str, Any]: + return {k: v for k, v in msg.items() if k in ALLOWED_MSG_KEYS} + + def _is_real_user_turn_start(self, record: Dict[str, Dict[str, Any]]) -> bool: + return ( + record["msg"].get("role") == ROLE_USER + and not record["metadata"].get("synthetic", False) + ) + + def _summarize_decision_locked(self) -> Tuple[bool, int]: + user_starts = [i for i, rec in enumerate(self._records) if self._is_real_user_turn_start(rec)] + real_turns = len(user_starts) + + if real_turns <= self.context_limit: + return False, -1 + + if self.keep_last_n_turns == 0: + return True, len(self._records) + + if len(user_starts) < self.keep_last_n_turns: + return False, -1 + + boundary = user_starts[-self.keep_last_n_turns] + if boundary <= 0: + return False, -1 + + return True, boundary + + def _normalize_synthetic_flags_locked(self) -> None: + for record in self._records: + role = record["msg"].get("role") + if role in (ROLE_USER, "assistant") and "synthetic" not in record["metadata"]: + record["metadata"]["synthetic"] = False + + async def _summarize(self, prefix_msgs: List[Dict[str, Any]]) -> Tuple[str, str]: + if not self.summarizer: + return "Summarize the conversation we had so far.", "Summary unavailable." + + clean_prefix = [self._sanitize_for_model(msg) for msg in prefix_msgs] + result = await self.summarizer.summarize(clean_prefix) + if not isinstance(result, tuple) or len(result) != 2: + return "Summarize the conversation we had so far.", str(result) + return result + + +__all__ = ["TrimmingSession", "SummarizingSession"] diff --git a/scripts/coding/tests/ai/shared/test_context_sessions.py b/scripts/coding/tests/ai/shared/test_context_sessions.py new file mode 100644 index 00000000..fb12aaa6 --- /dev/null +++ b/scripts/coding/tests/ai/shared/test_context_sessions.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +"""Tests for context session utilities (TDD).""" + +import asyncio +import sys +from pathlib import Path +from types import ModuleType +import importlib.machinery +import importlib.util + +PROJECT_ROOT = Path(__file__).parent.parent.parent.parent.parent.parent +SCRIPTS_ROOT = PROJECT_ROOT / "scripts" +CODING_ROOT = SCRIPTS_ROOT / "coding" + +# Ensure namespace resolution for "scripts" package used across tests +if str(PROJECT_ROOT) not in sys.path: + sys.path.insert(0, str(PROJECT_ROOT)) +if str(CODING_ROOT) not in sys.path: + sys.path.insert(0, str(CODING_ROOT)) + +namespace_paths = [str(SCRIPTS_ROOT), str(CODING_ROOT)] +scripts_pkg = ModuleType("scripts") +scripts_pkg.__package__ = "scripts" +scripts_pkg.__path__ = namespace_paths +scripts_pkg.__spec__ = importlib.machinery.ModuleSpec( + name="scripts", + loader=None, + is_package=True, +) +sys.modules.setdefault("scripts", scripts_pkg) + +MODULE_NAME = "scripts.ai.shared.context_sessions" +module_spec = importlib.util.find_spec(MODULE_NAME) +if module_spec is None: + module_path = CODING_ROOT / "ai" / "shared" / "context_sessions.py" + module_spec = importlib.util.spec_from_file_location(MODULE_NAME, module_path) + module = importlib.util.module_from_spec(module_spec) + assert module_spec and module_spec.loader, "No se pudo cargar spec para context_sessions" + module_spec.loader.exec_module(module) + sys.modules[MODULE_NAME] = module + +from scripts.ai.shared.context_sessions import ( # type: ignore # pylint: disable=wrong-import-position + TrimmingSession, + SummarizingSession, +) + + +def run_async(coro): + """Helper to execute async coroutines within sync pytest tests.""" + return asyncio.run(coro) + + +class DummySummarizer: + """Deterministic summarizer used in tests.""" + + def __init__(self): + self.calls = 0 + + async def summarize(self, messages): # pylint: disable=unused-argument + self.calls += 1 + shadow = "Summarize the conversation we had so far." + summary = "Synthetic summary block" + await asyncio.sleep(0) + return shadow, summary + + +def test_trimming_session_keeps_last_turns(): + session = TrimmingSession("session", max_turns=2) + transcript = [ + {"role": "user", "content": "First question"}, + {"role": "assistant", "content": "First answer"}, + {"role": "user", "content": "Second question"}, + {"role": "assistant", "content": "Second answer"}, + {"role": "user", "content": "Third question"}, + {"role": "assistant", "content": "Third answer"}, + ] + + run_async(session.add_items(transcript)) + history = run_async(session.get_items()) + + assert len(history) == 4 + assert history[0]["content"] == "Second question" + assert history[-1]["content"] == "Third answer" + + +def test_trimming_session_respects_dynamic_limit(): + session = TrimmingSession("session", max_turns=3) + run_async(session.add_items([ + {"role": "user", "content": "Alpha"}, + {"role": "assistant", "content": "Ack"}, + {"role": "user", "content": "Beta"}, + {"role": "assistant", "content": "Bee"}, + {"role": "user", "content": "Gamma"}, + {"role": "assistant", "content": "Gee"}, + ])) + + run_async(session.set_max_turns(1)) + history = run_async(session.get_items()) + + assert len(history) == 2 + assert history[0]["content"] == "Gamma" + + popped = run_async(session.pop_item()) + assert popped["content"] == "Gee" + + +def test_summarizing_session_generates_summary_block(): + summarizer = DummySummarizer() + session = SummarizingSession( + keep_last_n_turns=1, + context_limit=2, + summarizer=summarizer, + session_id="support", + ) + + run_async(session.add_items([ + {"role": "user", "content": "Initial issue"}, + {"role": "assistant", "content": "First response"}, + {"role": "user", "content": "Follow-up"}, + {"role": "assistant", "content": "Second response"}, + {"role": "user", "content": "Third turn"}, + {"role": "assistant", "content": "Third response"}, + ])) + + history = run_async(session.get_items()) + assert history[0]["role"] == "user" + assert history[0]["content"] == "Summarize the conversation we had so far." + assert history[1]["role"] == "assistant" + assert history[1]["content"] == "Synthetic summary block" + assert history[-2]["content"] == "Third turn" + assert summarizer.calls == 1 + + full_history = run_async(session.get_full_history()) + synthetic_entries = [item for item in full_history if item["metadata"].get("synthetic")] + assert len(synthetic_entries) == 2 + assert synthetic_entries[0]["metadata"]["kind"] == "history_summary_prompt" + assert synthetic_entries[1]["metadata"]["kind"] == "history_summary" + + +def test_summarizing_session_respects_context_limit_without_summary(): + summarizer = DummySummarizer() + session = SummarizingSession( + keep_last_n_turns=2, + context_limit=3, + summarizer=summarizer, + session_id="support", + ) + + run_async(session.add_items([ + {"role": "user", "content": "Turn one"}, + {"role": "assistant", "content": "Answer one"}, + {"role": "user", "content": "Turn two"}, + {"role": "assistant", "content": "Answer two"}, + ])) + + history = run_async(session.get_items()) + assert summarizer.calls == 0 + assert history[0]["content"] == "Turn one" + assert history[-1]["content"] == "Answer two"