added 260907 version of worker toolkit

This commit is contained in:
2026-09-08 20:30:51 -04:00
parent cbd3f0f8ca
commit 97aca37663
1283 changed files with 142951 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
FROM node:24.12.0-bookworm
ARG TOOLKIT_BUILD_ID=dev
# System deps
RUN apt-get update && apt-get install -y \
git \
python3 \
python3-pip \
python3-venv \
sqlite3 \
curl \
zip \
unzip \
ca-certificates \
gnupg \
&& rm -rf /var/lib/apt/lists/*
# Install Docker CE CLI + compose plugin (not docker.io from apt which lacks compose)
RUN install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \
&& chmod a+r /etc/apt/keyrings/docker.asc \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list \
&& apt-get update \
&& apt-get install -y docker-ce-cli docker-compose-plugin \
&& rm -rf /var/lib/apt/lists/*
# Pin npm so lockfiles do not churn between this container and any host
# install. node:24.12.0-bookworm bundles an older npm; overwrite it.
RUN npm install -g npm@11.12.1
# Install uv and harbor
RUN pip3 install --break-system-packages uv && uv tool install harbor==0.20.0
# Pin harbor to the local docker backend — the only backend this container is
# provisioned for (docker CLI + host docker socket, configured above). The
# bundled scripts/harbor-run otherwise defaults to a cloud sandbox backend that
# needs an API key this container doesn't ship, and exits 1 before running.
# NOTE: devcontainer.json also sets HARBOR_ENV=docker via containerEnv — keep
# BOTH. containerEnv survives a stale image (workers who upgrade the toolkit
# files without rebuilding still get docker), while this ENV covers running the
# image directly with `docker run` outside the devcontainer tooling. Removing
# either as a "duplicate" reintroduces the daytona-default error.
ENV HARBOR_ENV=docker
# Make uv tools and Claude Code available
ENV PATH="/root/.local/bin:${PATH}"
WORKDIR /workspace

View File

@@ -0,0 +1,22 @@
{
"name": "Raccoon Task Authoring (flaredown)",
"build": {
"dockerfile": "Dockerfile",
"args": {
"TOOLKIT_BUILD_ID": "1788781907637-qfa2vk"
}
},
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind",
"workspaceFolder": "/workspace",
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
"source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind"
],
"containerEnv": {
"HOST_WORKSPACE": "${localWorkspaceFolder}",
"HARBOR_ENV": "docker"
},
"postCreateCommand": "bash .devcontainer/post-create.sh",
"postStartCommand": "test -f .env && echo '.env found' || echo 'WARNING: No .env file. Create one with ANTHROPIC_API_KEY=sk-ant-...'",
"customizations": {}
}

View File

@@ -0,0 +1,129 @@
#!/bin/bash
# Post-create setup for the Authoring devcontainer.
set -euo pipefail
# Install every harness a worker can author with, and point each at the LLM proxy.
# Driven by scripts/harness-registry.toml, so adding a harness is a registry entry
# rather than an edit here and in the sibling container's post-create.
set -a; . /workspace/.env 2>/dev/null || true; set +a
. /workspace/scripts/setup-harnesses.sh
harness_setup_all
npm install
git config --global --add safe.directory '*'
# --- Claude auth for non-interactive / background-agent sessions ------------
# Interactive shells source .env via .bashrc (below), so `claude` picks up a
# live, per-launch ANTHROPIC_API_KEY. But sessions that don't run a login
# shell (headless `claude -p`, background agents) never source .env and have
# no key. apiKeyHelper closes that gap: Claude Code runs this script to fetch
# the key, re-reading the live .env every time (fresh per session, re-checked
# on the TTL below), so a rotated key is picked up with no container rebuild.
#
# Precedence is cloud > ANTHROPIC_AUTH_TOKEN > ANTHROPIC_API_KEY (env) >
# apiKeyHelper > OAuth. Interactive shells still have ANTHROPIC_API_KEY in
# their env (from .bashrc), so it outranks the helper there — also live, so
# fine. We deliberately do NOT put ANTHROPIC_API_KEY in the settings `env`
# block: that would cache it at daemon start and shadow the helper, defeating
# the whole point.
#
# The base URL does NOT rotate per task, so it doesn't need the live-helper
# treatment — but background sessions still need it (they never source .env).
# So we read it from .env ONCE here and bake it into the settings `env` block.
# .env stays the single source of truth (no hardcoded copy to keep in sync on
# a proxy-domain change), and the baked value is the worker's own .env value.
# Caveat: it's a snapshot — changing ANTHROPIC_BASE_URL in .env after boot
# needs a container rebuild to take effect (the key, which rotates, stays live).
mkdir -p /root/.claude
cat > /root/.claude/anthropic-key-helper.sh <<'HELPER'
#!/bin/bash
set -a; . /workspace/.env 2>/dev/null || true; set +a
K="${ANTHROPIC_API_KEY:-}"
# Raw value if `tr` is unavailable — never hand claude an empty key because a trim failed.
printf '%s' "$K" | tr -d '[:space:]' 2>/dev/null || printf '%s' "$K"
HELPER
chmod +x /root/.claude/anthropic-key-helper.sh
# Derive the base URL from .env (empty if absent -> line omitted, graceful).
AUTH_BASE_URL=$(set -a; . /workspace/.env 2>/dev/null || true; set +a; printf '%s' "${ANTHROPIC_BASE_URL:-}")
# Write valid JSON via node (guaranteed present: node base image); only include
# the base-URL key when .env actually had one.
# SKIP_FAST_MODE_NETWORK_ERRORS: the LLM proxy doesn't forward claude's fast-mode
# availability probe, and claude reads the failed probe as "no network" and refuses
# /fast. The override makes /fast toggleable; fast serving stays OFF until toggled.
AUTH_BASE_URL="$AUTH_BASE_URL" node -e '
const fs = require("fs");
const env = {
CLAUDE_CODE_API_KEY_HELPER_TTL_MS: "60000",
CLAUDE_CODE_DISABLE_AUTO_MEMORY: "1",
CLAUDE_CODE_SKIP_FAST_MODE_NETWORK_ERRORS: "1",
};
if (process.env.AUTH_BASE_URL) env.ANTHROPIC_BASE_URL = process.env.AUTH_BASE_URL;
fs.writeFileSync(
"/root/.claude/settings.json",
JSON.stringify({ apiKeyHelper: "/root/.claude/anthropic-key-helper.sh", env }, null, 2) + "\n"
);
'
# Reference-data corpus: expose it at the stable /data/zeta-corpus path (the same path a trial
# uses) by symlinking to the toolkit's bind-mounted copy. No-op if this toolkit ships no corpus.
if [ -d /workspace/data/zeta-corpus ]; then
{ mkdir -p /data || sudo mkdir -p /data; } 2>/dev/null || true
{ ln -sfn /workspace/data/zeta-corpus /data/zeta-corpus \
|| sudo ln -sfn /workspace/data/zeta-corpus /data/zeta-corpus; } 2>/dev/null || true
fi
# Shell setup
cat >> ~/.bashrc <<'BASHRC'
test -f .env && set -a && source .env && set +a
# Interactive shells only below. An agent's shell tool sources .bashrc too, so without
# this the welcome banner prints into command output and container_start fires per
# command rather than per session.
case $- in
*i*) ;;
*) return ;;
esac
# Hide ANTHROPIC_API_KEY from the `claude` process so it uses the (live)
# apiKeyHelper as its single credential source — same key, read from .env every
# call. Without this, an interactive shell has BOTH the env key AND the helper
# set, and Claude Code prints a scary "auth may not work as expected" warning
# (auth still works — the env key wins — but the warning alarms workers). The
# key stays in the shell env for harbor etc.; only `claude` runs without it.
# These pin the ASSISTANT's model and effort, not the agent-under-test's, so they don't
# track the registry: here we want the strongest available model, a trial wants a pinned id.
alias claude="env -u ANTHROPIC_API_KEY claude --model opus[1m] --effort max"
# codex keeps its key in a file written at container create, with no live helper of its
# own, so each launch re-derives it from .env first. Fails open — see the script.
alias codex="/workspace/scripts/refresh-harness-auth codex --model gpt-5.6-sol -c model_reasoning_effort=max"
export PS1="\[\033[1;33m\][raccoon-authoring]\[\033[0m\] \w\$ "
bash scripts/welcome.sh authoring 2>/dev/null
_AK="fde503c3bdb6e5cc9c48b1f8e4c2abeb"
_DK="e966e45af5ad1a18005f9fdb831186ea"
_WID="w-mtr6ka3o-99o0"
_VER="7f40461c4d"
_CT="authoring"
_RP=$(node -e "try{process.stdout.write(require('$PWD/toolkit.json').repo)}catch{}" 2>/dev/null)
_SID="$(date +%s)-$$"
_LAT=0
_ev() {
[ -z "$_AK" ] && return
{ curl -s -X POST "https://api2.amplitude.com/2/httpapi" \
-H "Content-Type: application/json" \
-d "{\"api_key\":\"$_AK\",\"events\":[{\"user_id\":\"$_WID\",\"event_type\":\"raccoon.$1\",\"event_properties\":{\"product\":\"raccoon\",\"container\":\"$_CT\",\"repo\":\"$_RP\",\"toolkit_version\":\"$_VER\",\"session_id\":\"$_SID\"},\"session_id\":$(date +%s000)}]}" \
>/dev/null 2>&1 & } 2>/dev/null; disown 2>/dev/null
}
_dl() {
[ -z "$_DK" ] && return
{ curl -s -X POST "https://http-intake.logs.datadoghq.com/api/v2/logs" \
-H "DD-API-KEY: $_DK" -H "Content-Type: application/json" \
-d "[{\"ddsource\":\"raccoon\",\"service\":\"toolkit\",\"hostname\":\"$(hostname)\",\"status\":\"$1\",\"message\":\"$2\",\"ddtags\":\"container:$_CT,worker:$_WID,repo:$_RP,toolkit_version:$_VER\"}]" \
>/dev/null 2>&1 & } 2>/dev/null; disown 2>/dev/null
}
_pc() { local n; n=$(date +%s); if (( n - _LAT >= 300 )); then _LAT=$n; _ev active; fi; }
PROMPT_COMMAND="_pc;${PROMPT_COMMAND:-}"
trap '_ev container_stop; _dl info container_stop; wait' EXIT
_ev container_start
_dl info container_start
BASHRC