comparison infinite_canvas/run_orchestration_dev.sh @ 280:49e9e591c9bb

Add persistent dictation, prewarmed WebRTC speech input, Copilot SDK routing, animated conversation lifecycle controls, parking, and architecture coverage.
author MrJuneJune <me@mrjunejune.com>
date Tue, 18 Aug 2026 19:14:53 -0700
parents
children
comparison
equal deleted inserted replaced
279:b3b547563ec7 280:49e9e591c9bb
1 #!/usr/bin/env bash
2 set -euo pipefail
3
4 RUNFILES_ROOT="${RUNFILES_DIR:-$0.runfiles}"
5 export RUNFILES_DIR="$RUNFILES_ROOT"
6
7 find_runfile() {
8 local pattern="$1"
9 local path
10 path="$(find -L "$RUNFILES_ROOT" -path "$pattern" -print -quit)"
11 if [[ -z "$path" ]]; then
12 echo "Could not locate orchestration runtime file: $pattern" >&2
13 exit 1
14 fi
15 realpath "$path"
16 }
17
18 find_config() {
19 local candidate
20 for candidate in \
21 "${BUILD_WORKSPACE_DIRECTORY:-}/mrjunejune/.config" \
22 "$PWD/mrjunejune/.config" \
23 "${HOME:-}/.config/mrjunejune/.config"; do
24 [[ "$candidate" != /mrjunejune/.config ]] || continue
25 [[ "$candidate" != /.config/mrjunejune/.config ]] || continue
26 if [[ -f "$candidate" ]]; then
27 realpath "$candidate"
28 return 0
29 fi
30 done
31 return 1
32 }
33
34 load_config() {
35 local config_path="$1"
36 local line key value
37 while IFS= read -r line || [[ -n "$line" ]]; do
38 line="${line%$'\r'}"
39 [[ "$line" =~ ^[[:space:]]*$ ]] && continue
40 [[ "$line" =~ ^[[:space:]]*# ]] && continue
41 if [[ "$line" != *=* ]]; then
42 echo "Invalid config line in $config_path" >&2
43 exit 1
44 fi
45 key="${line%%=*}"
46 value="${line#*=}"
47 key="${key#"${key%%[![:space:]]*}"}"
48 key="${key%"${key##*[![:space:]]}"}"
49 case "$key" in
50 LITELLM_MASTER_KEY|LITELLM_HOST|LITELLM_PORT|LITELLM_MODEL|\
51 LITELLM_WIRE_API|GITHUB_COPILOT_TOKEN_DIR|\
52 MRJUNEJUNE_INFERENCE_STATE|COPILOT_SESSION_IDLE_SECONDS|\
53 COPILOT_MAX_SESSIONS)
54 printf -v "$key" '%s' "$value"
55 ;;
56 esac
57 done < "$config_path"
58 }
59
60 dictation="$(find_runfile '*/dictation/server')"
61 dictation_bin="$(find_runfile '*/dictation/dictation_bin')"
62 canvas="$(find_runfile '*/infinite_canvas/dev_linux')"
63 sidecar_launcher="$(find_runfile '*/mrjunejune/inference_sidecar_launcher.sh')"
64 sidecar_zip="$(find_runfile '*/mrjunejune/inference/copilot_sidecar.zip')"
65 litellm_zip="$(find_runfile '*/mrjunejune/inference/litellm_proxy.zip')"
66 litellm_config="$(find_runfile '*/mrjunejune/inference/litellm_config.yaml')"
67 copilot_cli="$(find_runfile '*copilot_cli_linux_x86_64/copilot')"
68 python="$(find_runfile '*python_3_11_x86_64-unknown-linux-gnu/bin/python3')"
69
70 config_file="$(find_config || true)"
71 if [[ -z "$config_file" ]]; then
72 echo "Missing mrjunejune/.config." >&2
73 echo "Copy mrjunejune/.config.development to mrjunejune/.config." >&2
74 exit 1
75 fi
76 load_config "$config_file"
77
78 state_root="${MRJUNEJUNE_INFERENCE_STATE:-${XDG_STATE_HOME:-$HOME/.local/state}/mrjunejune/inference}"
79 token_dir="${GITHUB_COPILOT_TOKEN_DIR:-$state_root/litellm-copilot}"
80 cache_root="$state_root/cache"
81 mkdir -p "$state_root/copilot" "$token_dir" "$cache_root"
82 chmod 700 "$state_root" "$state_root/copilot" "$token_dir" "$cache_root"
83
84 if [[ ! -s "$token_dir/access-token" ]]; then
85 echo "GitHub Copilot is not authenticated." >&2
86 echo "Run: bazel run //mrjunejune:run_inference_stack -- --authenticate" >&2
87 exit 1
88 fi
89
90 if [[ -z "${LITELLM_MASTER_KEY:-}" ]]; then
91 umask 077
92 LITELLM_MASTER_KEY="sk-$("$python" -c 'import secrets; print(secrets.token_hex(24))')"
93 fi
94
95 litellm_host="${LITELLM_HOST:-127.0.0.1}"
96 litellm_port="${LITELLM_PORT:-4000}"
97 service_pids=()
98
99 cleanup() {
100 local status=$?
101 trap - EXIT INT TERM
102 for pid in "${service_pids[@]}"; do
103 kill -- "-$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true
104 done
105 for pid in "${service_pids[@]}"; do
106 wait "$pid" 2>/dev/null || true
107 done
108 exit "$status"
109 }
110
111 trap cleanup EXIT
112 trap 'exit 130' INT
113 trap 'exit 143' TERM
114
115 export GITHUB_COPILOT_TOKEN_DIR="$token_dir"
116 export XDG_CACHE_HOME="$cache_root"
117 export DICTATION_MODEL_DIR="${DICTATION_MODEL_DIR:-$HOME/.cache/zenbu/faster-whisper-small}"
118 export LITELLM_MASTER_KEY
119 setsid "$python" "$litellm_zip" \
120 --config "$litellm_config" \
121 --host "$litellm_host" \
122 --port "$litellm_port" &
123 service_pids+=("$!")
124
125 setsid "$dictation" "$dictation_bin" server &
126 service_pids+=("$!")
127
128 for _ in {1..150}; do
129 if curl --fail --silent \
130 --connect-timeout 1 \
131 --max-time 2 \
132 "http://${litellm_host}:${litellm_port}/health/readiness" \
133 >/dev/null; then
134 break
135 fi
136 if ! kill -0 "${service_pids[0]}" 2>/dev/null; then
137 echo "Copilot LiteLLM gateway exited before becoming ready." >&2
138 exit 1
139 fi
140 sleep 0.1
141 done
142 if ! curl --fail --silent \
143 --connect-timeout 1 \
144 --max-time 2 \
145 "http://${litellm_host}:${litellm_port}/health/readiness" \
146 >/dev/null; then
147 echo "Copilot LiteLLM readiness timed out." >&2
148 exit 1
149 fi
150
151 for _ in {1..120}; do
152 if curl --silent --fail --output /dev/null http://127.0.0.1:8090/; then
153 break
154 fi
155 if ! kill -0 "${service_pids[1]}" 2>/dev/null; then
156 echo "The dictation service exited before becoming ready." >&2
157 exit 1
158 fi
159 sleep 0.25
160 done
161 if ! curl --silent --fail --output /dev/null http://127.0.0.1:8090/; then
162 echo "Timed out waiting for dictation at http://127.0.0.1:8090." >&2
163 exit 1
164 fi
165
166 export MRJUNEJUNE_PYTHON_PATH="$python"
167 export MRJUNEJUNE_SIDECAR_ZIP="$sidecar_zip"
168 export COPILOT_SIDECAR_HOME="$state_root/copilot"
169 export LITELLM_BASE_URL="http://${litellm_host}:${litellm_port}/v1"
170 export LITELLM_MODEL="${LITELLM_MODEL:-jrpg-copilot}"
171 export LITELLM_WIRE_API="${LITELLM_WIRE_API:-completions}"
172 export LITELLM_API_KEY="$LITELLM_MASTER_KEY"
173 export INFINITE_CANVAS_COPILOT_SIDECAR_PATH="$sidecar_launcher"
174 export INFINITE_CANVAS_COPILOT_CLI_PATH="$copilot_cli"
175
176 echo "Copilot orchestration is ready. Starting Infinite Canvas."
177 canvas_status=0
178 "$canvas" "$@" || canvas_status=$?
179 exit "$canvas_status"