Merge pull request 'fix: feat: hire-an-agent should support --local-model to auto-configure llama agents (#182)' (#183) from fix/issue-182 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
This commit is contained in:
commit
3ca62fa96d
1 changed files with 110 additions and 1 deletions
111
bin/disinto
111
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 <agent-name> <role> [--formula <path>]" >&2
|
||||
echo "Usage: disinto hire-an-agent <agent-name> <role> [--formula <path>] [--local-model <url>] [--poll-interval <seconds>]" >&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,101 @@ 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)
|
||||
local service_name="agents-${agent_name}"
|
||||
service_name=$(echo "$service_name" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# Set default poll interval
|
||||
local interval="${poll_interval:-300}"
|
||||
|
||||
# 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
|
||||
cat > "$override_file" <<OVERRIDEOF
|
||||
# docker-compose.override.yml — auto-generated by disinto hire-an-agent
|
||||
# Local model agent configuration for ${agent_name}
|
||||
|
||||
services:
|
||||
${service_name}:
|
||||
image: disinto-agents:latest
|
||||
profiles: ["local-model"]
|
||||
restart: unless-stopped
|
||||
security_opt:
|
||||
- apparmor=unconfined
|
||||
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
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude: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
|
||||
DISINTO_CONTAINER: "1"
|
||||
PROJECT_REPO_ROOT: /home/agent/repos/${PROJECT_NAME:-project}
|
||||
WOODPECKER_DATA_DIR: /woodpecker-data
|
||||
ANTHROPIC_BASE_URL: ${local_model}
|
||||
ANTHROPIC_API_KEY: sk-no-key-required
|
||||
FORGE_TOKEN_OVERRIDE: \$FORGE_TOKEN
|
||||
CLAUDE_CONFIG_DIR: /home/agent/.claude
|
||||
POLL_INTERVAL: ${interval}
|
||||
env_file:
|
||||
- .env
|
||||
depends_on:
|
||||
- forgejo
|
||||
- woodpecker
|
||||
entrypoint: ["/home/agent/entrypoint-llama.sh"]
|
||||
|
||||
volumes:
|
||||
agent-data-llama:
|
||||
project-repos-llama:
|
||||
OVERRIDEOF
|
||||
|
||||
# Patch the Claude CLI binary path
|
||||
local claude_bin
|
||||
claude_bin="$(command -v claude 2>/dev/null || true)"
|
||||
if [ -n "$claude_bin" ]; then
|
||||
claude_bin="$(readlink -f "$claude_bin")"
|
||||
sed -i "s|CLAUDE_BIN_PLACEHOLDER|${claude_bin}|" "$override_file"
|
||||
else
|
||||
echo " Warning: claude CLI not found — update override file manually"
|
||||
sed -i "s|CLAUDE_BIN_PLACEHOLDER|/usr/local/bin/claude|" "$override_file"
|
||||
fi
|
||||
|
||||
echo " Created: ${override_file}"
|
||||
echo " Service name: ${service_name}"
|
||||
echo " Poll interval: ${interval}s"
|
||||
echo " Model endpoint: ${local_model}"
|
||||
echo ""
|
||||
echo " To start the agent, run:"
|
||||
echo " docker compose --profile local-model up -d ${service_name}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Done! Agent '${agent_name}' hired for role '${role}'."
|
||||
echo " User: ${forge_url}/${agent_name}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue