131 lines
5.5 KiB
Bash
Executable File
131 lines
5.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# run-turn.sh - Manual orchestration of a discussion turn
|
|
#
|
|
# This script demonstrates how all the SmartTools chain together.
|
|
# It does exactly what `discussions turn feature.md` would do,
|
|
# but each step is visible and debuggable.
|
|
#
|
|
# Usage: ./scripts/run-turn.sh path/to/discussion.md
|
|
|
|
set -e # Exit immediately if any command fails
|
|
|
|
# Validate command line argument
|
|
if [ -z "$1" ]; then
|
|
echo "Usage: $0 <discussion.md>"
|
|
exit 1
|
|
fi
|
|
|
|
DISCUSSION="$1" # Path to the discussion markdown file
|
|
WORKDIR=$(mktemp -d) # Create temporary working directory
|
|
|
|
echo "=== Discussion Turn Script ==="
|
|
echo "Discussion: $DISCUSSION"
|
|
echo "Work directory: $WORKDIR"
|
|
echo ""
|
|
|
|
# 1. Parse current state
|
|
echo "Step 1: Parsing discussion..."
|
|
cat "$DISCUSSION" | discussion-parser > "$WORKDIR/state.json" # Parse discussion into JSON
|
|
echo " Parsed state saved to $WORKDIR/state.json"
|
|
cat "$WORKDIR/state.json" | jq -r '" Title: \(.metadata.title)"' # Extract title
|
|
cat "$WORKDIR/state.json" | jq -r '" Phase: \(.metadata.phase)"' # Extract phase
|
|
cat "$WORKDIR/state.json" | jq -r '" Votes: READY=\(.vote_summary.READY) CHANGES=\(.vote_summary.CHANGES) REJECT=\(.vote_summary.REJECT)"' # Show current votes
|
|
echo ""
|
|
|
|
# 2. Determine who should respond
|
|
echo "Step 2: Routing mentions..."
|
|
cat "$WORKDIR/state.json" | discussion-mention-router > "$WORKDIR/routing.json" # Route mentions to participants
|
|
PARTICIPANTS=$(cat "$WORKDIR/routing.json" | jq -r '.participants_to_call | join(", ")') # Get comma-separated list
|
|
echo " Participants to call: $PARTICIPANTS"
|
|
echo ""
|
|
|
|
# 3. Call each participant (could be parallel in async Python)
|
|
echo "Step 3: Calling participants..."
|
|
echo "[]" > "$WORKDIR/responses.json" # Initialize empty responses array
|
|
|
|
# Loop through each participant that should respond
|
|
for PARTICIPANT in $(cat "$WORKDIR/routing.json" | jq -r '.participants_to_call[]'); do
|
|
TOOL="discussion-$PARTICIPANT" # Construct tool name from participant
|
|
|
|
# Check if tool exists
|
|
if ! command -v "$TOOL" &> /dev/null; then
|
|
echo " Warning: $TOOL not found, skipping"
|
|
continue
|
|
fi
|
|
|
|
echo " Calling $TOOL..."
|
|
# Call participant tool with discussion content, fallback to NO_RESPONSE sentinel
|
|
RESPONSE=$(cat "$DISCUSSION" | $TOOL --callout "Please review and provide feedback" 2>/dev/null || echo '{"sentinel": "NO_RESPONSE"}')
|
|
|
|
# Check for valid JSON
|
|
if echo "$RESPONSE" | jq -e . > /dev/null 2>&1; then
|
|
# Check for NO_RESPONSE sentinel
|
|
if [ "$(echo "$RESPONSE" | jq -r '.sentinel // empty')" = "NO_RESPONSE" ]; then
|
|
echo " -> No response"
|
|
else
|
|
# Add author field and append to responses
|
|
AUTHOR="AI-$(echo "$PARTICIPANT" | sed 's/\b\(.\)/\u\1/g')" # Capitalize participant name
|
|
RESPONSE_WITH_AUTHOR=$(echo "$RESPONSE" | jq --arg a "$AUTHOR" '. + {author: $a}')
|
|
|
|
# Append to responses array
|
|
cat "$WORKDIR/responses.json" | jq --argjson r "$RESPONSE_WITH_AUTHOR" '. + [$r]' > "$WORKDIR/responses.json.tmp"
|
|
mv "$WORKDIR/responses.json.tmp" "$WORKDIR/responses.json"
|
|
|
|
VOTE=$(echo "$RESPONSE" | jq -r '.vote // "no vote"') # Extract vote or default
|
|
echo " -> Vote: $VOTE"
|
|
fi
|
|
else
|
|
echo " -> Invalid response (not JSON)"
|
|
fi
|
|
done
|
|
echo ""
|
|
|
|
# 4. Show collected responses
|
|
echo "Step 4: Collected responses:"
|
|
cat "$WORKDIR/responses.json" | jq -r '.[] | " \(.author): \(.vote // "no vote")"' # Display author and vote
|
|
echo ""
|
|
|
|
# 5. Append responses to discussion (dry run - don't modify original)
|
|
echo "Step 5: Appending responses (dry run)..."
|
|
# Combine original discussion with responses and append using turn-appender
|
|
(cat "$DISCUSSION"; echo "---RESPONSES---"; cat "$WORKDIR/responses.json") | discussion-turn-appender > "$WORKDIR/discussion-updated.md"
|
|
echo " Updated discussion saved to $WORKDIR/discussion-updated.md"
|
|
echo ""
|
|
|
|
# 6. Count votes and check consensus
|
|
echo "Step 6: Counting votes..."
|
|
# Parse updated discussion and count votes
|
|
cat "$WORKDIR/discussion-updated.md" | discussion-parser | discussion-vote-counter > "$WORKDIR/votes.json"
|
|
cat "$WORKDIR/votes.json" | jq -r '" READY: \(.vote_summary.READY), CHANGES: \(.vote_summary.CHANGES), REJECT: \(.vote_summary.REJECT)"'
|
|
cat "$WORKDIR/votes.json" | jq -r '" Consensus reached: \(.consensus.reached)"'
|
|
cat "$WORKDIR/votes.json" | jq -r 'if .consensus.reason then " Reason: \(.consensus.reason)" else empty end'
|
|
echo ""
|
|
|
|
# 7. Check if status should change
|
|
echo "Step 7: Checking status promotion..."
|
|
CURRENT_STATUS=$(cat "$WORKDIR/state.json" | jq -r '.metadata.status // "OPEN"') # Get current status
|
|
CURRENT_PHASE=$(cat "$WORKDIR/state.json" | jq -r '.metadata.phase // "initial_feedback"') # Get current phase
|
|
# Check if status should be promoted based on votes
|
|
cat "$WORKDIR/votes.json" | discussion-status-promoter --current-status "$CURRENT_STATUS" --current-phase "$CURRENT_PHASE" > "$WORKDIR/promotion.json"
|
|
|
|
SHOULD_PROMOTE=$(cat "$WORKDIR/promotion.json" | jq -r '.should_promote')
|
|
if [ "$SHOULD_PROMOTE" = "true" ]; then
|
|
NEW_STATUS=$(cat "$WORKDIR/promotion.json" | jq -r '.new_status')
|
|
echo " Status should be promoted: $CURRENT_STATUS -> $NEW_STATUS"
|
|
else
|
|
echo " No status change needed"
|
|
fi
|
|
echo ""
|
|
|
|
# Summary
|
|
echo "=== Turn Complete ==="
|
|
echo ""
|
|
echo "Files created in $WORKDIR:"
|
|
ls -la "$WORKDIR" # List all created files
|
|
echo ""
|
|
echo "To apply changes, run:"
|
|
echo " cp $WORKDIR/discussion-updated.md $DISCUSSION" # Copy updated discussion back
|
|
echo ""
|
|
echo "To clean up:"
|
|
echo " rm -rf $WORKDIR" # Remove temporary directory
|