chore: auto-commit (5 archivos)
- app.md - backend/chat.go - Dockerfile - docker-compose.yml - traefik-dynamic.yml Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+38
-9
@@ -15,18 +15,17 @@ import (
|
||||
"nhooyr.io/websocket"
|
||||
)
|
||||
|
||||
const chatSystemPrompt = `Eres el asistente del tablero kanban. Responde al usuario y, cuando pida cambios, modifica el tablero llamando a tools nativas (MCP).
|
||||
const chatSystemPrompt = `Asistente del tablero kanban. Modifica el tablero llamando a tools MCP cuando el usuario pida cambios. Responde texto en markdown cuando solo informe.
|
||||
|
||||
Tools disponibles via MCP server "kanban":
|
||||
- list_board / find_cards / card_history / list_users — lectura
|
||||
- create_column / update_column / delete_column / reorder_columns — columnas
|
||||
- create_card / update_card / delete_card / move_card / assign_card — tarjetas
|
||||
Tools (MCP server "kanban"):
|
||||
- Lectura: list_board, find_cards, card_history, list_users
|
||||
- Columnas: create_column, update_column, delete_column, reorder_columns
|
||||
- Tarjetas: create_card, update_card, delete_card, move_card, assign_card
|
||||
|
||||
Llama directamente a las tools cuando necesites mutar el tablero. Usa list_board al principio si necesitas resolver nombres a IDs. NUNCA inventes IDs.
|
||||
El estado actual del tablero viene en <board_state> al final del mensaje. Usa esos IDs directamente — NO llames list_board si ya tienes lo que necesitas. NUNCA inventes IDs.
|
||||
|
||||
Cuando termines, responde texto natural en markdown (sin llamadas extra) — eso señala el fin de la conversacion.`
|
||||
Cuando termines, responde texto natural sin mas llamadas — eso cierra la conversacion.`
|
||||
|
||||
const claudeModel = "claude-sonnet-4-6"
|
||||
const claudeTimeout = 300 * time.Second
|
||||
|
||||
func claudeBinary() string {
|
||||
@@ -36,6 +35,13 @@ func claudeBinary() string {
|
||||
return "claude"
|
||||
}
|
||||
|
||||
func claudeModel() string {
|
||||
if m := os.Getenv("KANBAN_CLAUDE_MODEL"); m != "" {
|
||||
return m
|
||||
}
|
||||
return "claude-haiku-4-5-20251001"
|
||||
}
|
||||
|
||||
type chatMessage struct {
|
||||
Role string `json:"role"`
|
||||
Content string `json:"content"`
|
||||
@@ -125,13 +131,18 @@ func streamChat(ctx context.Context, conn *websocket.Conn, db *DB, workdir, toke
|
||||
defer os.Remove(mcpPath)
|
||||
|
||||
prompt := flattenMessages(msgs)
|
||||
if board, err := boardSnapshot(db); err == nil && board != "" {
|
||||
prompt += "\n\n<board_state>\n" + board + "\n</board_state>\n"
|
||||
}
|
||||
|
||||
stdin := strings.NewReader(prompt)
|
||||
events, err := core.StreamClaude(ctx, core.ClaudeStreamOpts{
|
||||
Bin: claudeBinary(),
|
||||
Args: []string{
|
||||
"--model", claudeModel,
|
||||
"--model", claudeModel(),
|
||||
"--no-session-persistence",
|
||||
"--mcp-config", mcpPath,
|
||||
"--strict-mcp-config",
|
||||
"--system-prompt", chatSystemPrompt,
|
||||
"--allowedTools",
|
||||
"mcp__kanban__list_board,mcp__kanban__create_column,mcp__kanban__update_column,mcp__kanban__rename_column,mcp__kanban__delete_column,mcp__kanban__reorder_columns,mcp__kanban__create_card,mcp__kanban__update_card,mcp__kanban__delete_card,mcp__kanban__move_card,mcp__kanban__card_history,mcp__kanban__find_cards,mcp__kanban__list_users,mcp__kanban__assign_card",
|
||||
@@ -215,6 +226,24 @@ func flattenMessages(msgs []chatMessage) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// boardSnapshot returns a JSON dump of columns + cards to inject in the
|
||||
// initial prompt, saving a list_board round-trip.
|
||||
func boardSnapshot(db *DB) (string, error) {
|
||||
cols, err := db.ListColumns()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cards, err := db.ListCardsWithTime()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b, err := json.Marshal(map[string]any{"columns": cols, "cards": cards})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
// chatWorkdir resolves an absolute working directory for `claude -p`.
|
||||
func chatWorkdir(dbPath string) string {
|
||||
abs, err := filepath.Abs(dbPath)
|
||||
|
||||
Reference in New Issue
Block a user