## Description - update default configuration to use model providers instead of profiles ## Type of Change - [ ] New module - [ ] New template - [ ] Bug fix - [x] Feature/enhancement - [ ] Documentation - [ ] Other ## Module Information <!-- Delete this section if not applicable --> **Path:** `registry/coder-labs/modules/codex` **New version:** `v4.3.1` **Breaking change:** [ ] Yes [x] No ## Testing & Validation - [x] Tests pass (`bun test`) - [x] Code formatted (`bun fmt`) - [x] Changes tested locally ## Related Issues <!-- Link related issues or write "None" if not applicable -->
230 lines
6.9 KiB
Bash
230 lines
6.9 KiB
Bash
#!/bin/bash
|
|
|
|
source "$HOME"/.bashrc
|
|
set -o errexit
|
|
set -o pipefail
|
|
|
|
command_exists() {
|
|
command -v "$1" > /dev/null 2>&1
|
|
}
|
|
|
|
if [ -f "$HOME/.nvm/nvm.sh" ]; then
|
|
source "$HOME"/.nvm/nvm.sh
|
|
else
|
|
export PATH="$HOME/.npm-global/bin:$PATH"
|
|
fi
|
|
|
|
printf "Version: %s\n" "$(codex --version)"
|
|
set -o nounset
|
|
ARG_CODEX_TASK_PROMPT=$(echo -n "$ARG_CODEX_TASK_PROMPT" | base64 -d)
|
|
ARG_CONTINUE=${ARG_CONTINUE:-true}
|
|
ARG_ENABLE_AIBRIDGE=${ARG_ENABLE_AIBRIDGE:-false}
|
|
|
|
echo "=== Codex Launch Configuration ==="
|
|
printf "OpenAI API Key: %s\n" "$([ -n "$ARG_OPENAI_API_KEY" ] && echo "Provided" || echo "Not provided")"
|
|
printf "Codex Model: %s\n" "${ARG_CODEX_MODEL:-"Default"}"
|
|
printf "Start Directory: %s\n" "$ARG_CODEX_START_DIRECTORY"
|
|
printf "Has Task Prompt: %s\n" "$([ -n "$ARG_CODEX_TASK_PROMPT" ] && echo "Yes" || echo "No")"
|
|
printf "Report Tasks: %s\n" "$ARG_REPORT_TASKS"
|
|
printf "Continue Sessions: %s\n" "$ARG_CONTINUE"
|
|
printf "Enable Coder AI Bridge: %s\n" "$ARG_ENABLE_AIBRIDGE"
|
|
echo "======================================"
|
|
set +o nounset
|
|
|
|
SESSION_TRACKING_FILE="$HOME/.codex-module/.codex-task-session"
|
|
|
|
find_session_for_directory() {
|
|
local target_dir="$1"
|
|
|
|
if [ ! -f "$SESSION_TRACKING_FILE" ]; then
|
|
return 1
|
|
fi
|
|
|
|
local session_id
|
|
session_id=$(grep "^$target_dir|" "$SESSION_TRACKING_FILE" | cut -d'|' -f2 | head -1)
|
|
|
|
if [ -n "$session_id" ]; then
|
|
echo "$session_id"
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
store_session_mapping() {
|
|
local dir="$1"
|
|
local session_id="$2"
|
|
|
|
mkdir -p "$(dirname "$SESSION_TRACKING_FILE")"
|
|
|
|
if [ -f "$SESSION_TRACKING_FILE" ]; then
|
|
grep -v "^$dir|" "$SESSION_TRACKING_FILE" > "$SESSION_TRACKING_FILE.tmp" 2> /dev/null || true
|
|
mv "$SESSION_TRACKING_FILE.tmp" "$SESSION_TRACKING_FILE"
|
|
fi
|
|
|
|
echo "$dir|$session_id" >> "$SESSION_TRACKING_FILE"
|
|
}
|
|
|
|
find_recent_session_file() {
|
|
local target_dir="$1"
|
|
local sessions_dir="$HOME/.codex/sessions"
|
|
|
|
if [ ! -d "$sessions_dir" ]; then
|
|
return 1
|
|
fi
|
|
|
|
local latest_file=""
|
|
local latest_time=0
|
|
|
|
while IFS= read -r session_file; do
|
|
local file_time
|
|
file_time=$(stat -c %Y "$session_file" 2> /dev/null || stat -f %m "$session_file" 2> /dev/null || echo "0")
|
|
local first_line
|
|
first_line=$(head -n 1 "$session_file" 2> /dev/null)
|
|
local session_cwd
|
|
session_cwd=$(echo "$first_line" | grep -o '"cwd":"[^"]*"' | cut -d'"' -f4)
|
|
|
|
if [ "$session_cwd" = "$target_dir" ] && [ "$file_time" -gt "$latest_time" ]; then
|
|
latest_file="$session_file"
|
|
latest_time="$file_time"
|
|
fi
|
|
done < <(find "$sessions_dir" -type f -name "*.jsonl" 2> /dev/null)
|
|
|
|
if [ -n "$latest_file" ]; then
|
|
local first_line
|
|
first_line=$(head -n 1 "$latest_file")
|
|
local session_id
|
|
session_id=$(echo "$first_line" | grep -o '"id":"[^"]*"' | cut -d'"' -f4)
|
|
if [ -n "$session_id" ]; then
|
|
echo "$session_id"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
wait_for_session_file() {
|
|
local target_dir="$1"
|
|
local max_attempts=20
|
|
local attempt=0
|
|
|
|
while [ $attempt -lt $max_attempts ]; do
|
|
local session_id
|
|
session_id=$(find_recent_session_file "$target_dir" 2> /dev/null || echo "")
|
|
if [ -n "$session_id" ]; then
|
|
echo "$session_id"
|
|
return 0
|
|
fi
|
|
sleep 0.5
|
|
attempt=$((attempt + 1))
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
validate_codex_installation() {
|
|
if command_exists codex; then
|
|
printf "Codex is installed\n"
|
|
else
|
|
printf "Error: Codex is not installed. Please enable install_codex or install it manually\n"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
setup_workdir() {
|
|
if [ -d "${ARG_CODEX_START_DIRECTORY}" ]; then
|
|
printf "Directory '%s' exists. Changing to it.\\n" "${ARG_CODEX_START_DIRECTORY}"
|
|
cd "${ARG_CODEX_START_DIRECTORY}" || {
|
|
printf "Error: Could not change to directory '%s'.\\n" "${ARG_CODEX_START_DIRECTORY}"
|
|
exit 1
|
|
}
|
|
else
|
|
printf "Directory '%s' does not exist. Creating and changing to it.\\n" "${ARG_CODEX_START_DIRECTORY}"
|
|
mkdir -p "${ARG_CODEX_START_DIRECTORY}" || {
|
|
printf "Error: Could not create directory '%s'.\\n" "${ARG_CODEX_START_DIRECTORY}"
|
|
exit 1
|
|
}
|
|
cd "${ARG_CODEX_START_DIRECTORY}" || {
|
|
printf "Error: Could not change to directory '%s'.\\n" "${ARG_CODEX_START_DIRECTORY}"
|
|
exit 1
|
|
}
|
|
fi
|
|
}
|
|
|
|
build_codex_args() {
|
|
CODEX_ARGS=()
|
|
|
|
if [[ -n "${ARG_CODEX_MODEL}" ]]; then
|
|
CODEX_ARGS+=("--model" "${ARG_CODEX_MODEL}")
|
|
fi
|
|
|
|
if [ "$ARG_CONTINUE" = "true" ]; then
|
|
existing_session=$(find_session_for_directory "$ARG_CODEX_START_DIRECTORY" 2> /dev/null || echo "")
|
|
|
|
if [ -n "$existing_session" ]; then
|
|
printf "Found existing task session for this directory: %s\n" "$existing_session"
|
|
printf "Resuming existing session...\n"
|
|
CODEX_ARGS+=("resume" "$existing_session")
|
|
else
|
|
printf "No existing task session found for this directory\n"
|
|
printf "Starting new task session...\n"
|
|
|
|
if [ -n "$ARG_CODEX_TASK_PROMPT" ]; then
|
|
if [ "${ARG_REPORT_TASKS}" == "true" ]; then
|
|
PROMPT="Complete the task at hand in one go. Every step of the way, report your progress using coder_report_task tool with proper summary and statuses. Your task at hand: $ARG_CODEX_TASK_PROMPT"
|
|
else
|
|
PROMPT="Your task at hand: $ARG_CODEX_TASK_PROMPT"
|
|
fi
|
|
CODEX_ARGS+=("$PROMPT")
|
|
fi
|
|
fi
|
|
else
|
|
printf "Continue disabled, starting fresh session\n"
|
|
|
|
if [ -n "$ARG_CODEX_TASK_PROMPT" ]; then
|
|
if [ "${ARG_REPORT_TASKS}" == "true" ]; then
|
|
PROMPT="Complete the task at hand in one go. Every step of the way, report your progress using Coder.coder_report_task tool with proper summary and statuses. Your task at hand: $ARG_CODEX_TASK_PROMPT"
|
|
else
|
|
PROMPT="Your task at hand: $ARG_CODEX_TASK_PROMPT"
|
|
fi
|
|
CODEX_ARGS+=("$PROMPT")
|
|
fi
|
|
fi
|
|
}
|
|
|
|
capture_session_id() {
|
|
if [ "$ARG_CONTINUE" = "true" ] && [ -z "$existing_session" ]; then
|
|
printf "Capturing new session ID...\n"
|
|
new_session=$(wait_for_session_file "$ARG_CODEX_START_DIRECTORY" || echo "")
|
|
|
|
if [ -n "$new_session" ]; then
|
|
store_session_mapping "$ARG_CODEX_START_DIRECTORY" "$new_session"
|
|
printf "✓ Session tracked: %s\n" "$new_session"
|
|
printf "This session will be automatically resumed on next restart\n"
|
|
else
|
|
printf "⚠ Could not capture session ID after 10s timeout\n"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
start_codex() {
|
|
printf "Starting Codex with arguments: %s\n" "${CODEX_ARGS[*]}"
|
|
# AGENTAPI_BOUNDARY_PREFIX is set by the agentapi module's main.sh when
|
|
# enable_boundary=true. It points to a wrapper script that runs the command
|
|
# through coder boundary, sandboxing only the agent process.
|
|
if [ -n "${AGENTAPI_BOUNDARY_PREFIX:-}" ]; then
|
|
printf "Starting with coder boundary enabled\n"
|
|
agentapi server --type codex --term-width 67 --term-height 1190 -- \
|
|
"${AGENTAPI_BOUNDARY_PREFIX}" codex "${CODEX_ARGS[@]}" &
|
|
else
|
|
agentapi server --type codex --term-width 67 --term-height 1190 -- codex "${CODEX_ARGS[@]}" &
|
|
fi
|
|
capture_session_id
|
|
}
|
|
|
|
validate_codex_installation
|
|
setup_workdir
|
|
build_codex_args
|
|
start_codex
|