fix: Fixed the bash prompt utils so that they correctly show output when being run by a tool invocation
This commit is contained in:
+29
-119
@@ -7,121 +7,13 @@ export AUTO_CONFIRM=true
|
|||||||
|
|
||||||
# @env LLM_OUTPUT=/dev/stdout
|
# @env LLM_OUTPUT=/dev/stdout
|
||||||
# @env LLM_AGENT_VAR_PROJECT_DIR=.
|
# @env LLM_AGENT_VAR_PROJECT_DIR=.
|
||||||
# @describe Sisyphus orchestrator tools for delegating to specialized agents
|
# @describe Sisyphus orchestrator tools (project info, build, test, user interaction)
|
||||||
|
|
||||||
_project_dir() {
|
_project_dir() {
|
||||||
local dir="${LLM_AGENT_VAR_PROJECT_DIR:-.}"
|
local dir="${LLM_AGENT_VAR_PROJECT_DIR:-.}"
|
||||||
(cd "${dir}" 2>/dev/null && pwd) || echo "${dir}"
|
(cd "${dir}" 2>/dev/null && pwd) || echo "${dir}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# @cmd Initialize context for a new task (call at the start of multi-step work)
|
|
||||||
# @option --goal! Description of the overall task/goal
|
|
||||||
start_task() {
|
|
||||||
local project_dir
|
|
||||||
project_dir=$(_project_dir)
|
|
||||||
|
|
||||||
export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}"
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
init_context "${argc_goal}"
|
|
||||||
|
|
||||||
cat <<-EOF >> "$LLM_OUTPUT"
|
|
||||||
$(green "Context initialized for task: ${argc_goal}")
|
|
||||||
Context file: ${project_dir}/.loki-context
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# @cmd Add a finding to the shared context (useful for recording discoveries)
|
|
||||||
# @option --source! Source of the finding (e.g., "manual", "explore", "coder")
|
|
||||||
# @option --finding! The finding to record
|
|
||||||
record_finding() {
|
|
||||||
local project_dir
|
|
||||||
project_dir=$(_project_dir)
|
|
||||||
|
|
||||||
export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}"
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
append_context "${argc_source}" "${argc_finding}"
|
|
||||||
|
|
||||||
green "Recorded finding from ${argc_source}" >> "$LLM_OUTPUT"
|
|
||||||
}
|
|
||||||
|
|
||||||
# @cmd Show current accumulated context
|
|
||||||
show_context() {
|
|
||||||
local project_dir
|
|
||||||
project_dir=$(_project_dir)
|
|
||||||
|
|
||||||
export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}"
|
|
||||||
local context
|
|
||||||
context=$(read_context)
|
|
||||||
|
|
||||||
if [[ -n "${context}" ]]; then
|
|
||||||
cat <<-EOF >> "$LLM_OUTPUT"
|
|
||||||
$(info "Current Context:")
|
|
||||||
|
|
||||||
${context}
|
|
||||||
EOF
|
|
||||||
else
|
|
||||||
warn "No context file found. Use start_task to initialize." >> "$LLM_OUTPUT"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# @cmd Clear the context file (call when task is complete)
|
|
||||||
end_task() {
|
|
||||||
local project_dir
|
|
||||||
project_dir=$(_project_dir)
|
|
||||||
|
|
||||||
export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}"
|
|
||||||
clear_context
|
|
||||||
|
|
||||||
green "Context cleared. Task complete." >> "$LLM_OUTPUT"
|
|
||||||
}
|
|
||||||
|
|
||||||
# @cmd Delegate a task to a specialized agent
|
|
||||||
# @option --agent! Agent to delegate to: explore, coder, or oracle
|
|
||||||
# @option --task! Specific task description for the agent
|
|
||||||
# @option --context Additional context (file paths, patterns, constraints)
|
|
||||||
delegate_to_agent() {
|
|
||||||
local extra_context="${argc_context:-}"
|
|
||||||
local project_dir
|
|
||||||
project_dir=$(_project_dir)
|
|
||||||
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
if [[ ! "${argc_agent}" =~ ^(explore|coder|oracle)$ ]]; then
|
|
||||||
error "Invalid agent: ${argc_agent}. Must be explore, coder, or oracle" >> "$LLM_OUTPUT"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}"
|
|
||||||
|
|
||||||
info "Delegating to ${argc_agent} agent..." >> "$LLM_OUTPUT"
|
|
||||||
echo "" >> "$LLM_OUTPUT"
|
|
||||||
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
local prompt="${argc_task}"
|
|
||||||
if [[ -n "${extra_context}" ]]; then
|
|
||||||
prompt="$(printf "%s\n\nAdditional Context:\n%s\n" "${argc_task}" "${extra_context}")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat <<-EOF >> "$LLM_OUTPUT"
|
|
||||||
$(cyan "------------------------------------------")
|
|
||||||
DELEGATING TO: ${argc_agent}
|
|
||||||
TASK: ${argc_task}
|
|
||||||
$(cyan "------------------------------------------")
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
local output
|
|
||||||
output=$(invoke_agent_with_summary "${argc_agent}" "${prompt}" \
|
|
||||||
--agent-variable project_dir "${project_dir}" 2>&1) || true
|
|
||||||
|
|
||||||
cat <<-EOF >> "$LLM_OUTPUT"
|
|
||||||
${output}
|
|
||||||
|
|
||||||
$(cyan "------------------------------------------")
|
|
||||||
DELEGATION COMPLETE: ${argc_agent}
|
|
||||||
$(cyan "------------------------------------------")
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# @cmd Get project information and structure
|
# @cmd Get project information and structure
|
||||||
get_project_info() {
|
get_project_info() {
|
||||||
local project_dir
|
local project_dir
|
||||||
@@ -254,17 +146,27 @@ search_content() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# @cmd Ask the user to select ONE option from a list. The first option should be your recommended choice; append '(Recommended)' to its label. Returns the selected option's label text.
|
# @cmd Ask the user to select ONE option from a list. The first option should be your recommended choice — append '(Recommended)' to its label. Returns the selected option's label text.
|
||||||
# @option --question! The question to present to the user
|
# @option --question! The question to present to the user
|
||||||
# @option --options+ The list of options to present (first option = recommended, append '(Recommended)' to its label)
|
# @option --options! The JSON array of options to present (first option = recommended, append '(Recommended)' to its label)
|
||||||
ask_user() {
|
ask_user() {
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
local question="${argc_question}"
|
local question="${argc_question}"
|
||||||
|
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
local opts=("${argc_options[@]}")
|
local options_json="${argc_options}"
|
||||||
|
|
||||||
|
local opts=()
|
||||||
|
|
||||||
|
# Convert JSON array string -> Bash array
|
||||||
|
if ! mapfile -t opts < <(jq -r '.[]' <<<"$options_json"); then
|
||||||
|
error "Invalid JSON in argc_options" >> "$LLM_OUTPUT"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
local opts_count="${#opts[@]}"
|
local opts_count="${#opts[@]}"
|
||||||
|
|
||||||
if [[ "${opts_count}" -eq 0 ]]; then
|
if [[ "$opts_count" -eq 0 ]]; then
|
||||||
error "No options provided for ask_user" >> "$LLM_OUTPUT"
|
error "No options provided for ask_user" >> "$LLM_OUTPUT"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -272,7 +174,7 @@ ask_user() {
|
|||||||
info "Asking user: ${question}" >> "$LLM_OUTPUT"
|
info "Asking user: ${question}" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
local selected_index
|
local selected_index
|
||||||
selected_index=$(list "${question}" "${opts[@]}")
|
selected_index=$(list "$question" "${opts[@]}" 2>/dev/tty)
|
||||||
|
|
||||||
local selected_label="${opts[$selected_index]}"
|
local selected_label="${opts[$selected_index]}"
|
||||||
|
|
||||||
@@ -290,7 +192,7 @@ ask_user_confirm() {
|
|||||||
info "Asking user: ${question}" >> "$LLM_OUTPUT"
|
info "Asking user: ${question}" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
local result
|
local result
|
||||||
result=$(confirm "${question}")
|
result=$(confirm "${question}" 2>/dev/tty)
|
||||||
|
|
||||||
if [[ "${result}" == "1" ]]; then
|
if [[ "${result}" == "1" ]]; then
|
||||||
echo "User confirmed: yes" >> "$LLM_OUTPUT"
|
echo "User confirmed: yes" >> "$LLM_OUTPUT"
|
||||||
@@ -301,12 +203,20 @@ ask_user_confirm() {
|
|||||||
|
|
||||||
# @cmd Ask the user to select MULTIPLE options from a list (checkbox). Returns the labels of all selected items.
|
# @cmd Ask the user to select MULTIPLE options from a list (checkbox). Returns the labels of all selected items.
|
||||||
# @option --question! The question to present to the user
|
# @option --question! The question to present to the user
|
||||||
# @option --options+ The list of options the user can select from (multiple selections allowed)
|
# @option --options! The JSON array of options to present
|
||||||
ask_user_checkbox() {
|
ask_user_checkbox() {
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
local question="${argc_question}"
|
local question="${argc_question}"
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
local opts=("${argc_options[@]}")
|
local options_json="${argc_options}"
|
||||||
|
|
||||||
|
local opts=()
|
||||||
|
|
||||||
|
# Convert JSON array string -> Bash array
|
||||||
|
if ! mapfile -t opts < <(jq -r '.[]' <<<"$options_json"); then
|
||||||
|
error "Invalid JSON in argc_options" >> "$LLM_OUTPUT"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
local opts_count="${#opts[@]}"
|
local opts_count="${#opts[@]}"
|
||||||
|
|
||||||
if [[ "${opts_count}" -eq 0 ]]; then
|
if [[ "${opts_count}" -eq 0 ]]; then
|
||||||
@@ -317,7 +227,7 @@ ask_user_checkbox() {
|
|||||||
info "Asking user (select multiple): ${question}" >> "$LLM_OUTPUT"
|
info "Asking user (select multiple): ${question}" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
local checked_indices
|
local checked_indices
|
||||||
checked_indices=$(checkbox "${question}" "${opts[@]}")
|
checked_indices=$(checkbox "${question}" "${opts[@]}" 2>/dev/tty)
|
||||||
|
|
||||||
local selected_labels=()
|
local selected_labels=()
|
||||||
for idx in ${checked_indices}; do
|
for idx in ${checked_indices}; do
|
||||||
@@ -345,7 +255,7 @@ ask_user_input() {
|
|||||||
info "Asking user: ${question}" >> "$LLM_OUTPUT"
|
info "Asking user: ${question}" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
local user_text
|
local user_text
|
||||||
user_text=$(input "${question}")
|
user_text=$(input "${question}" 2>/dev/tty)
|
||||||
|
|
||||||
cat <<-EOF >> "$LLM_OUTPUT"
|
cat <<-EOF >> "$LLM_OUTPUT"
|
||||||
User input: ${user_text}
|
User input: ${user_text}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ _cursor_blink_off() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cursor_to() {
|
_cursor_to() {
|
||||||
echo -en "\033[$1;$2H" >&2
|
echo -en "\033[$1;${2:-1}H" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
@@ -133,7 +133,7 @@ _key_input() {
|
|||||||
_read_stdin -rsn2 b
|
_read_stdin -rsn2 b
|
||||||
fi
|
fi
|
||||||
|
|
||||||
declare input="${a}${b}"
|
declare input="${a}${b:-}"
|
||||||
case "$input" in
|
case "$input" in
|
||||||
"${ESC}[A" | "k") echo up ;;
|
"${ESC}[A" | "k") echo up ;;
|
||||||
"${ESC}[B" | "j") echo down ;;
|
"${ESC}[B" | "j") echo down ;;
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ Prompt for text input
|
|||||||
|
|
||||||
**Example With Validation:**
|
**Example With Validation:**
|
||||||
```bash
|
```bash
|
||||||
text=$(with_validation 'input "Please enter something:"' validate_present)
|
text=$(with_validation 'input "Please enter something:"' validate_present 2>/dev/tty)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Example Without Validation:**
|
**Example Without Validation:**
|
||||||
```bash
|
```bash
|
||||||
text=$(input "Please enter something:")
|
text=$(input "Please enter something:" 2>/dev/tty)
|
||||||
```
|
```
|
||||||
|
|
||||||
### confirm
|
### confirm
|
||||||
@@ -81,7 +81,7 @@ Show a confirm dialog with options for yes/no
|
|||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
```bash
|
```bash
|
||||||
confirmed=$(confirm "Do the thing?")
|
confirmed=$(confirm "Do the thing?" 2>/dev/tty)
|
||||||
if [[ $confirmed == "0" ]]; then echo "No"; else echo "Yes"; fi
|
if [[ $confirmed == "0" ]]; then echo "No"; else echo "Yes"; fi
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ keys that then returns the chosen option.
|
|||||||
**Example:**
|
**Example:**
|
||||||
```bash
|
```bash
|
||||||
options=("one" "two" "three" "four")
|
options=("one" "two" "three" "four")
|
||||||
choice=$(list "Select an item" "${options[@]}")
|
choice=$(list "Select an item" "${options[@]}" 2>/dev/tty)
|
||||||
echo "Your choice: ${options[$choice]}"
|
echo "Your choice: ${options[$choice]}"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ and enter keys that then returns the chosen options.
|
|||||||
**Example:**
|
**Example:**
|
||||||
```bash
|
```bash
|
||||||
options=("one" "two" "three" "four")
|
options=("one" "two" "three" "four")
|
||||||
checked=$(checkbox "Select one or more items" "${options[@]}")
|
checked=$(checkbox "Select one or more items" "${options[@]}" 2>/dev/tty)
|
||||||
echo "Your choices: ${checked}"
|
echo "Your choices: ${checked}"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -124,12 +124,12 @@ validate_password() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
pass=$(with_validate 'password "Enter your password"' validate_password)
|
pass=$(with_validate 'password "Enter your password"' validate_password 2>/dev/tty)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Example Without Validation:**
|
**Example Without Validation:**
|
||||||
```bash
|
```bash
|
||||||
pass="$(password "Enter your password:")"
|
pass="$(password "Enter your password:" 2>/dev/tty)"
|
||||||
```
|
```
|
||||||
|
|
||||||
### editor
|
### editor
|
||||||
@@ -137,7 +137,7 @@ Open the default editor (`$EDITOR`); if none is set, default back to `vi`
|
|||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
```bash
|
```bash
|
||||||
text=$(editor "Please enter something in the editor")
|
text=$(editor "Please enter something in the editor" 2>/dev/tty)
|
||||||
echo -e "You wrote:\n${text}"
|
echo -e "You wrote:\n${text}"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ validation functions returns 0.
|
|||||||
**Example:**
|
**Example:**
|
||||||
```bash
|
```bash
|
||||||
# Using the built-in 'validate_present' validator
|
# Using the built-in 'validate_present' validator
|
||||||
text=$(with_validate 'input "Please enter something and confirm with enter"' validate_present)
|
text=$(with_validate 'input "Please enter something and confirm with enter"' validate_present 2>/dev/tty)
|
||||||
|
|
||||||
# Using a custom validator; e.g. for password
|
# Using a custom validator; e.g. for password
|
||||||
validate_password() {
|
validate_password() {
|
||||||
@@ -159,7 +159,7 @@ validate_password() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
pass=$(with_validate 'password "Enter random password"' validate_password)
|
pass=$(with_validate 'password "Enter random password"' validate_password 2>/dev/tty)
|
||||||
```
|
```
|
||||||
|
|
||||||
### validate_present
|
### validate_present
|
||||||
@@ -169,7 +169,7 @@ Validate that the prompt returned a value.
|
|||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
```bash
|
```bash
|
||||||
text=$(with_validate 'input "Please enter something and confirm with enter"' validate_present)
|
text=$(with_validate 'input "Please enter something and confirm with enter"' validate_present 2>/dev/tty)
|
||||||
```
|
```
|
||||||
|
|
||||||
### detect_os
|
### detect_os
|
||||||
|
|||||||
Reference in New Issue
Block a user