#!/usr/bin/env bash # --------------------------------------------------------------------------- # Check that generated regions in tracked files are current. # # The tool list inside a scenario's system prompt is generated from the backend's # contracts module. It has to be generated rather than referenced because pi does # not put the tool list in the prompt when --system-prompt is used: the # customPrompt branch returns before `toolsList` is assembled, so `promptSnippet` # and `promptGuidelines` never reach the model. # # That makes the prompt a copy of the tool definitions, and a copy drifts. The # failure is quiet and bad: the model is told about a tool that no longer exists, # or not told about one that does, and answers from memory instead of asking. # # Run by the pre-commit hook. The backend path comes from profile.toml, so this # checks against the code that will actually serve the tools. # --------------------------------------------------------------------------- # shellcheck source=lib/common.sh . "$(dirname "${BASH_SOURCE[0]}")/lib/common.sh" FIX=0 [ "${1:-}" = "--fix" ] && FIX=1 STALE=0 CHECKED=0 while IFS= read -r profile; do name="$(basename "$(dirname "$profile")")" backend="$(toml_get "$profile" scenario backend)" [ -n "$backend" ] || continue [ -d "$backend" ] || { warn "$name: backend not found: $backend"; continue; } while IFS= read -r prompt; do [ -f "$prompt" ] || continue grep -q 'BEGIN GENERATED TOOL LIST' "$prompt" || continue CHECKED=$((CHECKED + 1)) rel="${prompt#"$REPO_ROOT"/}" if PYTHONPATH="$backend" python3 - "$prompt" "$FIX" <<'PY' import pathlib, sys from curator import contracts path, fix = pathlib.Path(sys.argv[1]), sys.argv[2] == "1" text = path.read_text(encoding="utf-8") current = contracts.splice_tool_prose(text) if current == text: sys.exit(0) if fix: path.write_text(current, encoding="utf-8") sys.exit(0) sys.exit(1) PY then if [ "$FIX" -eq 1 ]; then ok "$rel"; else ok "$rel"; fi else STALE=$((STALE + 1)) warn "stale generated region: $rel" fi done < <(find "$(dirname "$profile")/workspace" -name '*.md' -type f 2>/dev/null | sort) done < <(find "$REPO_ROOT/scenarios" -mindepth 2 -maxdepth 2 -name profile.toml | sort) if [ "$STALE" -gt 0 ]; then die "$STALE generated region(s) out of date. Regenerate with: scripts/verify-generated.sh --fix" fi ok "verify-generated: $CHECKED file(s) checked, all current"