Extensión
Una sección por cada punto de extensión que el repositorio realmente expone.
Renderizador de texto conectable (text_renderer=)#
panel(), render_transcript(), y render_output_field() (streamlit_coco/ui.py, streamlit_coco/display.py) aceptan text_renderer= para que una app pueda renderizar texto de asistente/usuario con cualquier API de texto de Streamlit, o un callable personalizado, en lugar del st.markdown fijo por defecto.
Valores nombrados: "markdown" (por defecto), "write", "text", "caption", "code" (también acepta nombres con prefijo st.*). Pasar un nombre desconocido lanza un ValueError listando los nombres conocidos.
Forma callable: pasa cualquier función con forma Callable[[str], None] — se invoca con el texto del mensaje.
Archivos a tocar:
streamlit_coco/text_renderer.py— la tabla de resolución nombre →callable. Añade aquí un nuevo valor nombrado si extiendes el conjunto incluido.
- Los puntos de llamada en
streamlit_coco/ui.py(panel) ystreamlit_coco/display.py(render_transcript,render_output_field) ya propagantext_renderer; un renderizador nuevo solo necesita registrarse una vez.
Paso de regeneración/verificación: ejecuta examples/chat_app.py (make chat) con el nuevo renderizador pasado explícitamente y confirma que el texto de asistente/usuario se renderiza como se espera; no se necesita ningún paso de build ya que esto es Python puro.
Tests a añadir: extiende doc/features/text-renderer/test-checklist.md con el nuevo valor nombrado, y añade un caso al archivo de test unitario relevante que cubra la resolución del renderizador (no hay un test_text_renderer.py dedicado en el árbol actual — revisa tests/ para la cobertura existente más cercana antes de añadir un archivo nuevo).
Despacho de familia/nombre de herramienta#
streamlit_coco/tool_names.py mapea un nombre de herramienta en bruto a una enumeración ToolFamily (ASK_USER, SQL, READ, WRITE, EDIT, BASH, GLOB, GREP, EXIT_PLAN, GENERIC) vía tool_family(name), usando una tabla de búsqueda normalizada (minúsculas, sin separadores). Cualquier nombre de herramienta que no coincida con una familia conocida — incluidas las herramientas MCP — recae en GENERIC y obtiene una tarjeta de herramienta genérica en lugar de una específica de familia.
Archivos a tocar:
streamlit_coco/tool_names.py— añade el/los nombre(s) normalizado(s)de la herramienta a
_FAMILY_BY_NORMALIZED, y añade un caso afamily_label()si necesita una etiqueta de cabecera dedicada en lugar del nombre de herramienta en bruto.streamlit_coco/tool_cards.py/streamlit_coco/tool_extract.py—añade el renderizado de tarjeta específico de familia y cualquier extracción de entrada/diff/SQL que necesite la nueva familia. Una familia dejada sin registrar aquí todavía se renderiza (vía el fallback
GENERIC); registrarla solo cambia cómo se muestra.
Paso de regeneración/verificación: ejecuta una demo de chat (`make chat`) con un prompt que ejercite la nueva herramienta y confirma que la tarjeta de herramienta se renderiza con la etiqueta de familia esperada y la vista previa en lugar del fallback genérico.
Tests a añadir: un caso en los tests unitarios que cubra tool_family() / family_label() para el nuevo nombre de herramienta (ver el patrón de cobertura de familia de herramienta existente en tests/), y un fixture NDJSON bajo tests/fixtures/ndjson/ si la nueva familia necesita cobertura de normalización de eventos en test_ndjson_fixtures.py.
Catálogo types/<id>/ de App Builder y paquetes de skill#
Cada type de app de App Builder es una carpeta bajo examples/app_builder/types/:
types/<id>/
type.json tarjeta de catálogo: id, name, icon, users, needs,
needs_snowflake, topics, grounding_kind, brief
(context, enables, does_not, questions)
SKILL.md opcional — reglas de layout y datos específicas
del type, leídas por CoCo vía add_dirs al generar la app
reference/ opcional — material de referencia de apoyo para SKILL.md
CHECKLIST.md opcional — lista de autocomprobación que el prompt
de generación ejecuta contra sí una vez tras un Write, antes de detenerse
types/shared/SKILL.md reglas de generación para todo type (sin type.json —
no es una tarjeta de catálogo); cada prompt Build/regenerate
le dice a CoCo que lea este archivo más el SKILL.md propio
del type (ambos montados vía add_dirs)Este es un punto de extensión a nivel de contenido: añadir un type no requiere ningún cambio de código Python, solo una nueva carpeta types/<id>/ (o usar el editor de types de la pantalla Admin, que escribe los mismos archivos).
Archivos a tocar:
examples/app_builder/types/<id>/type.json— obligatorio; sigue laforma de un type existente (por ejemplo
types/call-transcription/type.json) para la estructura debrief.questionsy los valores degrounding_kind(tabular/semantic_view/documents/urls) que deciden si el paso de perfilado es un parser pandas determinista (examples/app_builder/engine/profile.py) o un trabajo de CoCo.examples/app_builder/types/<id>/SKILL.md— opcional pero esperadopara un type real; sin él, CoCo genera solo contra las reglas compartidas.
examples/app_builder/engine/paths.py— no se necesita ningún cambio;TYPES_DIRya apunta atypes/, así que una carpeta nueva se recoge automáticamente.
Paso de regeneración/verificación: make app-builder, abre Library, confirma que la nueva tarjeta de type aparece (filtrada correctamente por sus topics), rellena un brief, y Build — confirma que el streamlit_app.py generado sigue las reglas del nuevo SKILL.md y (si hay un CHECKLIST.md) que el prompt de generación se autocomprueba contra él una vez.
Tests a añadir: un caso en test_app_builder_catalog.py que cubra que el nuevo type.json se parsea y valida contra los campos de tarjeta de catálogo que leen las páginas Library/Brief/Admin; un caso en test_app_builder_profile.py si grounding_kind dispara una nueva ruta de perfilado determinista.
Añadir una nueva app de ejemplo#
El patrón establecido para un ejemplo basado en rail (como en examples/bi_to_semantic/ y examples/app_builder/) compone copilot_rail() para el Copilot y app_viewer() para una vista previa en vivo de lo que sea que escriba CoCo, conectados a través de on_fix / encolado de trabajos — ver architecture.
Archivos a tocar:
examples/<name>/— carpeta nueva con su propioapp.py(oapp_pages/multipágina), siguiendo el patrón de composición del ejemplo existente más cercano en forma al nuevo (backlog_desk/para un ejemplo de rail sin SQL;bi_to_semantic/oapp_builder/para un ejemplo de rail + vista previa).Makefile— añade un objetivo<name>:que ejecute el nuevo ejemplo(reflejando un objetivo existente, por ejemplo
bi-semantic:), añádelo a.PHONY, y añade una línea ahelp.doc/deployment/local.md§5 ydoc/testing.md— añade el nuevoobjetivo
makea la tabla de ejemplos para que se descubra desde la documentación que ya los lista.
Paso de regeneración/verificación: make <name> se ejecuta y alcanza una pantalla usable; si el ejemplo usa app_viewer(), confirma que el puerto de vista previa no colisiona con el puerto fijo de un ejemplo existente (los ejemplos chat/backlog no usan app_viewer; bi_to_semantic usa :8511/:8512; app_builder usa :8513).
Tests a añadir: como mínimo un test de smoke paralelo a la cobertura de test_smoke.py de los ejemplos existentes, y una entrada de checklist de funcionalidad bajo doc/features/<feature>/test-checklist.md si el ejemplo ejercita comportamiento de interfaz nuevo en lugar de solo recomponer primitivos existentes.