diff --git a/ngn-agent/setup-ngn-agent.sh b/ngn-agent/setup-ngn-agent.sh index 9b629a7..c038735 100755 --- a/ngn-agent/setup-ngn-agent.sh +++ b/ngn-agent/setup-ngn-agent.sh @@ -208,3 +208,189 @@ backup_config() { echo " → No existing config.yaml to backup" fi } + +# ============================================================================= +# Task 2: Config Generation (D-10) +# ============================================================================= + +# ---- Generate config.yaml ---- +# Uses hermes config set for simple keys, Python yaml or sed for arrays +generate_config_yaml() { + echo " → Generating config.yaml (D-10)..." + + # Scalars via hermes config set + hermes config set terminal.backend docker + hermes config set terminal.docker_image "${DOCKER_IMAGE}" + hermes config set terminal.cwd /workspace + hermes config set terminal.container_memory 5120 + hermes config set terminal.container_disk 51200 + hermes config set terminal.container_cpu 1 + hermes config set terminal.lifetime_seconds 300 + hermes config set memory.provider hindsight + hermes config set terminal.timezone "${TIMEZONE}" + hermes config set telegram.reactions false + hermes config set terminal.docker_env.AWS_REGION us-east-1 + hermes config set terminal.container_persistent true + hermes config set terminal.docker_mount_cwd_to_workspace true + echo " ✓ Scalar config keys set" + + # Complex structures (arrays): try Python yaml first, fall back to sed + if python3 -c "import yaml; import os" 2>/dev/null; then + echo " → Using Python yaml for array structures..." + python3 -c " +import yaml, os + +path = os.path.expanduser('~/.hermes/config.yaml') +with open(path) as f: + config = yaml.safe_load(f) + +ssh_key_1 = '${SSH_KEY_1}' +ssh_key_2 = '${SSH_KEY_2}' +ssh_config = '${SSH_CONFIG}' +ssh_known_hosts = '${SSH_KNOWN_HOSTS}' +repo_ops = '${REPO_OPS}' +repo_deploy = '${REPO_DEPLOY}' +repo_devtools = '${REPO_DEVTOOLS}' +home = os.path.expanduser('~') + +config['terminal']['docker_volumes'] = [ + ssh_key_1 + ':/root/.ssh/id_ed25519razer:ro', + ssh_key_2 + ':/root/.ssh/id_rsa:ro', + ssh_config + ':/root/.ssh/config:ro', + ssh_known_hosts + ':/root/.ssh/known_hosts:ro', + home + '/.aws/config:/root/.aws/config:ro', + home + '/.aws/sso/cache:/root/.aws/sso/cache:rw', + repo_ops + ':/workspace/rai-ops:rw', + repo_deploy + ':/workspace/rai-deployment:rw', + repo_devtools + ':/workspace/rai-devtools:rw', + home + '/.hermes/scripts:/usr/local/bin:ro', +] + +config['terminal']['docker_forward_env'] = ['JIRA_EMAIL', 'JIRA_API_TOKEN', 'DEFAULT_REPOS'] +config['terminal']['shell_init_files'] = ['/usr/local/bin/session-init.sh'] + +with open(path, 'w') as f: + yaml.dump(config, f, default_flow_style=False) +" + echo " ✓ Array structures set via Python yaml" + else + echo " → Python yaml not available, using sed fallback..." + # Fallback: use sed to inject arrays into config.yaml + local config_file="$HOME/.hermes/config.yaml" + + # Add docker_volumes block + cat >> "$config_file" << 'SEDVOL' + +terminal: + docker_volumes: + - ${SSH_KEY_1}:/root/.ssh/id_ed25519razer:ro + - ${SSH_KEY_2}:/root/.ssh/id_rsa:ro + - ${SSH_CONFIG}:/root/.ssh/config:ro + - ${SSH_KNOWN_HOSTS}:/root/.ssh/known_hosts:ro + - ${HOME}/.aws/config:/root/.aws/config:ro + - ${HOME}/.aws/sso/cache:/root/.aws/sso/cache:rw + - ${REPO_OPS}:/workspace/rai-ops:rw + - ${REPO_DEPLOY}:/workspace/rai-deployment:rw + - ${REPO_DEVTOOLS}:/workspace/rai-devtools:rw + - ${HOME}/.hermes/scripts:/usr/local/bin:ro + docker_forward_env: + - JIRA_EMAIL + - JIRA_API_TOKEN + - DEFAULT_REPOS + shell_init_files: + - /usr/local/bin/session-init.sh +SEDVOL + echo " ✓ Array structures set via sed (partial — review config.yaml)" + fi + + # Validate + local img + img=$(hermes config get terminal.docker_image 2>/dev/null || echo "unset") + echo " ✓ Verified: terminal.docker_image = ${img}" +} + +# ---- Generate .env file ---- +# T-09-06 mitigation: chmod 600 on .env immediately after writing +generate_env_file() { + echo " → Generating .env (D-08, D-10)..." + + local env_file="$HOME/.hermes/.env" + + # Resolve HINDSIGHT_LLM_API_KEY — defaults to OPENROUTER_API_KEY if not separately provided + local hind_key="${HINDSIGHT_LLM_API_KEY:-${OPENROUTER_API_KEY}}" + + cat > "$env_file" << ENVEOF +# ngn-agent Environment — generated by setup-ngn-agent.sh +# Embedded file snapshots frozen at: 2026-06-15 + +# ============================================================================= +# LLM PROVIDER (OpenRouter) +# ============================================================================= +OPENROUTER_API_KEY=${OPENROUTER_API_KEY} + +# ============================================================================= +# ATLASSIAN INTEGRATION +# ============================================================================= +JIRA_API_TOKEN=${JIRA_API_TOKEN} +JIRA_EMAIL=${JIRA_EMAIL} + +# ============================================================================= +# TELEGRAM GATEWAY +# ============================================================================= +TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} +TELEGRAM_ALLOWED_USERS=474440517 + +# ============================================================================= +# HINDSIGHT MEMORY +# ============================================================================= +HINDSIGHT_LLM_API_KEY=${hind_key} + +# ============================================================================= +# NGN-AGENT CONFIG +# ============================================================================= +DEFAULT_REPOS=rai-ops,rai-deployment,rai-devtools +TERMINAL_TIMEOUT=60 +TERMINAL_LIFETIME_SECONDS=300 +ENVEOF + + # T-09-06: Restrict permissions immediately after writing + chmod 600 "$env_file" + echo " ✓ .env written with chmod 600 (T-09-06)" +} + +# ---- Generate hindsight config.json (D-10) ---- +generate_hindsight_config() { + echo " → Generating hindsight/config.json (D-10)..." + + cat > "$HOME/.hermes/hindsight/config.json" << 'JSONEOF' +{ + "mode": "local_embedded", + "llm_provider": "openrouter", + "llm_base_url": "https://openrouter.ai/api/v1", + "llm_model": "qwen/qwen3.5-9b", + "bank_id": "hermes", + "recall_budget": "low", + "recall_prefetch_method": "recall", + "auto_recall": true, + "recall_types": "observation", + "auto_retain": true, + "retain_async": true, + "retain_every_n_turns": 5, + "memory_mode": "hybrid" +} +JSONEOF + + echo " ✓ hindsight/config.json written" +} + +# ---- Generate cron env config (D-10) ---- +generate_cron_env_config() { + echo " → Configuring cron environment (D-10)..." + + hermes config set cron.env.JIRA_EMAIL "${JIRA_EMAIL}" 2>/dev/null || \ + echo " ⚠ Could not set cron.env.JIRA_EMAIL" + hermes config set cron.env.JIRA_API_TOKEN "${JIRA_API_TOKEN}" 2>/dev/null || \ + echo " ⚠ Could not set cron.env.JIRA_API_TOKEN" + + echo " ✓ Cron env vars configured" +}