Compare commits

..

1 commit

Author SHA1 Message Date
Claude
4ac560ea1d fix: Migrate planner, predictor, supervisor to SDK (#6)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline failed
Replace tmux-based run_formula_and_monitor() with synchronous agent_run()
from lib/agent-sdk.sh, matching the pattern established in gardener-run.sh.

Key changes per agent:
- Drop agent-session.sh, use agent-sdk.sh (SID_FILE, LOGFILE)
- Remove SESSION_NAME, PHASE_FILE, PHASE_POLL_INTERVAL (tmux/phase artifacts)
- Create explicit worktree with cleanup trap (replaces formula session worktree)
- Strip phase protocol from prompt footer (SDK mode needs no phase signals)
- Preserve all prompt composition: context blocks, memory, journal, preflight

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:35:36 +00:00
6 changed files with 60 additions and 43 deletions

View file

@ -18,7 +18,7 @@ log() {
# Build crontab from project TOMLs and install for the agent user. # Build crontab from project TOMLs and install for the agent user.
install_project_crons() { install_project_crons() {
local cron_lines="DISINTO_CONTAINER=1" local cron_lines=""
for toml in "${DISINTO_DIR}"/projects/*.toml; do for toml in "${DISINTO_DIR}"/projects/*.toml; do
[ -f "$toml" ] || continue [ -f "$toml" ] || continue
local pname local pname
@ -30,9 +30,9 @@ with open(sys.argv[1], 'rb') as f:
cron_lines="${cron_lines} cron_lines="${cron_lines}
# disinto: ${pname} # disinto: ${pname}
2,7,12,17,22,27,32,37,42,47,52,57 * * * * ${DISINTO_DIR}/review/review-poll.sh ${toml} >>/home/agent/data/logs/cron.log 2>&1 2,7,12,17,22,27,32,37,42,47,52,57 * * * * ${DISINTO_DIR}/review/review-poll.sh ${toml} >/dev/null 2>&1
4,9,14,19,24,29,34,39,44,49,54,59 * * * * ${DISINTO_DIR}/dev/dev-poll.sh ${toml} >>/home/agent/data/logs/cron.log 2>&1 4,9,14,19,24,29,34,39,44,49,54,59 * * * * ${DISINTO_DIR}/dev/dev-poll.sh ${toml} >/dev/null 2>&1
0 0,6,12,18 * * * cd ${DISINTO_DIR} && bash gardener/gardener-run.sh ${toml} >>/home/agent/data/logs/cron.log 2>&1" 0 0,6,12,18 * * * cd ${DISINTO_DIR} && bash gardener/gardener-run.sh ${toml} >/dev/null 2>&1"
done done
if [ -n "$cron_lines" ]; then if [ -n "$cron_lines" ]; then

View file

@ -92,8 +92,11 @@ Supported actions:
The commit-and-pr step converts JSONL to JSON array. The orchestrator executes The commit-and-pr step converts JSONL to JSON array. The orchestrator executes
actions after the PR merges. Do NOT call mutation APIs directly during the run." actions after the PR merges. Do NOT call mutation APIs directly during the run."
build_sdk_prompt_footer "$GARDENER_API_EXTRA" # Reuse shared footer (API reference + environment), replace phase protocol
PROMPT_FOOTER="${PROMPT_FOOTER}## Completion protocol (REQUIRED) # shellcheck disable=SC2034 # consumed by build_prompt_footer
PHASE_FILE="" # not used in SDK mode
build_prompt_footer "$GARDENER_API_EXTRA"
PROMPT_FOOTER="${PROMPT_FOOTER%%## Phase protocol*}## Completion protocol (REQUIRED)
When the commit-and-pr step creates a PR, write the PR number and stop: When the commit-and-pr step creates a PR, write the PR number and stop:
echo \"\$PR_NUMBER\" > '${GARDENER_PR_FILE}' echo \"\$PR_NUMBER\" > '${GARDENER_PR_FILE}'
Then STOP. Do NOT write PHASE: signals — the orchestrator handles CI, review, and merge. Then STOP. Do NOT write PHASE: signals — the orchestrator handles CI, review, and merge.

View file

@ -291,33 +291,6 @@ build_graph_section() {
fi fi
} }
# ── SDK helpers ───────────────────────────────────────────────────────────
# build_sdk_prompt_footer [EXTRA_API_LINES]
# Like build_prompt_footer but omits the phase protocol section (SDK mode).
# Sets PROMPT_FOOTER.
build_sdk_prompt_footer() {
# shellcheck disable=SC2034 # consumed by build_prompt_footer
PHASE_FILE="" # not used in SDK mode
build_prompt_footer "${1:-}"
PROMPT_FOOTER="${PROMPT_FOOTER%%## Phase protocol*}"
}
# formula_worktree_setup WORKTREE
# Creates an isolated worktree for synchronous formula execution.
# Fetches primary branch, cleans stale worktree, creates new one, and
# sets an EXIT trap for cleanup.
# Requires globals: PROJECT_REPO_ROOT, PRIMARY_BRANCH.
formula_worktree_setup() {
local worktree="$1"
cd "$PROJECT_REPO_ROOT"
git fetch origin "$PRIMARY_BRANCH" 2>/dev/null || true
worktree_cleanup "$worktree"
git worktree add "$worktree" "origin/${PRIMARY_BRANCH}" --detach 2>/dev/null
# shellcheck disable=SC2064 # expand worktree now, not at trap time
trap "worktree_cleanup '$worktree'" EXIT
}
# ── Prompt + monitor helpers ────────────────────────────────────────────── # ── Prompt + monitor helpers ──────────────────────────────────────────────
# build_prompt_footer [EXTRA_API_LINES] # build_prompt_footer [EXTRA_API_LINES]

View file

@ -96,11 +96,16 @@ SCRATCH_CONTEXT=$(read_scratch_context "$SCRATCH_FILE")
SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE") SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE")
# ── Build prompt ───────────────────────────────────────────────────────── # ── Build prompt ─────────────────────────────────────────────────────────
build_sdk_prompt_footer " # Reuse shared footer (API reference + environment), replace phase protocol
# shellcheck disable=SC2034 # consumed by build_prompt_footer
PHASE_FILE="" # not used in SDK mode
build_prompt_footer "
Relabel: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" -X PUT -H 'Content-Type: application/json' '${FORGE_API}/issues/{number}/labels' -d '{\"labels\":[LABEL_ID]}' Relabel: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" -X PUT -H 'Content-Type: application/json' '${FORGE_API}/issues/{number}/labels' -d '{\"labels\":[LABEL_ID]}'
Comment: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" -X POST -H 'Content-Type: application/json' '${FORGE_API}/issues/{number}/comments' -d '{\"body\":\"...\"}' Comment: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" -X POST -H 'Content-Type: application/json' '${FORGE_API}/issues/{number}/comments' -d '{\"body\":\"...\"}'
Close: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" -X PATCH -H 'Content-Type: application/json' '${FORGE_API}/issues/{number}' -d '{\"state\":\"closed\"}' Close: curl -sf -H \"Authorization: token \${FORGE_TOKEN}\" -X PATCH -H 'Content-Type: application/json' '${FORGE_API}/issues/{number}' -d '{\"state\":\"closed\"}'
" "
# Strip phase protocol — not used in SDK mode
PROMPT_FOOTER="${PROMPT_FOOTER%%## Phase protocol*}"
PROMPT="You are the strategic planner for ${FORGE_REPO}. Work through the formula below. PROMPT="You are the strategic planner for ${FORGE_REPO}. Work through the formula below.
@ -117,7 +122,15 @@ ${SCRATCH_INSTRUCTION}
${PROMPT_FOOTER}" ${PROMPT_FOOTER}"
# ── Create worktree ────────────────────────────────────────────────────── # ── Create worktree ──────────────────────────────────────────────────────
formula_worktree_setup "$WORKTREE" cd "$PROJECT_REPO_ROOT"
git fetch origin "$PRIMARY_BRANCH" 2>/dev/null || true
worktree_cleanup "$WORKTREE"
git worktree add "$WORKTREE" "origin/${PRIMARY_BRANCH}" --detach 2>/dev/null
cleanup() {
worktree_cleanup "$WORKTREE"
}
trap cleanup EXIT
# ── Run agent ───────────────────────────────────────────────────────────── # ── Run agent ─────────────────────────────────────────────────────────────
export CLAUDE_MODEL="opus" export CLAUDE_MODEL="opus"

View file

@ -65,8 +65,12 @@ SCRATCH_CONTEXT=$(read_scratch_context "$SCRATCH_FILE")
SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE") SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE")
# ── Build prompt ───────────────────────────────────────────────────────── # ── Build prompt ─────────────────────────────────────────────────────────
build_sdk_prompt_footer # Reuse shared footer (API reference + environment), replace phase protocol
export CLAUDE_MODEL="sonnet" # shellcheck disable=SC2034 # consumed by build_prompt_footer
PHASE_FILE="" # not used in SDK mode
build_prompt_footer
# Strip phase protocol — not used in SDK mode
PROMPT_FOOTER="${PROMPT_FOOTER%%## Phase protocol*}"
PROMPT="You are the prediction agent (goblin) for ${FORGE_REPO}. Work through the formula below. PROMPT="You are the prediction agent (goblin) for ${FORGE_REPO}. Work through the formula below.
@ -92,9 +96,19 @@ ${SCRATCH_INSTRUCTION}
${PROMPT_FOOTER}" ${PROMPT_FOOTER}"
# ── Create worktree ────────────────────────────────────────────────────── # ── Create worktree ──────────────────────────────────────────────────────
formula_worktree_setup "$WORKTREE" cd "$PROJECT_REPO_ROOT"
git fetch origin "$PRIMARY_BRANCH" 2>/dev/null || true
worktree_cleanup "$WORKTREE"
git worktree add "$WORKTREE" "origin/${PRIMARY_BRANCH}" --detach 2>/dev/null
cleanup() {
worktree_cleanup "$WORKTREE"
}
trap cleanup EXIT
# ── Run agent ───────────────────────────────────────────────────────────── # ── Run agent ─────────────────────────────────────────────────────────────
export CLAUDE_MODEL="sonnet"
agent_run --worktree "$WORKTREE" "$PROMPT" agent_run --worktree "$WORKTREE" "$PROMPT"
log "agent_run complete" log "agent_run complete"

View file

@ -76,11 +76,12 @@ SCRATCH_CONTEXT=$(read_scratch_context "$SCRATCH_FILE")
SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE") SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE")
# ── Build prompt ───────────────────────────────────────────────────────── # ── Build prompt ─────────────────────────────────────────────────────────
build_sdk_prompt_footer # Reuse shared footer (API reference + environment), replace phase protocol
export CLAUDE_MODEL="sonnet" # shellcheck disable=SC2034 # consumed by build_prompt_footer
PHASE_FILE="" # not used in SDK mode
# ── Create worktree (before prompt assembly so trap is set early) ──────── build_prompt_footer
formula_worktree_setup "$WORKTREE" # Strip phase protocol — not used in SDK mode
PROMPT_FOOTER="${PROMPT_FOOTER%%## Phase protocol*}"
PROMPT="You are the supervisor agent for ${FORGE_REPO}. Work through the formula below. PROMPT="You are the supervisor agent for ${FORGE_REPO}. Work through the formula below.
@ -101,7 +102,20 @@ ${FORMULA_CONTENT}
${SCRATCH_INSTRUCTION} ${SCRATCH_INSTRUCTION}
${PROMPT_FOOTER}" ${PROMPT_FOOTER}"
# ── Create worktree ──────────────────────────────────────────────────────
cd "$PROJECT_REPO_ROOT"
git fetch origin "$PRIMARY_BRANCH" 2>/dev/null || true
worktree_cleanup "$WORKTREE"
git worktree add "$WORKTREE" "origin/${PRIMARY_BRANCH}" --detach 2>/dev/null
cleanup() {
worktree_cleanup "$WORKTREE"
}
trap cleanup EXIT
# ── Run agent ───────────────────────────────────────────────────────────── # ── Run agent ─────────────────────────────────────────────────────────────
export CLAUDE_MODEL="sonnet"
agent_run --worktree "$WORKTREE" "$PROMPT" agent_run --worktree "$WORKTREE" "$PROMPT"
log "agent_run complete" log "agent_run complete"