Files
roboco/docker/scripts/sdk-startup-hook.sh
T

58 lines
2.4 KiB
Bash
Raw Normal View History

2026-01-06 00:59:09 +01:00
#!/bin/bash
2026-04-21 17:48:45 +02:00
# SessionStart hook — starts the SDK server and prints the pre-rendered
# task briefing into the session so Claude doesn't burn its first turns
2026-06-03 06:35:03 +02:00
# on tool discovery (give_me_work → read files).
2026-01-06 00:59:09 +01:00
#
2026-04-21 17:48:45 +02:00
# The briefing is written by the orchestrator before the container spawns
# (_write_agent_briefing) and mounted read-only at /app/briefing.md.
2026-01-06 00:59:09 +01:00
SDK_PORT="${ROBOCO_SDK_PORT:-9000}"
AGENT_ID="${ROBOCO_AGENT_ID:-unknown}"
LOG_FILE="/tmp/sdk-server.log"
2026-04-21 17:48:45 +02:00
BRIEFING_FILE="/app/briefing.md"
PRECOMPACT_FILE="/tmp/roboco-precompact-${AGENT_ID}.md"
2026-01-06 00:59:09 +01:00
# #179: this hook runs with cwd = the agent's workspace, so a bare
# `uv run` resolves a cwd-relative `.venv` (≠ the baked /app/.venv),
# ignores VIRTUAL_ENV with a warning, and RE-SYNCS the full dependency
# set (torch/lancedb/pyarrow/scipy, ~350MB) into a fresh venv. On a cold
# uv wheel cache (first spawn after an image rebuild) that download takes
# minutes and the SDK/MCP layer never comes up before the agent reaps.
# Pin uv to the pre-baked image venv AND pass `--no-sync` on the run below.
# Pinning the env location alone is NOT sufficient: `uv run` still discovers
# the cwd project and re-syncs the pinned venv against the clone's (drifted)
# lock — that resync is the actual multi-minute stall. `--no-sync` skips it.
# (The orchestrator passes the same var + --no-sync to every MCP server in
# the generated mcp-config.json — keep both in sync.)
export UV_PROJECT_ENVIRONMENT=/app/.venv
2026-04-21 17:48:45 +02:00
# --- SDK bring-up ---------------------------------------------------------
if ! curl -sf "http://localhost:${SDK_PORT}/health" >/dev/null 2>&1; then
echo "[SDK] Starting for agent ${AGENT_ID} on port ${SDK_PORT}..."
nohup uv run --no-sync python -m roboco.agent_sdk.server > "$LOG_FILE" 2>&1 &
2026-04-21 17:48:45 +02:00
SDK_PID=$!
sleep 2
if curl -sf "http://localhost:${SDK_PORT}/health" >/dev/null 2>&1; then
echo "[SDK] Ready (PID: ${SDK_PID})"
else
echo "[SDK] Starting in background (PID: ${SDK_PID}, check ${LOG_FILE})"
fi
2026-01-06 00:59:09 +01:00
fi
2026-04-21 17:48:45 +02:00
# Reset budget/terminal counters at the start of every session.
curl -sf -m 2 -X POST "http://localhost:${SDK_PORT}/budget/reset" >/dev/null 2>&1 || true
2026-01-06 00:59:09 +01:00
2026-04-21 17:48:45 +02:00
# --- Briefing + PreCompact recovery --------------------------------------
# Compact restore comes FIRST so it's clear what this session is resuming.
if [[ -s "$PRECOMPACT_FILE" ]]; then
echo "### Resumed from compact"
cat "$PRECOMPACT_FILE"
echo
fi
2026-01-06 00:59:09 +01:00
2026-04-21 17:48:45 +02:00
if [[ -s "$BRIEFING_FILE" ]]; then
cat "$BRIEFING_FILE"
2026-01-06 00:59:09 +01:00
fi
exit 0