From bbaccd678d5bda6129fe665f275b6793ccb3ac7a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 16 Apr 2026 18:36:42 +0000 Subject: [PATCH 1/4] fix: entrypoint: validate_projects_dir silently exits instead of logging FATAL under set -eo pipefail (#877) `compgen -G ... | wc -l` under `set -eo pipefail` aborts the script on the non-zero pipeline exit (compgen returns 1 on no match) before the FATAL diagnostic branch can run. The container still fast-fails, but operators saw no explanation. Switch to the conditional `if ! compgen -G ... >/dev/null 2>&1; then` pattern already used at the two other compgen call sites in this file (bootstrap_factory_repo and the PROJECT_NAME parser). The count for the success-path log is computed after we've confirmed at least one match. Co-Authored-By: Claude Opus 4.6 (1M context) --- docker/agents/entrypoint.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docker/agents/entrypoint.sh b/docker/agents/entrypoint.sh index 89a520b..f838c15 100644 --- a/docker/agents/entrypoint.sh +++ b/docker/agents/entrypoint.sh @@ -346,15 +346,19 @@ bootstrap_factory_repo # This prevents the silent-zombie mode where the polling loop matches zero files # and does nothing forever. validate_projects_dir() { - local toml_count - toml_count=$(compgen -G "${DISINTO_DIR}/projects/*.toml" 2>/dev/null | wc -l) - if [ "$toml_count" -eq 0 ]; then + # NOTE: compgen -G exits non-zero when no matches exist, so piping it through + # `wc -l` under `set -eo pipefail` aborts the script before the FATAL branch + # can log a diagnostic (#877). Use the conditional form already adopted at + # lines above (see bootstrap_factory_repo, PROJECT_NAME parsing). + if ! compgen -G "${DISINTO_DIR}/projects/*.toml" >/dev/null 2>&1; then log "FATAL: No real .toml files found in ${DISINTO_DIR}/projects/" log "Expected at least one project config file (e.g., disinto.toml)" log "The directory only contains *.toml.example template files." log "Mount the host ./projects volume or copy real .toml files into the container." exit 1 fi + local toml_count + toml_count=$(compgen -G "${DISINTO_DIR}/projects/*.toml" | wc -l) log "Projects directory validated: ${toml_count} real .toml file(s) found" } From 11f89d9b7a68f342027d7dd03828280015d352ed Mon Sep 17 00:00:00 2001 From: dev-qwen2 Date: Thu, 16 Apr 2026 18:40:35 +0000 Subject: [PATCH 2/4] fix: Two parallel activation paths for llama agents (ENABLE_LLAMA_AGENT vs [agents.X] TOML) (#846) --- .env.example | 14 +-- bin/disinto | 14 --- docker/agents/entrypoint.sh | 32 +++++++ docs/agents-llama.md | 5 +- lib/forge-setup.sh | 166 ------------------------------------ lib/generators.sh | 130 ---------------------------- 6 files changed, 38 insertions(+), 323 deletions(-) diff --git a/.env.example b/.env.example index c1c0b98..a1f24d5 100644 --- a/.env.example +++ b/.env.example @@ -32,13 +32,10 @@ FORGE_URL=http://localhost:3000 # [CONFIG] local Forgejo instance # - FORGE_PASS_DEV_QWEN2 # Name conversion: tr 'a-z-' 'A-Z_' (lowercase→UPPER, hyphens→underscores). # The compose generator looks these up via the agent's `forge_user` field in -# the project TOML. The pre-existing `dev-qwen` llama agent uses -# FORGE_TOKEN_LLAMA / FORGE_PASS_LLAMA (kept for backwards-compat with the -# legacy `ENABLE_LLAMA_AGENT=1` single-agent path). +# the project TOML. Configure local-model agents via [agents.X] sections in +# projects/*.toml — this is the canonical activation path. FORGE_TOKEN= # [SECRET] dev-bot API token (default for all agents) FORGE_PASS= # [SECRET] dev-bot password for git HTTP push (#361) -FORGE_TOKEN_LLAMA= # [SECRET] dev-qwen API token (for agents-llama) -FORGE_PASS_LLAMA= # [SECRET] dev-qwen password for git HTTP push FORGE_REVIEW_TOKEN= # [SECRET] review-bot API token FORGE_REVIEW_PASS= # [SECRET] review-bot password for git HTTP push FORGE_PLANNER_TOKEN= # [SECRET] planner-bot API token @@ -107,13 +104,6 @@ FORWARD_AUTH_SECRET= # [SECRET] Shared secret for Caddy ↔ # Store all project secrets here so formulas reference env vars, never hardcode. BASE_RPC_URL= # [SECRET] on-chain RPC endpoint -# ── Local Qwen dev agent (optional) ────────────────────────────────────── -# Set ENABLE_LLAMA_AGENT=1 to emit agents-llama in docker-compose.yml. -# Requires a running llama-server reachable at ANTHROPIC_BASE_URL. -# See docs/agents-llama.md for details. -ENABLE_LLAMA_AGENT=0 # [CONFIG] 1 = enable agents-llama service -ANTHROPIC_BASE_URL= # [CONFIG] e.g. http://host.docker.internal:8081 - # ── Tuning ──────────────────────────────────────────────────────────────── CLAUDE_TIMEOUT=7200 # [CONFIG] max seconds per Claude invocation diff --git a/bin/disinto b/bin/disinto index 6128b7c..c6c2421 100755 --- a/bin/disinto +++ b/bin/disinto @@ -977,7 +977,6 @@ p.write_text(text) echo "" echo "[ensure] Forgejo admin user 'disinto-admin'" echo "[ensure] 8 bot users: dev-bot, review-bot, planner-bot, gardener-bot, vault-bot, supervisor-bot, predictor-bot, architect-bot" - echo "[ensure] 2 llama bot users: dev-qwen, dev-qwen-nightly" echo "[ensure] .profile repos for all bots" echo "[ensure] repo ${forge_repo} on Forgejo with collaborators" echo "[run] preflight checks" @@ -1173,19 +1172,6 @@ p.write_text(text) echo "Config: CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 saved to .env" fi - # Write local-Qwen dev agent env keys with safe defaults (#769) - if ! grep -q '^ENABLE_LLAMA_AGENT=' "$env_file" 2>/dev/null; then - cat >> "$env_file" <<'LLAMAENVEOF' - -# Local Qwen dev agent (optional) — set to 1 to enable -ENABLE_LLAMA_AGENT=0 -FORGE_TOKEN_LLAMA= -FORGE_PASS_LLAMA= -ANTHROPIC_BASE_URL= -LLAMAENVEOF - echo "Config: ENABLE_LLAMA_AGENT keys written to .env (disabled by default)" - fi - # Create labels on remote create_labels "$forge_repo" "$forge_url" diff --git a/docker/agents/entrypoint.sh b/docker/agents/entrypoint.sh index 89a520b..0007c0e 100644 --- a/docker/agents/entrypoint.sh +++ b/docker/agents/entrypoint.sh @@ -17,6 +17,38 @@ set -euo pipefail # - predictor: every 24 hours (288 iterations * 5 min) # - supervisor: every SUPERVISOR_INTERVAL seconds (default: 1200 = 20 min) +# ── Migration check: reject ENABLE_LLAMA_AGENT ─────────────────────────────── +# #846: The legacy ENABLE_LLAMA_AGENT env flag is no longer supported. +# Activation is now done exclusively via [agents.X] sections in project TOML. +# If this legacy flag is detected, fail immediately with a migration message. +if [ "${ENABLE_LLAMA_AGENT:-}" = "1" ]; then + cat <<'MIGRATION_ERR' +FATAL: ENABLE_LLAMA_AGENT is no longer supported. + +The legacy ENABLE_LLAMA_AGENT=1 flag has been removed (#846). +Activation is now done exclusively via [agents.X] sections in projects/*.toml. + +To migrate: + 1. Remove ENABLE_LLAMA_AGENT from your .env or .env.enc file + 2. Add an [agents.] section to your project TOML: + + [agents.dev-qwen] + base_url = "http://your-llama-server:8081" + model = "unsloth/Qwen3.5-35B-A3B" + api_key = "sk-no-key-required" + roles = ["dev"] + forge_user = "dev-qwen" + compact_pct = 60 + poll_interval = 60 + + 3. Run: disinto init + 4. Start the agent: docker compose up -d agents-dev-qwen + +See docs/agents-llama.md for full details. +MIGRATION_ERR + exit 1 +fi + DISINTO_BAKED="/home/agent/disinto" DISINTO_LIVE="/home/agent/repos/_factory" DISINTO_DIR="$DISINTO_BAKED" # start with baked copy; switched to live checkout after bootstrap diff --git a/docs/agents-llama.md b/docs/agents-llama.md index bc973b7..b3a1334 100644 --- a/docs/agents-llama.md +++ b/docs/agents-llama.md @@ -2,9 +2,12 @@ Local-model agents run the same agent code as the Claude-backed agents, but connect to a local llama-server (or compatible OpenAI-API endpoint) instead of -the Anthropic API. This document describes the current activation flow using +the Anthropic API. This document describes the canonical activation flow using `disinto hire-an-agent` and `[agents.X]` TOML configuration. +> **Note:** The legacy `ENABLE_LLAMA_AGENT=1` env flag has been removed (#846). +> Activation is now done exclusively via `[agents.X]` sections in project TOML. + ## Overview Local-model agents are configured via `[agents.]` sections in diff --git a/lib/forge-setup.sh b/lib/forge-setup.sh index 2b7b697..2f8b117 100644 --- a/lib/forge-setup.sh +++ b/lib/forge-setup.sh @@ -356,16 +356,6 @@ setup_forge() { [predictor-bot]="FORGE_PREDICTOR_PASS" [architect-bot]="FORGE_ARCHITECT_PASS" ) - # Llama bot users (local-model agents) — separate from main agents - # Each llama agent gets its own Forgejo user, token, and password - local -A llama_token_vars=( - [dev-qwen]="FORGE_TOKEN_LLAMA" - [dev-qwen-nightly]="FORGE_TOKEN_LLAMA_NIGHTLY" - ) - local -A llama_pass_vars=( - [dev-qwen]="FORGE_PASS_LLAMA" - [dev-qwen-nightly]="FORGE_PASS_LLAMA_NIGHTLY" - ) local bot_user bot_pass token token_var pass_var @@ -515,159 +505,12 @@ setup_forge() { fi done - # Create llama bot users and tokens (local-model agents) - # These are separate from the main agents and get their own credentials - echo "" - echo "── Setting up llama bot users ────────────────────────────" - - local llama_user llama_pass llama_token llama_token_var llama_pass_var - for llama_user in "${!llama_token_vars[@]}"; do - llama_token_var="${llama_token_vars[$llama_user]}" - llama_pass_var="${llama_pass_vars[$llama_user]}" - - # Check if token already exists in .env - local token_exists=false - if _token_exists_in_env "$llama_token_var" "$env_file"; then - token_exists=true - fi - - # Check if password already exists in .env - local pass_exists=false - if _pass_exists_in_env "$llama_pass_var" "$env_file"; then - pass_exists=true - fi - - # Check if llama bot user exists on Forgejo - local llama_user_exists=false - if curl -sf --max-time 5 \ - -H "Authorization: token ${admin_token}" \ - "${forge_url}/api/v1/users/${llama_user}" >/dev/null 2>&1; then - llama_user_exists=true - fi - - # Skip token/password regeneration if both exist in .env and not forcing rotation - if [ "$token_exists" = true ] && [ "$pass_exists" = true ] && [ "$rotate_tokens" = false ]; then - echo " ${llama_user} token and password preserved (use --rotate-tokens to force)" - # Still export the existing token for use within this run - local existing_token existing_pass - existing_token=$(grep "^${llama_token_var}=" "$env_file" | head -1 | cut -d= -f2-) - existing_pass=$(grep "^${llama_pass_var}=" "$env_file" | head -1 | cut -d= -f2-) - export "${llama_token_var}=${existing_token}" - export "${llama_pass_var}=${existing_pass}" - continue - fi - - # Generate new credentials if: - # - Token doesn't exist (first run) - # - Password doesn't exist (first run) - # - --rotate-tokens flag is set (explicit rotation) - if [ "$llama_user_exists" = false ]; then - # User doesn't exist - create it - llama_pass="llama-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)" - echo "Creating llama bot user: ${llama_user}" - local create_output - if ! create_output=$(_forgejo_exec forgejo admin user create \ - --username "${llama_user}" \ - --password "${llama_pass}" \ - --email "${llama_user}@disinto.local" \ - --must-change-password=false 2>&1); then - echo "Error: failed to create llama bot user '${llama_user}':" >&2 - echo " ${create_output}" >&2 - exit 1 - fi - # Forgejo 11.x ignores --must-change-password=false on create; - # explicitly clear the flag so basic-auth token creation works. - _forgejo_exec forgejo admin user change-password \ - --username "${llama_user}" \ - --password "${llama_pass}" \ - --must-change-password=false - - # Verify llama bot user was actually created - if ! curl -sf --max-time 5 \ - -H "Authorization: token ${admin_token}" \ - "${forge_url}/api/v1/users/${llama_user}" >/dev/null 2>&1; then - echo "Error: llama bot user '${llama_user}' not found after creation" >&2 - exit 1 - fi - echo " ${llama_user} user created" - else - # User exists - reset password if needed - echo " ${llama_user} user exists" - if [ "$rotate_tokens" = true ] || [ "$pass_exists" = false ]; then - llama_pass="llama-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)" - _forgejo_exec forgejo admin user change-password \ - --username "${llama_user}" \ - --password "${llama_pass}" \ - --must-change-password=false || { - echo "Error: failed to reset password for existing llama bot user '${llama_user}'" >&2 - exit 1 - } - echo " ${llama_user} password reset for token generation" - else - # Password exists, get it from .env - llama_pass=$(grep "^${llama_pass_var}=" "$env_file" | head -1 | cut -d= -f2-) - fi - fi - - # Generate token via API (basic auth as the llama user) - # First, delete any existing tokens to avoid name collision - local existing_llama_token_ids - existing_llama_token_ids=$(curl -sf \ - -u "${llama_user}:${llama_pass}" \ - "${forge_url}/api/v1/users/${llama_user}/tokens" 2>/dev/null \ - | jq -r '.[].id // empty' 2>/dev/null) || existing_llama_token_ids="" - - # Delete any existing tokens for this user - if [ -n "$existing_llama_token_ids" ]; then - while IFS= read -r tid; do - [ -n "$tid" ] && curl -sf -X DELETE \ - -u "${llama_user}:${llama_pass}" \ - "${forge_url}/api/v1/users/${llama_user}/tokens/${tid}" >/dev/null 2>&1 || true - done <<< "$existing_llama_token_ids" - fi - - llama_token=$(curl -sf -X POST \ - -u "${llama_user}:${llama_pass}" \ - -H "Content-Type: application/json" \ - "${forge_url}/api/v1/users/${llama_user}/tokens" \ - -d "{\"name\":\"disinto-${llama_user}-token\",\"scopes\":[\"all\"]}" 2>/dev/null \ - | jq -r '.sha1 // empty') || llama_token="" - - if [ -z "$llama_token" ]; then - echo "Error: failed to create API token for '${llama_user}'" >&2 - exit 1 - fi - - # Store token in .env under the llama-specific variable name - if grep -q "^${llama_token_var}=" "$env_file" 2>/dev/null; then - sed -i "s|^${llama_token_var}=.*|${llama_token_var}=${llama_token}|" "$env_file" - else - printf '%s=%s\n' "$llama_token_var" "$llama_token" >> "$env_file" - fi - export "${llama_token_var}=${llama_token}" - echo " ${llama_user} token generated and saved (${llama_token_var})" - - # Store password in .env for git HTTP push (#361) - # Forgejo 11.x API tokens don't work for git push; password auth does. - if grep -q "^${llama_pass_var}=" "$env_file" 2>/dev/null; then - sed -i "s|^${llama_pass_var}=.*|${llama_pass_var}=${llama_pass}|" "$env_file" - else - printf '%s=%s\n' "$llama_pass_var" "$llama_pass" >> "$env_file" - fi - export "${llama_pass_var}=${llama_pass}" - echo " ${llama_user} password saved (${llama_pass_var})" - done - # Create .profile repos for all bot users (if they don't already exist) # This runs the same logic as hire-an-agent Step 2-3 for idempotent setup echo "" echo "── Setting up .profile repos ────────────────────────────" local -a bot_users=(dev-bot review-bot planner-bot gardener-bot vault-bot supervisor-bot predictor-bot architect-bot) - # Add llama bot users to .profile repo creation - for llama_user in "${!llama_token_vars[@]}"; do - bot_users+=("$llama_user") - done local bot_user for bot_user in "${bot_users[@]}"; do @@ -775,15 +618,6 @@ setup_forge() { -d "{\"permission\":\"${bot_perm}\"}" >/dev/null 2>&1 || true done - # Add llama bot users as write collaborators for local-model agents - for llama_user in "${!llama_token_vars[@]}"; do - curl -sf -X PUT \ - -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ - -H "Content-Type: application/json" \ - "${forge_url}/api/v1/repos/${repo_slug}/collaborators/${llama_user}" \ - -d '{"permission":"write"}' >/dev/null 2>&1 || true - done - # Add disinto-admin as admin collaborator curl -sf -X PUT \ -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ diff --git a/lib/generators.sh b/lib/generators.sh index 3f88e39..0df5725 100644 --- a/lib/generators.sh +++ b/lib/generators.sh @@ -438,136 +438,6 @@ services: COMPOSEEOF - # ── Conditional agents-llama block (ENABLE_LLAMA_AGENT=1) ────────────── - # Local-Qwen dev agent — gated on ENABLE_LLAMA_AGENT so factories without - # a local llama endpoint don't try to start it. See docs/agents-llama.md. - if [ "${ENABLE_LLAMA_AGENT:-0}" = "1" ]; then - cat >> "$compose_file" <<'LLAMAEOF' - - agents-llama: - build: - context: . - dockerfile: docker/agents/Dockerfile - # Rebuild on every up (#887): makes docker/agents/ source changes reach this - # container without a manual \`docker compose build\`. Cache-fast when clean. - pull_policy: build - container_name: disinto-agents-llama - restart: unless-stopped - security_opt: - - apparmor=unconfined - volumes: - - agent-data:/home/agent/data - - project-repos:/home/agent/repos - - ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared} - - ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro - - ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro - - ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro - - ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro - - woodpecker-data:/woodpecker-data:ro - environment: - FORGE_URL: http://forgejo:3000 - FORGE_REPO: ${FORGE_REPO:-disinto-admin/disinto} - FORGE_TOKEN: ${FORGE_TOKEN_LLAMA:-} - FORGE_PASS: ${FORGE_PASS_LLAMA:-} - FORGE_BOT_USERNAMES: ${FORGE_BOT_USERNAMES:-} - WOODPECKER_TOKEN: ${WOODPECKER_TOKEN:-} - CLAUDE_TIMEOUT: ${CLAUDE_TIMEOUT:-7200} - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: ${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1} - CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "60" - ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} - ANTHROPIC_BASE_URL: ${ANTHROPIC_BASE_URL:-} - FORGE_ADMIN_PASS: ${FORGE_ADMIN_PASS:-} - DISINTO_CONTAINER: "1" - PROJECT_NAME: ${PROJECT_NAME:-project} - PROJECT_REPO_ROOT: /home/agent/repos/${PROJECT_NAME:-project} - WOODPECKER_DATA_DIR: /woodpecker-data - WOODPECKER_REPO_ID: "PLACEHOLDER_WP_REPO_ID" - CLAUDE_CONFIG_DIR: ${CLAUDE_CONFIG_DIR:-/var/lib/disinto/claude-shared/config} - POLL_INTERVAL: ${POLL_INTERVAL:-300} - AGENT_ROLES: dev - healthcheck: - test: ["CMD", "pgrep", "-f", "entrypoint.sh"] - interval: 60s - timeout: 5s - retries: 3 - start_period: 30s - depends_on: - forgejo: - condition: service_healthy - networks: - - disinto-net - - agents-llama-all: - build: - context: . - dockerfile: docker/agents/Dockerfile - # Rebuild on every up (#887): makes docker/agents/ source changes reach this - # container without a manual \`docker compose build\`. Cache-fast when clean. - pull_policy: build - container_name: disinto-agents-llama-all - restart: unless-stopped - profiles: ["agents-llama-all"] - security_opt: - - apparmor=unconfined - volumes: - - agent-data:/home/agent/data - - project-repos:/home/agent/repos - - ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared} - - ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro - - ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro - - ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro - - ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro - - woodpecker-data:/woodpecker-data:ro - environment: - FORGE_URL: http://forgejo:3000 - FORGE_REPO: ${FORGE_REPO:-disinto-admin/disinto} - FORGE_TOKEN: ${FORGE_TOKEN_LLAMA:-} - FORGE_PASS: ${FORGE_PASS_LLAMA:-} - FORGE_REVIEW_TOKEN: ${FORGE_REVIEW_TOKEN:-} - FORGE_PLANNER_TOKEN: ${FORGE_PLANNER_TOKEN:-} - FORGE_GARDENER_TOKEN: ${FORGE_GARDENER_TOKEN:-} - FORGE_VAULT_TOKEN: ${FORGE_VAULT_TOKEN:-} - FORGE_SUPERVISOR_TOKEN: ${FORGE_SUPERVISOR_TOKEN:-} - FORGE_PREDICTOR_TOKEN: ${FORGE_PREDICTOR_TOKEN:-} - FORGE_ARCHITECT_TOKEN: ${FORGE_ARCHITECT_TOKEN:-} - FORGE_FILER_TOKEN: ${FORGE_FILER_TOKEN:-} - FORGE_BOT_USERNAMES: ${FORGE_BOT_USERNAMES:-} - WOODPECKER_TOKEN: ${WOODPECKER_TOKEN:-} - CLAUDE_TIMEOUT: ${CLAUDE_TIMEOUT:-7200} - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: ${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1} - CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "60" - CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1" - ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} - ANTHROPIC_BASE_URL: ${ANTHROPIC_BASE_URL:-} - FORGE_ADMIN_PASS: ${FORGE_ADMIN_PASS:-} - DISINTO_CONTAINER: "1" - PROJECT_NAME: ${PROJECT_NAME:-project} - PROJECT_REPO_ROOT: /home/agent/repos/${PROJECT_NAME:-project} - WOODPECKER_DATA_DIR: /woodpecker-data - WOODPECKER_REPO_ID: "PLACEHOLDER_WP_REPO_ID" - CLAUDE_CONFIG_DIR: ${CLAUDE_CONFIG_DIR:-/var/lib/disinto/claude-shared/config} - POLL_INTERVAL: ${POLL_INTERVAL:-300} - GARDENER_INTERVAL: ${GARDENER_INTERVAL:-21600} - ARCHITECT_INTERVAL: ${ARCHITECT_INTERVAL:-21600} - PLANNER_INTERVAL: ${PLANNER_INTERVAL:-43200} - SUPERVISOR_INTERVAL: ${SUPERVISOR_INTERVAL:-1200} - AGENT_ROLES: review,dev,gardener,architect,planner,predictor,supervisor - healthcheck: - test: ["CMD", "pgrep", "-f", "entrypoint.sh"] - interval: 60s - timeout: 5s - retries: 3 - start_period: 30s - depends_on: - forgejo: - condition: service_healthy - woodpecker: - condition: service_started - networks: - - disinto-net -LLAMAEOF - fi - # Resume the rest of the compose file (runner onward) cat >> "$compose_file" <<'COMPOSEEOF' From 28eb182487c3f9ad2fe4918f7c0390a090adb583 Mon Sep 17 00:00:00 2001 From: dev-qwen2 Date: Thu, 16 Apr 2026 18:40:35 +0000 Subject: [PATCH 3/4] fix: Two parallel activation paths for llama agents (ENABLE_LLAMA_AGENT vs [agents.X] TOML) (#846) --- .env.example | 14 +-- bin/disinto | 14 --- docker/agents/entrypoint.sh | 32 +++++++ docs/agents-llama.md | 5 +- lib/forge-setup.sh | 166 ------------------------------------ lib/generators.sh | 130 ---------------------------- 6 files changed, 38 insertions(+), 323 deletions(-) diff --git a/.env.example b/.env.example index c1c0b98..a1f24d5 100644 --- a/.env.example +++ b/.env.example @@ -32,13 +32,10 @@ FORGE_URL=http://localhost:3000 # [CONFIG] local Forgejo instance # - FORGE_PASS_DEV_QWEN2 # Name conversion: tr 'a-z-' 'A-Z_' (lowercase→UPPER, hyphens→underscores). # The compose generator looks these up via the agent's `forge_user` field in -# the project TOML. The pre-existing `dev-qwen` llama agent uses -# FORGE_TOKEN_LLAMA / FORGE_PASS_LLAMA (kept for backwards-compat with the -# legacy `ENABLE_LLAMA_AGENT=1` single-agent path). +# the project TOML. Configure local-model agents via [agents.X] sections in +# projects/*.toml — this is the canonical activation path. FORGE_TOKEN= # [SECRET] dev-bot API token (default for all agents) FORGE_PASS= # [SECRET] dev-bot password for git HTTP push (#361) -FORGE_TOKEN_LLAMA= # [SECRET] dev-qwen API token (for agents-llama) -FORGE_PASS_LLAMA= # [SECRET] dev-qwen password for git HTTP push FORGE_REVIEW_TOKEN= # [SECRET] review-bot API token FORGE_REVIEW_PASS= # [SECRET] review-bot password for git HTTP push FORGE_PLANNER_TOKEN= # [SECRET] planner-bot API token @@ -107,13 +104,6 @@ FORWARD_AUTH_SECRET= # [SECRET] Shared secret for Caddy ↔ # Store all project secrets here so formulas reference env vars, never hardcode. BASE_RPC_URL= # [SECRET] on-chain RPC endpoint -# ── Local Qwen dev agent (optional) ────────────────────────────────────── -# Set ENABLE_LLAMA_AGENT=1 to emit agents-llama in docker-compose.yml. -# Requires a running llama-server reachable at ANTHROPIC_BASE_URL. -# See docs/agents-llama.md for details. -ENABLE_LLAMA_AGENT=0 # [CONFIG] 1 = enable agents-llama service -ANTHROPIC_BASE_URL= # [CONFIG] e.g. http://host.docker.internal:8081 - # ── Tuning ──────────────────────────────────────────────────────────────── CLAUDE_TIMEOUT=7200 # [CONFIG] max seconds per Claude invocation diff --git a/bin/disinto b/bin/disinto index 6128b7c..c6c2421 100755 --- a/bin/disinto +++ b/bin/disinto @@ -977,7 +977,6 @@ p.write_text(text) echo "" echo "[ensure] Forgejo admin user 'disinto-admin'" echo "[ensure] 8 bot users: dev-bot, review-bot, planner-bot, gardener-bot, vault-bot, supervisor-bot, predictor-bot, architect-bot" - echo "[ensure] 2 llama bot users: dev-qwen, dev-qwen-nightly" echo "[ensure] .profile repos for all bots" echo "[ensure] repo ${forge_repo} on Forgejo with collaborators" echo "[run] preflight checks" @@ -1173,19 +1172,6 @@ p.write_text(text) echo "Config: CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 saved to .env" fi - # Write local-Qwen dev agent env keys with safe defaults (#769) - if ! grep -q '^ENABLE_LLAMA_AGENT=' "$env_file" 2>/dev/null; then - cat >> "$env_file" <<'LLAMAENVEOF' - -# Local Qwen dev agent (optional) — set to 1 to enable -ENABLE_LLAMA_AGENT=0 -FORGE_TOKEN_LLAMA= -FORGE_PASS_LLAMA= -ANTHROPIC_BASE_URL= -LLAMAENVEOF - echo "Config: ENABLE_LLAMA_AGENT keys written to .env (disabled by default)" - fi - # Create labels on remote create_labels "$forge_repo" "$forge_url" diff --git a/docker/agents/entrypoint.sh b/docker/agents/entrypoint.sh index f838c15..7c58674 100644 --- a/docker/agents/entrypoint.sh +++ b/docker/agents/entrypoint.sh @@ -17,6 +17,38 @@ set -euo pipefail # - predictor: every 24 hours (288 iterations * 5 min) # - supervisor: every SUPERVISOR_INTERVAL seconds (default: 1200 = 20 min) +# ── Migration check: reject ENABLE_LLAMA_AGENT ─────────────────────────────── +# #846: The legacy ENABLE_LLAMA_AGENT env flag is no longer supported. +# Activation is now done exclusively via [agents.X] sections in project TOML. +# If this legacy flag is detected, fail immediately with a migration message. +if [ "${ENABLE_LLAMA_AGENT:-}" = "1" ]; then + cat <<'MIGRATION_ERR' +FATAL: ENABLE_LLAMA_AGENT is no longer supported. + +The legacy ENABLE_LLAMA_AGENT=1 flag has been removed (#846). +Activation is now done exclusively via [agents.X] sections in projects/*.toml. + +To migrate: + 1. Remove ENABLE_LLAMA_AGENT from your .env or .env.enc file + 2. Add an [agents.] section to your project TOML: + + [agents.dev-qwen] + base_url = "http://your-llama-server:8081" + model = "unsloth/Qwen3.5-35B-A3B" + api_key = "sk-no-key-required" + roles = ["dev"] + forge_user = "dev-qwen" + compact_pct = 60 + poll_interval = 60 + + 3. Run: disinto init + 4. Start the agent: docker compose up -d agents-dev-qwen + +See docs/agents-llama.md for full details. +MIGRATION_ERR + exit 1 +fi + DISINTO_BAKED="/home/agent/disinto" DISINTO_LIVE="/home/agent/repos/_factory" DISINTO_DIR="$DISINTO_BAKED" # start with baked copy; switched to live checkout after bootstrap diff --git a/docs/agents-llama.md b/docs/agents-llama.md index bc973b7..b3a1334 100644 --- a/docs/agents-llama.md +++ b/docs/agents-llama.md @@ -2,9 +2,12 @@ Local-model agents run the same agent code as the Claude-backed agents, but connect to a local llama-server (or compatible OpenAI-API endpoint) instead of -the Anthropic API. This document describes the current activation flow using +the Anthropic API. This document describes the canonical activation flow using `disinto hire-an-agent` and `[agents.X]` TOML configuration. +> **Note:** The legacy `ENABLE_LLAMA_AGENT=1` env flag has been removed (#846). +> Activation is now done exclusively via `[agents.X]` sections in project TOML. + ## Overview Local-model agents are configured via `[agents.]` sections in diff --git a/lib/forge-setup.sh b/lib/forge-setup.sh index 2b7b697..2f8b117 100644 --- a/lib/forge-setup.sh +++ b/lib/forge-setup.sh @@ -356,16 +356,6 @@ setup_forge() { [predictor-bot]="FORGE_PREDICTOR_PASS" [architect-bot]="FORGE_ARCHITECT_PASS" ) - # Llama bot users (local-model agents) — separate from main agents - # Each llama agent gets its own Forgejo user, token, and password - local -A llama_token_vars=( - [dev-qwen]="FORGE_TOKEN_LLAMA" - [dev-qwen-nightly]="FORGE_TOKEN_LLAMA_NIGHTLY" - ) - local -A llama_pass_vars=( - [dev-qwen]="FORGE_PASS_LLAMA" - [dev-qwen-nightly]="FORGE_PASS_LLAMA_NIGHTLY" - ) local bot_user bot_pass token token_var pass_var @@ -515,159 +505,12 @@ setup_forge() { fi done - # Create llama bot users and tokens (local-model agents) - # These are separate from the main agents and get their own credentials - echo "" - echo "── Setting up llama bot users ────────────────────────────" - - local llama_user llama_pass llama_token llama_token_var llama_pass_var - for llama_user in "${!llama_token_vars[@]}"; do - llama_token_var="${llama_token_vars[$llama_user]}" - llama_pass_var="${llama_pass_vars[$llama_user]}" - - # Check if token already exists in .env - local token_exists=false - if _token_exists_in_env "$llama_token_var" "$env_file"; then - token_exists=true - fi - - # Check if password already exists in .env - local pass_exists=false - if _pass_exists_in_env "$llama_pass_var" "$env_file"; then - pass_exists=true - fi - - # Check if llama bot user exists on Forgejo - local llama_user_exists=false - if curl -sf --max-time 5 \ - -H "Authorization: token ${admin_token}" \ - "${forge_url}/api/v1/users/${llama_user}" >/dev/null 2>&1; then - llama_user_exists=true - fi - - # Skip token/password regeneration if both exist in .env and not forcing rotation - if [ "$token_exists" = true ] && [ "$pass_exists" = true ] && [ "$rotate_tokens" = false ]; then - echo " ${llama_user} token and password preserved (use --rotate-tokens to force)" - # Still export the existing token for use within this run - local existing_token existing_pass - existing_token=$(grep "^${llama_token_var}=" "$env_file" | head -1 | cut -d= -f2-) - existing_pass=$(grep "^${llama_pass_var}=" "$env_file" | head -1 | cut -d= -f2-) - export "${llama_token_var}=${existing_token}" - export "${llama_pass_var}=${existing_pass}" - continue - fi - - # Generate new credentials if: - # - Token doesn't exist (first run) - # - Password doesn't exist (first run) - # - --rotate-tokens flag is set (explicit rotation) - if [ "$llama_user_exists" = false ]; then - # User doesn't exist - create it - llama_pass="llama-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)" - echo "Creating llama bot user: ${llama_user}" - local create_output - if ! create_output=$(_forgejo_exec forgejo admin user create \ - --username "${llama_user}" \ - --password "${llama_pass}" \ - --email "${llama_user}@disinto.local" \ - --must-change-password=false 2>&1); then - echo "Error: failed to create llama bot user '${llama_user}':" >&2 - echo " ${create_output}" >&2 - exit 1 - fi - # Forgejo 11.x ignores --must-change-password=false on create; - # explicitly clear the flag so basic-auth token creation works. - _forgejo_exec forgejo admin user change-password \ - --username "${llama_user}" \ - --password "${llama_pass}" \ - --must-change-password=false - - # Verify llama bot user was actually created - if ! curl -sf --max-time 5 \ - -H "Authorization: token ${admin_token}" \ - "${forge_url}/api/v1/users/${llama_user}" >/dev/null 2>&1; then - echo "Error: llama bot user '${llama_user}' not found after creation" >&2 - exit 1 - fi - echo " ${llama_user} user created" - else - # User exists - reset password if needed - echo " ${llama_user} user exists" - if [ "$rotate_tokens" = true ] || [ "$pass_exists" = false ]; then - llama_pass="llama-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)" - _forgejo_exec forgejo admin user change-password \ - --username "${llama_user}" \ - --password "${llama_pass}" \ - --must-change-password=false || { - echo "Error: failed to reset password for existing llama bot user '${llama_user}'" >&2 - exit 1 - } - echo " ${llama_user} password reset for token generation" - else - # Password exists, get it from .env - llama_pass=$(grep "^${llama_pass_var}=" "$env_file" | head -1 | cut -d= -f2-) - fi - fi - - # Generate token via API (basic auth as the llama user) - # First, delete any existing tokens to avoid name collision - local existing_llama_token_ids - existing_llama_token_ids=$(curl -sf \ - -u "${llama_user}:${llama_pass}" \ - "${forge_url}/api/v1/users/${llama_user}/tokens" 2>/dev/null \ - | jq -r '.[].id // empty' 2>/dev/null) || existing_llama_token_ids="" - - # Delete any existing tokens for this user - if [ -n "$existing_llama_token_ids" ]; then - while IFS= read -r tid; do - [ -n "$tid" ] && curl -sf -X DELETE \ - -u "${llama_user}:${llama_pass}" \ - "${forge_url}/api/v1/users/${llama_user}/tokens/${tid}" >/dev/null 2>&1 || true - done <<< "$existing_llama_token_ids" - fi - - llama_token=$(curl -sf -X POST \ - -u "${llama_user}:${llama_pass}" \ - -H "Content-Type: application/json" \ - "${forge_url}/api/v1/users/${llama_user}/tokens" \ - -d "{\"name\":\"disinto-${llama_user}-token\",\"scopes\":[\"all\"]}" 2>/dev/null \ - | jq -r '.sha1 // empty') || llama_token="" - - if [ -z "$llama_token" ]; then - echo "Error: failed to create API token for '${llama_user}'" >&2 - exit 1 - fi - - # Store token in .env under the llama-specific variable name - if grep -q "^${llama_token_var}=" "$env_file" 2>/dev/null; then - sed -i "s|^${llama_token_var}=.*|${llama_token_var}=${llama_token}|" "$env_file" - else - printf '%s=%s\n' "$llama_token_var" "$llama_token" >> "$env_file" - fi - export "${llama_token_var}=${llama_token}" - echo " ${llama_user} token generated and saved (${llama_token_var})" - - # Store password in .env for git HTTP push (#361) - # Forgejo 11.x API tokens don't work for git push; password auth does. - if grep -q "^${llama_pass_var}=" "$env_file" 2>/dev/null; then - sed -i "s|^${llama_pass_var}=.*|${llama_pass_var}=${llama_pass}|" "$env_file" - else - printf '%s=%s\n' "$llama_pass_var" "$llama_pass" >> "$env_file" - fi - export "${llama_pass_var}=${llama_pass}" - echo " ${llama_user} password saved (${llama_pass_var})" - done - # Create .profile repos for all bot users (if they don't already exist) # This runs the same logic as hire-an-agent Step 2-3 for idempotent setup echo "" echo "── Setting up .profile repos ────────────────────────────" local -a bot_users=(dev-bot review-bot planner-bot gardener-bot vault-bot supervisor-bot predictor-bot architect-bot) - # Add llama bot users to .profile repo creation - for llama_user in "${!llama_token_vars[@]}"; do - bot_users+=("$llama_user") - done local bot_user for bot_user in "${bot_users[@]}"; do @@ -775,15 +618,6 @@ setup_forge() { -d "{\"permission\":\"${bot_perm}\"}" >/dev/null 2>&1 || true done - # Add llama bot users as write collaborators for local-model agents - for llama_user in "${!llama_token_vars[@]}"; do - curl -sf -X PUT \ - -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ - -H "Content-Type: application/json" \ - "${forge_url}/api/v1/repos/${repo_slug}/collaborators/${llama_user}" \ - -d '{"permission":"write"}' >/dev/null 2>&1 || true - done - # Add disinto-admin as admin collaborator curl -sf -X PUT \ -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ diff --git a/lib/generators.sh b/lib/generators.sh index 3f88e39..0df5725 100644 --- a/lib/generators.sh +++ b/lib/generators.sh @@ -438,136 +438,6 @@ services: COMPOSEEOF - # ── Conditional agents-llama block (ENABLE_LLAMA_AGENT=1) ────────────── - # Local-Qwen dev agent — gated on ENABLE_LLAMA_AGENT so factories without - # a local llama endpoint don't try to start it. See docs/agents-llama.md. - if [ "${ENABLE_LLAMA_AGENT:-0}" = "1" ]; then - cat >> "$compose_file" <<'LLAMAEOF' - - agents-llama: - build: - context: . - dockerfile: docker/agents/Dockerfile - # Rebuild on every up (#887): makes docker/agents/ source changes reach this - # container without a manual \`docker compose build\`. Cache-fast when clean. - pull_policy: build - container_name: disinto-agents-llama - restart: unless-stopped - security_opt: - - apparmor=unconfined - volumes: - - agent-data:/home/agent/data - - project-repos:/home/agent/repos - - ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared} - - ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro - - ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro - - ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro - - ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro - - woodpecker-data:/woodpecker-data:ro - environment: - FORGE_URL: http://forgejo:3000 - FORGE_REPO: ${FORGE_REPO:-disinto-admin/disinto} - FORGE_TOKEN: ${FORGE_TOKEN_LLAMA:-} - FORGE_PASS: ${FORGE_PASS_LLAMA:-} - FORGE_BOT_USERNAMES: ${FORGE_BOT_USERNAMES:-} - WOODPECKER_TOKEN: ${WOODPECKER_TOKEN:-} - CLAUDE_TIMEOUT: ${CLAUDE_TIMEOUT:-7200} - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: ${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1} - CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "60" - ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} - ANTHROPIC_BASE_URL: ${ANTHROPIC_BASE_URL:-} - FORGE_ADMIN_PASS: ${FORGE_ADMIN_PASS:-} - DISINTO_CONTAINER: "1" - PROJECT_NAME: ${PROJECT_NAME:-project} - PROJECT_REPO_ROOT: /home/agent/repos/${PROJECT_NAME:-project} - WOODPECKER_DATA_DIR: /woodpecker-data - WOODPECKER_REPO_ID: "PLACEHOLDER_WP_REPO_ID" - CLAUDE_CONFIG_DIR: ${CLAUDE_CONFIG_DIR:-/var/lib/disinto/claude-shared/config} - POLL_INTERVAL: ${POLL_INTERVAL:-300} - AGENT_ROLES: dev - healthcheck: - test: ["CMD", "pgrep", "-f", "entrypoint.sh"] - interval: 60s - timeout: 5s - retries: 3 - start_period: 30s - depends_on: - forgejo: - condition: service_healthy - networks: - - disinto-net - - agents-llama-all: - build: - context: . - dockerfile: docker/agents/Dockerfile - # Rebuild on every up (#887): makes docker/agents/ source changes reach this - # container without a manual \`docker compose build\`. Cache-fast when clean. - pull_policy: build - container_name: disinto-agents-llama-all - restart: unless-stopped - profiles: ["agents-llama-all"] - security_opt: - - apparmor=unconfined - volumes: - - agent-data:/home/agent/data - - project-repos:/home/agent/repos - - ${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared}:${CLAUDE_SHARED_DIR:-/var/lib/disinto/claude-shared} - - ${CLAUDE_CONFIG_FILE:-${HOME}/.claude.json}:/home/agent/.claude.json:ro - - ${CLAUDE_BIN_DIR}:/usr/local/bin/claude:ro - - ${AGENT_SSH_DIR:-${HOME}/.ssh}:/home/agent/.ssh:ro - - ${SOPS_AGE_DIR:-${HOME}/.config/sops/age}:/home/agent/.config/sops/age:ro - - woodpecker-data:/woodpecker-data:ro - environment: - FORGE_URL: http://forgejo:3000 - FORGE_REPO: ${FORGE_REPO:-disinto-admin/disinto} - FORGE_TOKEN: ${FORGE_TOKEN_LLAMA:-} - FORGE_PASS: ${FORGE_PASS_LLAMA:-} - FORGE_REVIEW_TOKEN: ${FORGE_REVIEW_TOKEN:-} - FORGE_PLANNER_TOKEN: ${FORGE_PLANNER_TOKEN:-} - FORGE_GARDENER_TOKEN: ${FORGE_GARDENER_TOKEN:-} - FORGE_VAULT_TOKEN: ${FORGE_VAULT_TOKEN:-} - FORGE_SUPERVISOR_TOKEN: ${FORGE_SUPERVISOR_TOKEN:-} - FORGE_PREDICTOR_TOKEN: ${FORGE_PREDICTOR_TOKEN:-} - FORGE_ARCHITECT_TOKEN: ${FORGE_ARCHITECT_TOKEN:-} - FORGE_FILER_TOKEN: ${FORGE_FILER_TOKEN:-} - FORGE_BOT_USERNAMES: ${FORGE_BOT_USERNAMES:-} - WOODPECKER_TOKEN: ${WOODPECKER_TOKEN:-} - CLAUDE_TIMEOUT: ${CLAUDE_TIMEOUT:-7200} - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: ${CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:-1} - CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "60" - CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1" - ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} - ANTHROPIC_BASE_URL: ${ANTHROPIC_BASE_URL:-} - FORGE_ADMIN_PASS: ${FORGE_ADMIN_PASS:-} - DISINTO_CONTAINER: "1" - PROJECT_NAME: ${PROJECT_NAME:-project} - PROJECT_REPO_ROOT: /home/agent/repos/${PROJECT_NAME:-project} - WOODPECKER_DATA_DIR: /woodpecker-data - WOODPECKER_REPO_ID: "PLACEHOLDER_WP_REPO_ID" - CLAUDE_CONFIG_DIR: ${CLAUDE_CONFIG_DIR:-/var/lib/disinto/claude-shared/config} - POLL_INTERVAL: ${POLL_INTERVAL:-300} - GARDENER_INTERVAL: ${GARDENER_INTERVAL:-21600} - ARCHITECT_INTERVAL: ${ARCHITECT_INTERVAL:-21600} - PLANNER_INTERVAL: ${PLANNER_INTERVAL:-43200} - SUPERVISOR_INTERVAL: ${SUPERVISOR_INTERVAL:-1200} - AGENT_ROLES: review,dev,gardener,architect,planner,predictor,supervisor - healthcheck: - test: ["CMD", "pgrep", "-f", "entrypoint.sh"] - interval: 60s - timeout: 5s - retries: 3 - start_period: 30s - depends_on: - forgejo: - condition: service_healthy - woodpecker: - condition: service_started - networks: - - disinto-net -LLAMAEOF - fi - # Resume the rest of the compose file (runner onward) cat >> "$compose_file" <<'COMPOSEEOF' From e003829eaa444b2a5802a9f2a9ac8e88261fc863 Mon Sep 17 00:00:00 2001 From: dev-qwen2 Date: Thu, 16 Apr 2026 19:05:43 +0000 Subject: [PATCH 4/4] fix: Remove agents-llama service references from docs and formulas (#846) - AGENTS.md: Replace agents-llama and agents-llama-all rows with generic 'Local-model agents' entry pointing to docs/agents-llama.md - formulas/release.sh: Remove agents-llama from docker compose stop/up commands (line 181-182) - formulas/release.toml: Remove agents-llama references from restart-agents step description (lines 192, 195, 206) These changes complete the removal of the legacy ENABLE_LLAMA_AGENT activation path. The release formula now only references the 'agents' service, which is the only service that exists after disinto init regenerates docker-compose.yml based on [agents.X] TOML sections. --- AGENTS.md | 3 +-- formulas/release.sh | 4 ++-- formulas/release.toml | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ef5f00d..ad3867b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -122,8 +122,7 @@ bash dev/phase-test.sh | Reproduce | `docker/reproduce/` | Bug reproduction using Playwright MCP | `formulas/reproduce.toml` | | Triage | `docker/reproduce/` | Deep root cause analysis | `formulas/triage.toml` | | Edge dispatcher | `docker/edge/` | Polls ops repo for vault actions, executes via Claude sessions | `docker/edge/dispatcher.sh` | -| agents-llama | `docker/agents/` (same image) | Local-Qwen dev agent (`AGENT_ROLES=dev`), gated on `ENABLE_LLAMA_AGENT=1` | [docs/agents-llama.md](docs/agents-llama.md) | -| agents-llama-all | `docker/agents/` (same image) | Local-Qwen all-roles agent (all 7 roles), profile `agents-llama-all` | [docs/agents-llama.md](docs/agents-llama.md) | +| Local-model agents | `docker/agents/` (same image) | Local llama-server agents configured via `[agents.X]` sections in project TOML | [docs/agents-llama.md](docs/agents-llama.md) | > **Vault:** Being redesigned as a PR-based approval workflow (issues #73-#77). > See [docs/VAULT.md](docs/VAULT.md) for the vault PR workflow details. diff --git a/formulas/release.sh b/formulas/release.sh index b8c4eb6..6526d1a 100644 --- a/formulas/release.sh +++ b/formulas/release.sh @@ -178,8 +178,8 @@ log "Tagged disinto/agents:${RELEASE_VERSION}" log "Step 6/6: Restarting agent containers" -docker compose stop agents agents-llama 2>/dev/null || true -docker compose up -d agents agents-llama +docker compose stop agents 2>/dev/null || true +docker compose up -d agents log "Agent containers restarted" # ── Done ───────────────────────────────────────────────────────────────── diff --git a/formulas/release.toml b/formulas/release.toml index f702f42..ccd7f95 100644 --- a/formulas/release.toml +++ b/formulas/release.toml @@ -189,10 +189,10 @@ Restart agent containers to use the new image. - docker compose pull agents 2. Stop and remove existing agent containers: - - docker compose down agents agents-llama 2>/dev/null || true + - docker compose down agents 3. Start agents with new image: - - docker compose up -d agents agents-llama + - docker compose up -d agents 4. Wait for containers to be healthy: - for i in {1..30}; do @@ -203,7 +203,7 @@ Restart agent containers to use the new image. - done 5. Verify containers are running: - - docker compose ps agents agents-llama + - docker compose ps agents 6. Log restart: - echo "Restarted agents containers"