From 99adbc9fb50bf21e8c95394545e0b5cc946d9897 Mon Sep 17 00:00:00 2001 From: Agent Date: Fri, 3 Apr 2026 08:19:51 +0000 Subject: [PATCH 1/4] fix: feat: hire-an-agent should support --local-model to auto-configure llama agents (#182) --- bin/disinto | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/bin/disinto b/bin/disinto index aaa8473..74e37f5 100755 --- a/bin/disinto +++ b/bin/disinto @@ -2569,10 +2569,12 @@ disinto_hire_an_agent() { local agent_name="${1:-}" local role="${2:-}" local formula_path="" + local local_model="" + local poll_interval="" if [ -z "$agent_name" ] || [ -z "$role" ]; then echo "Error: agent-name and role required" >&2 - echo "Usage: disinto hire-an-agent [--formula ]" >&2 + echo "Usage: disinto hire-an-agent [--formula ] [--local-model ] [--poll-interval ]" >&2 exit 1 fi shift 2 @@ -2584,6 +2586,14 @@ disinto_hire_an_agent() { formula_path="$2" shift 2 ;; + --local-model) + local_model="$2" + shift 2 + ;; + --poll-interval) + poll_interval="$2" + shift 2 + ;; *) echo "Unknown option: $1" >&2 exit 1 @@ -2604,6 +2614,10 @@ disinto_hire_an_agent() { echo "── Hiring agent: ${agent_name} (${role}) ───────────────────────" echo "Formula: ${formula_path}" + if [ -n "$local_model" ]; then + echo "Local model: ${local_model}" + echo "Poll interval: ${poll_interval:-300}s" + fi # Ensure FORGE_TOKEN is set if [ -z "${FORGE_TOKEN:-}" ]; then @@ -2859,6 +2873,102 @@ EOF echo " State marker already exists: ${state_file}" fi + # Step 6: Set up local model agent (if --local-model specified) + if [ -n "$local_model" ]; then + echo "" + echo "Step 6: Configuring local model agent..." + + local compose_file="${FACTORY_ROOT}/docker-compose.yml" + local override_file="${FACTORY_ROOT}/docker-compose.override.yml" + local override_dir + override_dir=$(dirname "$override_file") + mkdir -p "$override_dir" + + # Validate model endpoint is reachable + echo " Validating model endpoint: ${local_model}" + if ! curl -sf --max-time 10 "${local_model}/health" >/dev/null 2>&1; then + # Try /v1/chat/completions as fallback endpoint check + if ! curl -sf --max-time 10 "${local_model}/v1/chat/completions" >/dev/null 2>&1; then + echo " Warning: model endpoint may not be reachable at ${local_model}" + echo " Continuing with configuration..." + fi + else + echo " Model endpoint is reachable" + fi + + # Generate service name from agent name (lowercase, replace - with -) + local service_name="agents-${agent_name}" + service_name=$(echo "$service_name" | tr '[:upper:]' '[:lower:]') + + # Set default poll interval + local interval="${poll_interval:-300}" + + # Generate token for the agent (use same token as FORGE_TOKEN for simplicity) + local agent_token="${FORGE_TOKEN}" + + # Generate the override compose file + cat > "$override_file" < Date: Fri, 3 Apr 2026 08:27:52 +0000 Subject: [PATCH 2/4] fix: escape dollar signs in docker-compose override to prevent secret exposure (#182) --- bin/disinto | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/bin/disinto b/bin/disinto index 74e37f5..b937b73 100755 --- a/bin/disinto +++ b/bin/disinto @@ -2896,18 +2896,17 @@ EOF echo " Model endpoint is reachable" fi - # Generate service name from agent name (lowercase, replace - with -) + # Generate service name from agent name (lowercase) local service_name="agents-${agent_name}" service_name=$(echo "$service_name" | tr '[:upper:]' '[:lower:]') # Set default poll interval local interval="${poll_interval:-300}" - # Generate token for the agent (use same token as FORGE_TOKEN for simplicity) - local agent_token="${FORGE_TOKEN}" - # Generate the override compose file - cat > "$override_file" < "$override_file" <<'OVERRIDEOF' # docker-compose.override.yml — auto-generated by disinto hire-an-agent # Local model agent configuration for ${agent_name} @@ -2921,11 +2920,11 @@ services: volumes: - agent-data-llama:/home/agent/data - project-repos-llama:/home/agent/repos - - ${HOME}/.claude:/home/agent/.claude - - ${HOME}/.claude.json:/home/agent/.claude.json:ro + - $${HOME}/.claude:/home/agent/.claude + - $${HOME}/.claude.json:/home/agent/.claude.json:ro - CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro - - ${HOME}/.ssh:/home/agent/.ssh:ro - - ${HOME}/.config/sops/age:/home/agent/.config/sops/age:ro + - $${HOME}/.ssh:/home/agent/.ssh:ro + - $${HOME}/.config/sops/age:/home/agent/.config/sops/age:ro environment: FORGE_URL: http://forgejo:3000 WOODPECKER_SERVER: http://woodpecker:8000 @@ -2934,7 +2933,7 @@ services: WOODPECKER_DATA_DIR: /woodpecker-data ANTHROPIC_BASE_URL: ${local_model} ANTHROPIC_API_KEY: sk-no-key-required - FORGE_TOKEN_OVERRIDE: ${agent_token} + FORGE_TOKEN_OVERRIDE: $${FORGE_TOKEN} CLAUDE_CONFIG_DIR: /home/agent/.claude POLL_INTERVAL: ${interval} env_file: From 554998c6c9b8f5af61d441b62f30a15370795d2e Mon Sep 17 00:00:00 2001 From: Agent Date: Fri, 3 Apr 2026 08:40:32 +0000 Subject: [PATCH 3/4] fix: proper docker-compose variable expansion (bash at gen, compose at runtime) (#182) --- bin/disinto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/disinto b/bin/disinto index b937b73..5ca8f19 100755 --- a/bin/disinto +++ b/bin/disinto @@ -2904,9 +2904,9 @@ EOF local interval="${poll_interval:-300}" # Generate the override compose file - # Note: $${VAR} syntax is used so docker-compose interpolates at runtime, - # not at generation time (AD-005: secrets via env var indirection) - cat > "$override_file" <<'OVERRIDEOF' + # Bash expands ${service_name}, ${local_model}, ${interval}, ${PROJECT_NAME} at generation time + # $${HOME}, $${FORGE_TOKEN} become ${HOME}, ${FORGE_TOKEN} in the file for docker-compose runtime expansion + cat > "$override_file" < Date: Fri, 3 Apr 2026 08:48:24 +0000 Subject: [PATCH 4/4] fix: escape $ signs with backslash for docker-compose runtime interpolation (#182) --- bin/disinto | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/disinto b/bin/disinto index 5ca8f19..dc08953 100755 --- a/bin/disinto +++ b/bin/disinto @@ -2905,7 +2905,7 @@ EOF # Generate the override compose file # Bash expands ${service_name}, ${local_model}, ${interval}, ${PROJECT_NAME} at generation time - # $${HOME}, $${FORGE_TOKEN} become ${HOME}, ${FORGE_TOKEN} in the file for docker-compose runtime expansion + # \$HOME, \$FORGE_TOKEN become ${HOME}, ${FORGE_TOKEN} in the file for docker-compose runtime expansion cat > "$override_file" <