-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathprompt_cycle
More file actions
executable file
·264 lines (236 loc) · 8.36 KB
/
prompt_cycle
File metadata and controls
executable file
·264 lines (236 loc) · 8.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#!/bin/bash
# Configuration
MODEL="r1" # Default model
EDITOR_MODEL="" # Editor model (if different from main model)
PROMPTS_FILE="prompts.txt" # File containing prompts to cycle through
ITERATIONS=1000
SLEEP_TIME=1 # Sleep time between iterations in seconds
GLOBAL_PROMPT="" # Global prompt to prepend to all messages
# Check if rich-cli is installed
if ! command -v rich &> /dev/null; then
echo "Installing rich-cli for better formatting..."
pip install rich-cli
fi
# Default prompts
DEFAULT_PROMPTS=(
"improve code structure and organization"
"add more error handling and edge cases"
"optimize performance where possible"
"improve documentation and comments"
"refactor for better readability"
"add unit tests for critical functions"
"implement additional features"
"fix potential bugs and issues"
)
# Create default prompts file if it doesn't exist
if [ ! -f "$PROMPTS_FILE" ]; then
echo "Creating default prompts file: $PROMPTS_FILE"
printf "%s\n" "${DEFAULT_PROMPTS[@]}" > "$PROMPTS_FILE"
fi
# Initial check if prompts file exists and is not empty
if [ ! -s "$PROMPTS_FILE" ]; then
echo "Error: Prompts file is empty or doesn't exist: $PROMPTS_FILE"
exit 1
fi
# Initial count of prompts
PROMPT_COUNT=$(wc -l < "$PROMPTS_FILE")
echo "Found $PROMPT_COUNT prompts in $PROMPTS_FILE"
echo "Note: Changes to $PROMPTS_FILE will be detected automatically on each iteration"
# Function to display usage information
usage() {
echo "Usage: $0 [options] [file1 [file2 ...]]"
echo "Options:"
echo " -m, --model MODEL Set the model (default: $MODEL)"
echo " -e, --editor-model MODEL Set a specific editor model (optional)"
echo " -p, --prompts FILE Set the prompts file (default: $PROMPTS_FILE)"
echo " -i, --iterations NUM Set number of iterations (default: $ITERATIONS)"
echo " -s, --sleep SECONDS Set sleep time between iterations (default: $SLEEP_TIME)"
echo " -n, --no-files Run without specifying files (architect mode can add files)"
echo " -g, --global-prompt TEXT Set a global prompt to prepend to all messages"
echo " -h, --help Display this help message"
exit 1
}
# Parse command line arguments
FILE_PATTERNS=()
NO_FILES=false
READ_FILES=()
while [[ $# -gt 0 ]]; do
case $1 in
-m|--model)
MODEL="$2"
shift 2
;;
-e|--editor-model)
EDITOR_MODEL="$2"
shift 2
;;
-p|--prompts)
PROMPTS_FILE="$2"
# Create default prompts file if specified file doesn't exist
if [ ! -f "$PROMPTS_FILE" ]; then
echo "Creating specified prompts file: $PROMPTS_FILE"
printf "%s\n" "${DEFAULT_PROMPTS[@]}" > "$PROMPTS_FILE"
fi
shift 2
;;
-g|--global-prompt)
GLOBAL_PROMPT="$2"
shift 2
;;
-n|--no-files)
NO_FILES=true
shift
;;
-r|--read)
if [ -f "$2" ]; then
READ_FILES+=("$2")
else
echo "Warning: Read file '$2' does not exist and will be ignored."
fi
shift 2
;;
-i|--iterations)
ITERATIONS="$2"
shift 2
;;
-s|--sleep)
SLEEP_TIME="$2"
shift 2
;;
-h|--help)
usage
;;
-*)
echo "Unknown option: $1"
usage
;;
*)
FILE_PATTERNS+=("$1")
shift
;;
esac
done
# Default read files if none specified
if [ ${#READ_FILES[@]} -eq 0 ]; then
for DEFAULT_READ in "plex.md" "context.txt" "spec.md"; do
if [ -f "$DEFAULT_READ" ]; then
READ_FILES+=("$DEFAULT_READ")
fi
done
fi
# Check if at least one file pattern is provided or --no-files flag is set
if [ ${#FILE_PATTERNS[@]} -eq 0 ] && [ "$NO_FILES" = false ]; then
echo "Error: No files specified. Use --no-files flag if you want to run without specifying files."
usage
fi
# Initial check for file patterns
if [ ${#FILE_PATTERNS[@]} -gt 0 ] && [ "$NO_FILES" = false ]; then
# Check if at least one pattern matches something
FOUND_FILES=false
for PATTERN in "${FILE_PATTERNS[@]}"; do
if compgen -G "$PATTERN" > /dev/null; then
FOUND_FILES=true
break
fi
done
if [ "$FOUND_FILES" = false ]; then
echo "Warning: None of the specified file patterns match any files."
echo "Files will be included if they appear later during execution."
fi
fi
# Function to handle script interruption
cleanup() {
echo -e "\nScript interrupted. Exiting gracefully..."
exit 0
}
# Set up trap for CTRL+C
trap cleanup SIGINT SIGTERM
# Main loop
for i in $(seq 1 $ITERATIONS); do
# Get valid prompts (non-empty lines)
mapfile -t VALID_PROMPTS < <(grep -v '^\s*$' "$PROMPTS_FILE")
PROMPT_COUNT=${#VALID_PROMPTS[@]}
if [ "$PROMPT_COUNT" -eq 0 ]; then
echo "Warning: No valid prompts found in $PROMPTS_FILE. Using default prompt."
CURRENT_PROMPT="improve code"
else
# Calculate which prompt to use (random start then cycle)
PROMPT_INDEX=$(( (RANDOM + i - 1) % PROMPT_COUNT ))
CURRENT_PROMPT="${VALID_PROMPTS[$PROMPT_INDEX]}"
fi
# Combine global prompt with current prompt if global prompt is set
FULL_PROMPT="$CURRENT_PROMPT"
if [ -n "$GLOBAL_PROMPT" ]; then
FULL_PROMPT="$GLOBAL_PROMPT $CURRENT_PROMPT"
fi
# Display the current prompt with rich formatting
echo -e "\n"
if command -v rich &> /dev/null; then
rich --print "[bold blue]Iteration $i - $(date)[/bold blue]"
rich --print "[bold green]====================================================[/bold green]"
if [ -n "$GLOBAL_PROMPT" ]; then
rich --print "[bold magenta]GLOBAL:[/bold magenta] [white]$GLOBAL_PROMPT[/white]"
fi
rich --print "[bold yellow]PROMPT:[/bold yellow] [bold white]$CURRENT_PROMPT[/bold white]"
rich --print "[bold green]====================================================[/bold green]"
else
echo "Iteration $i - $(date)"
echo "===================================================="
if [ -n "$GLOBAL_PROMPT" ]; then
echo "GLOBAL: $GLOBAL_PROMPT"
fi
echo "PROMPT: $CURRENT_PROMPT"
echo "===================================================="
fi
# Build read arguments
READ_ARGS=""
for READ_FILE in "${READ_FILES[@]}"; do
READ_ARGS="$READ_ARGS --read \"$READ_FILE\""
done
# Build read arguments
READ_ARGS=()
for READ_FILE in "${READ_FILES[@]}"; do
READ_ARGS+=(--read "$READ_FILE")
done
# Build the base command
AIDER_CMD=(aider --model "$MODEL" --subtree-only "${READ_ARGS[@]}"
--yes-always --no-show-model-warnings
--weak-model 'openrouter/google/gemini-2.0-flash-001')
# Add editor model if specified
if [ -n "$EDITOR_MODEL" ]; then
AIDER_CMD+=(--editor-model "$EDITOR_MODEL")
fi
# Add message
AIDER_CMD+=(--message "$FULL_PROMPT")
# Add files if needed - resolve globs on each iteration
if [ "$NO_FILES" = false ]; then
FILES=()
for PATTERN in "${FILE_PATTERNS[@]}"; do
# Use compgen to expand globs
while IFS= read -r FILE; do
if [ -f "$FILE" ]; then
FILES+=("$FILE")
fi
done < <(compgen -G "$PATTERN" 2>/dev/null || echo "")
done
if [ ${#FILES[@]} -gt 0 ]; then
AIDER_CMD+=("${FILES[@]}")
# Display the files being processed
if command -v rich &> /dev/null; then
rich --print "[cyan]Processing files:[/cyan] [white]${FILES[*]}[/white]"
else
echo "Processing files: ${FILES[*]}"
fi
else
echo "Warning: No files match the specified patterns at this iteration."
fi
fi
# Execute the command
"${AIDER_CMD[@]}"
if command -v rich &> /dev/null; then
rich --print "[dim]Sleeping for $SLEEP_TIME seconds...[/dim]"
else
echo "Sleeping for $SLEEP_TIME seconds..."
fi
sleep $SLEEP_TIME
done