From 515c26d56d0993685ed9a7487fee37231d1abf3e Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Fri, 6 Mar 2026 23:02:50 +0000 Subject: [PATCH] =?UTF-8?q?chore:=20mover=20tareas=2006-07=20a=20completed?= =?UTF-8?q?=20y=20a=C3=B1adir=20tareas=2008-09?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mueve las tareas completadas (06-añadir-claude-p, 07-logs-mejorados) al directorio completed/. Añade nuevas tareas pendientes: 08-knowledge_por_agente y 09-command_system. Co-Authored-By: Claude Opus 4.6 --- .claude/tasks/08-knowledge_por_agente.md | 305 ++++++++++++++++++ .claude/tasks/09-command_system.md | 0 .../{ => completed}/06-añadir-claude-p.md | 2 +- .../{ => completed}/07-logs-mejorados.md | 0 4 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 .claude/tasks/08-knowledge_por_agente.md create mode 100644 .claude/tasks/09-command_system.md rename .claude/tasks/{ => completed}/06-añadir-claude-p.md (99%) rename .claude/tasks/{ => completed}/07-logs-mejorados.md (100%) diff --git a/.claude/tasks/08-knowledge_por_agente.md b/.claude/tasks/08-knowledge_por_agente.md new file mode 100644 index 0000000..629b0d2 --- /dev/null +++ b/.claude/tasks/08-knowledge_por_agente.md @@ -0,0 +1,305 @@ +# Tarea 08 — Knowledge por agente + +## Objetivo + +Cada agente tiene una carpeta `knowledge/` donde almacena documentos de conocimiento (markdown). +El agente puede buscar, leer, escribir y mejorar su propio conocimiento usando tools siempre disponibles. +El conocimiento es archivos reales — inspeccionables por humanos, editables, y se pueden sembrar con contenido inicial. + +## Diseño + +### Almacenamiento híbrido: archivos + índice FTS5 + +``` +agents//knowledge/ ← archivos .md reales (human-readable) +├── go-patterns.md +├── user-preferences.md +└── matrix-tips.md + +agents//data/knowledge.db ← índice SQLite FTS5 (búsqueda rápida) +``` + +- Los documentos viven como archivos `.md` en `knowledge/`. +- Un índice FTS5 en SQLite permite búsqueda full-text instantánea. +- Al iniciar, se sincroniza: archivos → índice (detecta nuevos, modificados, eliminados). +- Al escribir via tool, se actualiza archivo + índice atómicamente. + +### Por qué archivos y no solo SQLite + +1. **Sembrables**: se puede crear `knowledge/` con documentos iniciales antes de arrancar +2. **Inspeccionables**: un humano puede leer/editar el conocimiento del agente +3. **Git-friendly**: opcionalmente trackeable en el repo +4. **Naturales**: el agente "escribe documentos", no inserta rows + +--- + +## Arquitectura (pure core / impure shell) + +### 1. Pure core: `pkg/knowledge/` + +```go +// pkg/knowledge/types.go +package knowledge + +import "time" + +// Document represents a knowledge document. +type Document struct { + Slug string // filename sin extensión, e.g. "go-patterns" + Title string // primera línea H1 del markdown, o slug humanizado + Content string // contenido completo del archivo + UpdatedAt time.Time // mtime del archivo +} + +// SearchResult is a document matched by a search query. +type SearchResult struct { + Slug string + Title string + Snippet string // fragmento relevante con match highlights + Rank float64 // relevancia FTS5 +} +``` + +```go +// pkg/knowledge/store.go +package knowledge + +import "context" + +// Store is the pure interface for knowledge operations. +// Implemented by shell/knowledge. +type Store interface { + // Search performs full-text search across all documents. + Search(ctx context.Context, query string, limit int) ([]SearchResult, error) + + // Get retrieves a document by slug. + Get(ctx context.Context, slug string) (*Document, error) + + // Put creates or updates a document (file + index). + Put(ctx context.Context, doc Document) error + + // Delete removes a document (file + index). + Delete(ctx context.Context, slug string) error + + // List returns all document slugs with titles. + List(ctx context.Context) ([]Document, error) + + // Sync re-indexes all files from disk. Called on startup. + Sync(ctx context.Context) error + + // Close releases resources. + Close() error +} +``` + +### 2. Impure shell: `shell/knowledge/` + +```go +// shell/knowledge/store.go +package knowledge + +// FileStore implements knowledge.Store using files + SQLite FTS5. +type FileStore struct { + dir string // path a agents//knowledge/ + dbPath string // path a agents//data/knowledge.db + db *sql.DB + logger *slog.Logger +} +``` + +**Schema SQLite:** + +```sql +CREATE VIRTUAL TABLE IF NOT EXISTS documents USING fts5( + slug, + title, + content, + updated_at UNINDEXED +); +``` + +**Operaciones:** + +| Método | Archivos | SQLite FTS5 | +|--------|----------|-------------| +| `Sync()` | Lee todos los `.md` del dir | Reconstruye índice completo | +| `Search()` | — | `SELECT slug, title, snippet(...) FROM documents WHERE documents MATCH ?` | +| `Get()` | Lee `{slug}.md` | — | +| `Put()` | Escribe `{slug}.md` | Upsert en FTS5 | +| `Delete()` | Borra `{slug}.md` | Delete en FTS5 | +| `List()` | — | `SELECT slug, title FROM documents` | + +**Sync al startup:** +1. Listar `*.md` en el directorio +2. Para cada archivo: leer contenido, extraer título (primer `# ...`), calcular mtime +3. `DELETE FROM documents` + re-insertar todo (rebuild completo, simple y correcto) +4. Log: `knowledge_sync count=N` + +**Slug rules:** +- Solo `[a-z0-9-]`, máximo 64 chars +- Derivado del nombre de archivo sin `.md` +- El tool valida antes de escribir + +### 3. Tools: `tools/knowledge.go` + +Cuatro tools que el agente siempre tiene disponibles cuando knowledge está habilitado: + +#### `knowledge_search` +``` +Nombre: knowledge_search +Descripción: Search your knowledge base for relevant documents. Returns matching snippets ranked by relevance. +Parámetros: + - query (string, required): Search terms or phrase + - limit (integer, optional): Max results, default 5 +Retorna: Lista de resultados con slug, título y snippet +``` + +#### `knowledge_read` +``` +Nombre: knowledge_read +Descripción: Read the full content of a knowledge document by its slug. +Parámetros: + - slug (string, required): Document slug (e.g. "go-patterns") +Retorna: Contenido completo del documento +``` + +#### `knowledge_write` +``` +Nombre: knowledge_write +Descripción: Create or update a knowledge document. Use this to save new knowledge or improve existing documents. +Parámetros: + - slug (string, required): Document slug (lowercase, hyphens, e.g. "matrix-tips") + - content (string, required): Full markdown content of the document +Retorna: Confirmación con slug y tamaño +``` + +#### `knowledge_list` +``` +Nombre: knowledge_list +Descripción: List all documents in your knowledge base with their titles. +Parámetros: ninguno +Retorna: Lista de slugs con títulos y fecha de última actualización +``` + +> **Nota:** No incluyo `knowledge_delete` por ahora. Los agentes deberían mejorar y ampliar, no borrar. Si se necesita, se añade después. + +### 4. Config: `internal/config/schema.go` + +```go +type KnowledgeCfg struct { + Enabled bool `yaml:"enabled"` + Dir string `yaml:"dir"` // default: "./knowledge" (relativo al dir del agente) +} +``` + +Añadir a `ToolsCfg`: +```go +type ToolsCfg struct { + // ... existentes ... + Knowledge KnowledgeCfg `yaml:"knowledge"` +} +``` + +Config de ejemplo en `config.yaml`: +```yaml +tools: + knowledge: + enabled: true + dir: "./knowledge" # opcional, default relativo al agente +``` + +### 5. Registro en runtime: `agents/runtime.go` + +En `buildToolRegistry()`, después de los memory tools: + +```go +if cfg.Tools.Knowledge.Enabled { + knowledgeDir := resolveKnowledgeDir(cfg) // resolve relative to agent dir + knowledgeDBPath := filepath.Join(cfg.Storage.DataDir, "knowledge.db") + kStore, err := shellknowledge.New(knowledgeDir, knowledgeDBPath, logger) + if err != nil { + logger.Error("knowledge_store_init_failed", "err", err) + } else { + // Sync on startup + if err := kStore.Sync(ctx); err != nil { + logger.Error("knowledge_sync_failed", "err", err) + } + reg.Register(tools.NewKnowledgeSearch(kStore)) + reg.Register(tools.NewKnowledgeRead(kStore)) + reg.Register(tools.NewKnowledgeWrite(kStore)) + reg.Register(tools.NewKnowledgeList(kStore)) + logger.Debug("registered knowledge tools") + } +} +``` + +--- + +## Plan de implementación (orden) + +### Paso 1 — Pure types (`pkg/knowledge/`) +- [ ] `pkg/knowledge/types.go` — Document, SearchResult +- [ ] `pkg/knowledge/store.go` — Store interface + +### Paso 2 — Config +- [ ] Añadir `KnowledgeCfg` a `internal/config/schema.go` dentro de `ToolsCfg` + +### Paso 3 — Shell store (`shell/knowledge/`) +- [ ] `shell/knowledge/store.go` — FileStore con FTS5 + - Constructor `New(dir, dbPath, logger)` + - Sync(), Search(), Get(), Put(), Delete(), List(), Close() + - Validación de slugs + - Extracción de título del markdown (primer `# `) + +### Paso 4 — Tools (`tools/knowledge.go`) +- [ ] `tools/knowledge.go` — NewKnowledgeSearch, NewKnowledgeRead, NewKnowledgeWrite, NewKnowledgeList +- [ ] Interface `KnowledgeStore` en tools (subset de knowledge.Store, como se hizo con MemoryStore) + +### Paso 5 — Registro en runtime +- [ ] Modificar `buildToolRegistry()` en `agents/runtime.go` +- [ ] Resolver directorio de knowledge relativo al agente + +### Paso 6 — Activar en agentes existentes +- [ ] Crear `agents/assistant-bot/knowledge/` con un documento semilla +- [ ] Crear `agents/asistente-2/knowledge/` con un documento semilla +- [ ] Actualizar `config.yaml` de ambos agentes: `tools.knowledge.enabled: true` +- [ ] Actualizar system prompts para que el agente sepa que tiene knowledge tools + +### Paso 7 — Tests +- [ ] Test de `shell/knowledge/` — sync, search, put, get, list +- [ ] Test de `tools/knowledge.go` — validación de slugs, parámetros +- [ ] Build completo: `go build -tags goolm ./...` + +--- + +## Ejemplo de uso por el agente + +Un usuario le dice al bot: "¿Cómo configuro un webhook en Gitea?" + +1. El agente llama `knowledge_search(query="gitea webhook")` +2. Encuentra `gitea-admin.md` con snippet relevante +3. Llama `knowledge_read(slug="gitea-admin")` para leer el documento completo +4. Responde al usuario con la info +5. Si descubre info nueva en la conversación, llama `knowledge_write(slug="gitea-webhooks", content="# Gitea Webhooks\n\n...")` para ampliar su base + +## Diferencia con memory tools + +| Aspecto | Memory (facts) | Knowledge (documents) | +|---------|----------------|----------------------| +| Granularidad | Key-value individual | Documentos completos | +| Búsqueda | Por subject exacto | Full-text search (FTS5) | +| Formato | Tripla (subject, key, value) | Markdown libre | +| Propósito | Datos puntuales sobre users/temas | Base de conocimiento estructurada | +| Persistencia | SQLite rows | Archivos .md + índice FTS5 | +| Editable por humanos | No (solo via SQL) | Sí (archivos normales) | + +--- + +## Notas de implementación + +- **FTS5 y modernc/sqlite**: modernc.org/sqlite soporta FTS5 nativamente, no necesita CGO. +- **Slugs**: validar con regexp `^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$` (min 2 chars). +- **Título**: extraer primera línea que empiece con `# `. Si no hay, usar slug humanizado. +- **Tamaño máximo por documento**: 64 KB (consistente con read_file tool). +- **Directorio knowledge/ en .gitignore**: decisión del usuario. Se puede trackear o no. +- **No embeddings**: FTS5 keyword search es suficiente para v1. Embeddings es extensión futura. diff --git a/.claude/tasks/09-command_system.md b/.claude/tasks/09-command_system.md new file mode 100644 index 0000000..e69de29 diff --git a/.claude/tasks/06-añadir-claude-p.md b/.claude/tasks/completed/06-añadir-claude-p.md similarity index 99% rename from .claude/tasks/06-añadir-claude-p.md rename to .claude/tasks/completed/06-añadir-claude-p.md index 4eaf100..8194ec9 100644 --- a/.claude/tasks/06-añadir-claude-p.md +++ b/.claude/tasks/completed/06-añadir-claude-p.md @@ -4,7 +4,7 @@ Que `claude -p` sea un backend LLM más dentro de `shell/llm/`, al mismo nivel que la API HTTP de Anthropic u otros proveedores. Los agentes no saben si su "modelo" es una llamada REST o un subproceso de Claude Code — simplemente envían un `CompletionRequest` y reciben un `CompletionResult`. -## Estado: pendiente +## Estado: Completado --- diff --git a/.claude/tasks/07-logs-mejorados.md b/.claude/tasks/completed/07-logs-mejorados.md similarity index 100% rename from .claude/tasks/07-logs-mejorados.md rename to .claude/tasks/completed/07-logs-mejorados.md