chore: auto-commit (27 archivos)
- .claude/CLAUDE.md - .claude/rules/create_agent.md - agents/_specials/father-bot/prompts/system.md - agents/_template/config.yaml - agents/_template_robot/config.yaml - cmd/agentctl/autoavatar.go - cmd/launcher/sqlite.go - dev-scripts/_common.sh - dev-scripts/agent/create-full.sh - dev-scripts/agent/delete-full.sh - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -57,7 +57,8 @@ config_path_for() {
|
||||
for cfg in agents/*/config.yaml agents/_specials/*/config.yaml; do
|
||||
[[ -f "$cfg" ]] || continue
|
||||
local id
|
||||
id=$(grep -m1 '^ id:' "$cfg" | awk '{print $2}')
|
||||
# Strip quotes from value: handles both `id: foo` and `id: "foo"`
|
||||
id=$(grep -m1 '^ id:' "$cfg" | sed -E 's/^[^:]*:[[:space:]]*//; s/^"//; s/"$//; s/^'\''//; s/'\''$//')
|
||||
if [[ "$id" == "$target_id" ]]; then
|
||||
echo "$cfg"
|
||||
return
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
#
|
||||
# Flags de personalización (opcionales, activan el Paso 8 automático):
|
||||
# --description "<texto>" descripcion del agente
|
||||
# --provider <openai|anthropic|...> proveedor LLM (default: auto-detect)
|
||||
# --provider <claude-code|openai|anthropic> proveedor LLM (default: claude-code)
|
||||
# REGLA PROYECTO: usar claude-code SIEMPRE salvo razon explicita
|
||||
# --model <modelo> modelo LLM (default: segun provider)
|
||||
# --tone <friendly|professional|...> tono (default: friendly)
|
||||
# --prefix "<emoji>" emoji prefix (default: 🤖)
|
||||
@@ -37,6 +38,8 @@
|
||||
# --system-prompt-file <path> system prompt desde archivo
|
||||
# --tool-use habilitar tool_use en config
|
||||
# --language <es|en> idioma (default: es)
|
||||
# --avatar <URL_o_ruta> imagen para el avatar (default: generador random)
|
||||
# ej: https://example/pikachu.png o ./avatars/poke.png
|
||||
#
|
||||
# Requisitos en .env:
|
||||
# MATRIX_ADMIN_TOKEN, MATRIX_HOMESERVER, MATRIX_SERVER_NAME
|
||||
@@ -88,10 +91,15 @@ while [[ $# -gt 0 ]]; do
|
||||
--tool-use) PERSONALIZE_TOOL_USE=true; DO_PERSONALIZE=true; shift ;;
|
||||
--language) PERSONALIZE_LANGUAGE="${2:-es}"; DO_PERSONALIZE=true; shift 2 ;;
|
||||
--language=*) PERSONALIZE_LANGUAGE="${1#--language=}"; DO_PERSONALIZE=true; shift ;;
|
||||
--avatar) AVATAR_SOURCE="${2:-}"; shift 2 ;;
|
||||
--avatar=*) AVATAR_SOURCE="${1#--avatar=}"; shift ;;
|
||||
*) shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# AVATAR_SOURCE puede ser URL (http/https) o ruta local. Vacio = generador random.
|
||||
: "${AVATAR_SOURCE:=}"
|
||||
|
||||
if [[ "$TYPE" == "robot" ]]; then
|
||||
TYPE_LABEL="robot"
|
||||
TYPE_EMOJI="🤖"
|
||||
@@ -165,22 +173,34 @@ if [[ "$TYPE" == "robot" ]]; then
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ── Paso auto-avatar: Generar avatar automatico ─────────────────────────
|
||||
# ── Paso auto-avatar: Generar/aplicar avatar ────────────────────────────
|
||||
AVATAR_STEP=$((TOTAL_STEPS - 2))
|
||||
info "Paso ${AVATAR_STEP}/${TOTAL_STEPS} — Generando avatar automatico..."
|
||||
info "Paso ${AVATAR_STEP}/${TOTAL_STEPS} — Configurando avatar del bot..."
|
||||
echo ""
|
||||
|
||||
# Resuelve el binario de agentctl
|
||||
# Resuelve el binario de agentctl como array (preserva split por espacios)
|
||||
if [[ -f "$REPO_ROOT/bin/agentctl" ]]; then
|
||||
CTL="$REPO_ROOT/bin/agentctl"
|
||||
CTL_ARR=("$REPO_ROOT/bin/agentctl")
|
||||
else
|
||||
CTL="$GO run -tags goolm ./cmd/agentctl"
|
||||
CTL_ARR=("$GO" run -tags goolm ./cmd/agentctl)
|
||||
fi
|
||||
|
||||
if $CTL auto-avatar "$ID" 2>&1; then
|
||||
ok "Avatar generado y aplicado"
|
||||
# Si el usuario pasa --avatar, usa la URL/ruta indicada en vez del generador random.
|
||||
AVATAR_CMD=("${CTL_ARR[@]}" auto-avatar "$ID")
|
||||
if [[ -n "$AVATAR_SOURCE" ]]; then
|
||||
if [[ "$AVATAR_SOURCE" =~ ^https?:// ]]; then
|
||||
AVATAR_CMD+=(--from-url "$AVATAR_SOURCE")
|
||||
info "Usando avatar personalizado desde URL: $AVATAR_SOURCE"
|
||||
else
|
||||
AVATAR_CMD+=(--from-file "$AVATAR_SOURCE")
|
||||
info "Usando avatar personalizado desde archivo: $AVATAR_SOURCE"
|
||||
fi
|
||||
fi
|
||||
|
||||
if "${AVATAR_CMD[@]}" 2>&1; then
|
||||
ok "Avatar configurado y aplicado"
|
||||
else
|
||||
warn "No se pudo generar avatar automatico (se puede hacer despues con: agentctl auto-avatar $ID)"
|
||||
warn "No se pudo configurar avatar (se puede hacer despues con: agentctl auto-avatar $ID [--from-url <url> | --from-file <path>])"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -213,6 +233,21 @@ fi
|
||||
|
||||
echo ""
|
||||
|
||||
# ── Paso 8a (robots): aplicar --description al config.yaml ──────────────
|
||||
# Los robots no tienen prompts/system.md ni agent.go (no LLM), pero su
|
||||
# config.yaml SI tiene un campo `description:` que personalize.sh ignora.
|
||||
# Para evitar que el robot quede con la descripcion del template literal,
|
||||
# parcheamos la linea aqui.
|
||||
if [[ "$TYPE" == "robot" ]] && [[ -n "$PERSONALIZE_DESCRIPTION" ]]; then
|
||||
CFG_FILE="agents/$ID/config.yaml"
|
||||
if [[ -f "$CFG_FILE" ]]; then
|
||||
# Escapar caracteres especiales del valor para sed
|
||||
ESCAPED_DESC="$(printf '%s' "$PERSONALIZE_DESCRIPTION" | sed -e 's/[\/&|]/\\&/g')"
|
||||
sed -i "0,/^ description:.*/s|| description: \"$ESCAPED_DESC\"|" "$CFG_FILE"
|
||||
ok "Descripcion del robot aplicada al config.yaml"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Paso 8 (automático, solo agents): Personalizar archivos ─────────────
|
||||
PERSONALIZE_DONE=false
|
||||
if $DO_PERSONALIZE && [[ "$TYPE" != "robot" ]]; then
|
||||
|
||||
@@ -78,14 +78,16 @@ fi
|
||||
AGENT_DESC=""
|
||||
AGENT_TYPE="agent"
|
||||
if [[ -f "$CFG_PATH" ]]; then
|
||||
AGENT_DESC=$(grep -m1 'description:' "$CFG_PATH" | cut -d'"' -f2)
|
||||
TYPE_LINE=$(grep -m1 'type:' "$CFG_PATH" | awk '{print $2}')
|
||||
[[ -n "$TYPE_LINE" ]] && AGENT_TYPE="$TYPE_LINE"
|
||||
AGENT_DESC=$(grep -m1 'description:' "$CFG_PATH" | cut -d'"' -f2 || true)
|
||||
TYPE_LINE=$(grep -m1 'type:' "$CFG_PATH" | awk '{print $2}' || true)
|
||||
if [[ -n "${TYPE_LINE:-}" ]]; then
|
||||
AGENT_TYPE="$TYPE_LINE"
|
||||
fi
|
||||
fi
|
||||
|
||||
ok "Agente $ID encontrado en $AGENT_DIR/"
|
||||
dim " Tipo: $AGENT_TYPE"
|
||||
[[ -n "$AGENT_DESC" ]] && dim " Descripcion: $AGENT_DESC"
|
||||
if [[ -n "$AGENT_DESC" ]]; then dim " Descripcion: $AGENT_DESC"; fi
|
||||
echo ""
|
||||
|
||||
# ── Confirmacion interactiva ────────────────────────────────────────────────
|
||||
|
||||
@@ -2,37 +2,47 @@
|
||||
# detect-provider.sh — detecta el proveedor LLM disponible desde .env
|
||||
#
|
||||
# Salida: dos palabras en stdout — "<provider> <model>"
|
||||
# openai gpt-4o
|
||||
# anthropic claude-sonnet-4-20250514
|
||||
# claude-code sonnet (DEFAULT)
|
||||
# openai gpt-4o
|
||||
# anthropic claude-sonnet-4-20250514
|
||||
#
|
||||
# Orden de detección:
|
||||
# 1. OPENAI_API_KEY → openai gpt-4o
|
||||
# 2. ANTHROPIC_API_KEY → anthropic claude-sonnet-4-20250514
|
||||
# Fallback: openai gpt-4o (con warning en stderr)
|
||||
# Orden de detección (claude-code primero — REGLA DEL PROYECTO):
|
||||
# 1. CLAUDE binary disponible en PATH → claude-code sonnet
|
||||
# 2. OPENAI_API_KEY → openai gpt-4o
|
||||
# 3. ANTHROPIC_API_KEY → anthropic claude-sonnet-4-20250514
|
||||
# Fallback: claude-code sonnet (binary `claude` debe estar instalado)
|
||||
#
|
||||
# Uso:
|
||||
# read -r PROVIDER MODEL < <(./dev-scripts/agent/detect-provider.sh)
|
||||
# ./dev-scripts/agent/detect-provider.sh # imprime "openai gpt-4o"
|
||||
# ./dev-scripts/agent/detect-provider.sh # imprime "claude-code sonnet"
|
||||
|
||||
source "$(dirname "$0")/../_common.sh"
|
||||
load_env
|
||||
|
||||
# Default models por provider
|
||||
CLAUDE_CODE_DEFAULT_MODEL="sonnet"
|
||||
OPENAI_DEFAULT_MODEL="gpt-4o"
|
||||
ANTHROPIC_DEFAULT_MODEL="claude-sonnet-4-20250514"
|
||||
|
||||
# Detectar provider disponible
|
||||
# 1. claude-code (preferido) — solo requiere el binario `claude` en PATH
|
||||
if command -v claude >/dev/null 2>&1; then
|
||||
echo "claude-code $CLAUDE_CODE_DEFAULT_MODEL"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 2. OpenAI API key
|
||||
if [[ -n "${OPENAI_API_KEY:-}" ]]; then
|
||||
echo "openai $OPENAI_DEFAULT_MODEL"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 3. Anthropic API key
|
||||
if [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then
|
||||
echo "anthropic $ANTHROPIC_DEFAULT_MODEL"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fallback con warning
|
||||
warn "Ninguna API key configurada (OPENAI_API_KEY, ANTHROPIC_API_KEY) — usando fallback openai/gpt-4o" >&2
|
||||
echo "openai $OPENAI_DEFAULT_MODEL"
|
||||
# Fallback: claude-code (warning porque el binario falta)
|
||||
warn "Ningun proveedor disponible (binary 'claude' missing, OPENAI_API_KEY/ANTHROPIC_API_KEY missing) — usando fallback claude-code/sonnet (instala claude CLI)" >&2
|
||||
echo "claude-code $CLAUDE_CODE_DEFAULT_MODEL"
|
||||
exit 0
|
||||
|
||||
@@ -42,6 +42,10 @@ sed -i "s/template: true/template: false/g" "$DIR/config.yaml"
|
||||
sed -i "s/enabled: true/enabled: true/g" "$DIR/config.yaml"
|
||||
sed -i "s/MATRIX_TOKEN_TEMPLATE/MATRIX_TOKEN_${NORM}/g" "$DIR/config.yaml"
|
||||
sed -i "s/PICKLE_KEY_TEMPLATE/PICKLE_KEY_${NORM}/g" "$DIR/config.yaml"
|
||||
sed -i "s/SSSS_RECOVERY_KEY_TEMPLATE/SSSS_RECOVERY_KEY_${NORM}/g" "$DIR/config.yaml"
|
||||
sed -i "s/SSSS_RECOVERY_KEY_ROBOT/SSSS_RECOVERY_KEY_${NORM}/g" "$DIR/config.yaml"
|
||||
sed -i "s/MATRIX_TOKEN_ROBOT/MATRIX_TOKEN_${NORM}/g" "$DIR/config.yaml"
|
||||
sed -i "s/PICKLE_KEY_ROBOT/PICKLE_KEY_${NORM}/g" "$DIR/config.yaml"
|
||||
sed -i "s/@template:matrix.example.com/@$ID:\${MATRIX_SERVER_NAME}/g" "$DIR/config.yaml"
|
||||
sed -i "s|https://matrix.example.com|\${MATRIX_HOMESERVER}|g" "$DIR/config.yaml"
|
||||
|
||||
|
||||
@@ -186,7 +186,15 @@ for dev in "${DEVS[@]}"; do
|
||||
dev="$(echo "$dev" | xargs)" # trim spaces
|
||||
[[ -z "$dev" ]] && continue
|
||||
|
||||
USER_ID="@${dev}:${MATRIX_SERVER_NAME}"
|
||||
# Acepta ambos formatos:
|
||||
# - "egutierrez" (bare username)
|
||||
# - "@egutierrez:matrix-...organic-machine.com" (full MXID)
|
||||
if [[ "$dev" == @*:* ]]; then
|
||||
USER_ID="$dev"
|
||||
else
|
||||
USER_ID="@${dev}:${MATRIX_SERVER_NAME}"
|
||||
fi
|
||||
|
||||
info "Enviando DM de $ID a $USER_ID..."
|
||||
|
||||
send_dm "$USER_ID"
|
||||
|
||||
Reference in New Issue
Block a user