Files
agent-runtime-framework/harnesses/contexts/minimax/v1/init.sh
Paul O'Reilly 2c1ec7d52c fix: update MiniMax harness base URL to api.minimaxi.chat
MiniMax moved their Anthropic-compatible API from api.minimax.io to
api.minimaxi.chat. Update ANTHROPIC_BASE_URL in the minimax/v1 context
harness and corresponding comments in init.sh and the TODO note.

Model routing is unaffected: the API defaults unrecognised model names
(e.g. "minimax" from the registry slug) to MiniMax-M3 already.

Claude-Session: https://claude.ai/code/session_01XtWRazqRbMnMRa4iV3zbVx
2026-07-17 22:55:47 +12:00

77 lines
3.0 KiB
Bash
Executable File

#!/bin/bash
# minimax init — stage the api_key for the agent user and wire apiKeyHelper.
#
# Threat model: keep the ESO mount root-only (mode 0400) so the agent user
# cannot directly `cat` /run/agent/secrets/minimax/api_key. init.sh runs as
# root (in uid-wrapper.sh, before the gosu drop) and stages a per-secret
# copy into the agent's home with mode 0600 owned by agent. apiKeyHelper
# points at the COPY. This is the gitea-ssh pattern — only the file the
# harness explicitly grants is reachable by the runtime.
#
# Rotation handling: this is a one-shot copy at container start. For
# ephemeral container agents (one task = one container) every task starts
# with the latest secret. Long-running sessions don't refresh the copy
# until a future scripts.control_loop hook lands (planning E1-M3).
#
# Auth wire-up: apiKeyHelper output is sent as `Authorization: Bearer
# <value>` when ANTHROPIC_BASE_URL is non-anthropic.com — exactly what
# api.minimaxi.chat/anthropic requires. The secret value never enters this
# process' env, the claude subprocess' env, or /proc/<pid>/environ.
set -euo pipefail
ESO_API_KEY="/run/agent/secrets/minimax/api_key"
if [ ! -r "$ESO_API_KEY" ]; then
echo "ERROR: $ESO_API_KEY not readable. Check ESO ExternalSecret acct-<minimax-id>." >&2
exit 1
fi
# Resolve the agent user's home (init.sh's $HOME is /root before gosu drop).
AGENT_USER="${AGENT_USER:-agent}"
AGENT_HOME=$(getent passwd "$AGENT_USER" | cut -d: -f6)
if [ -z "$AGENT_HOME" ] || [ ! -d "$AGENT_HOME" ]; then
AGENT_HOME="/home/$AGENT_USER"
fi
# Stage the api_key into a per-secret path owned by agent, mode 0600.
# install(1) handles ownership/mode atomically; the destination is outside
# the read-only ESO mount so we can chmod/chown freely.
STAGED_KEY_DIR="$AGENT_HOME/.claude/secrets"
STAGED_KEY="$STAGED_KEY_DIR/minimax-api-key"
mkdir -p "$STAGED_KEY_DIR"
chown "$AGENT_USER:" "$STAGED_KEY_DIR" 2>/dev/null || true
chmod 0700 "$STAGED_KEY_DIR"
install -m 0600 -o "$AGENT_USER" -g "$AGENT_USER" "$ESO_API_KEY" "$STAGED_KEY"
# Wire apiKeyHelper to the staged copy in the agent's settings.json.
CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$AGENT_HOME/.claude}"
mkdir -p "$CONFIG_DIR"
chown "$AGENT_USER:" "$CONFIG_DIR" 2>/dev/null || true
chmod 0755 "$CONFIG_DIR"
SETTINGS_FILE="$CONFIG_DIR/settings.json"
# Merge into an existing settings.json (from another harness layer) when
# possible; otherwise create a fresh one.
if [ -f "$SETTINGS_FILE" ] && command -v jq >/dev/null 2>&1; then
TMP=$(mktemp)
jq --arg helper "cat $STAGED_KEY" \
'. + {apiKeyHelper: $helper}' \
"$SETTINGS_FILE" > "$TMP"
mv "$TMP" "$SETTINGS_FILE"
else
cat > "$SETTINGS_FILE" <<EOF
{
"apiKeyHelper": "cat $STAGED_KEY"
}
EOF
fi
# settings.json holds a command (a path), not a credential value.
chown "$AGENT_USER:" "$SETTINGS_FILE" 2>/dev/null || true
chmod 0644 "$SETTINGS_FILE"
echo "minimax api_key staged at $STAGED_KEY (0600 $AGENT_USER:$AGENT_USER)"
echo "minimax apiKeyHelper wired in $SETTINGS_FILE"