diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/infinite_canvas/run_orchestration_dev.sh	Tue Aug 18 19:14:53 2026 -0700
@@ -0,0 +1,179 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+RUNFILES_ROOT="${RUNFILES_DIR:-$0.runfiles}"
+export RUNFILES_DIR="$RUNFILES_ROOT"
+
+find_runfile() {
+  local pattern="$1"
+  local path
+  path="$(find -L "$RUNFILES_ROOT" -path "$pattern" -print -quit)"
+  if [[ -z "$path" ]]; then
+    echo "Could not locate orchestration runtime file: $pattern" >&2
+    exit 1
+  fi
+  realpath "$path"
+}
+
+find_config() {
+  local candidate
+  for candidate in \
+    "${BUILD_WORKSPACE_DIRECTORY:-}/mrjunejune/.config" \
+    "$PWD/mrjunejune/.config" \
+    "${HOME:-}/.config/mrjunejune/.config"; do
+    [[ "$candidate" != /mrjunejune/.config ]] || continue
+    [[ "$candidate" != /.config/mrjunejune/.config ]] || continue
+    if [[ -f "$candidate" ]]; then
+      realpath "$candidate"
+      return 0
+    fi
+  done
+  return 1
+}
+
+load_config() {
+  local config_path="$1"
+  local line key value
+  while IFS= read -r line || [[ -n "$line" ]]; do
+    line="${line%$'\r'}"
+    [[ "$line" =~ ^[[:space:]]*$ ]] && continue
+    [[ "$line" =~ ^[[:space:]]*# ]] && continue
+    if [[ "$line" != *=* ]]; then
+      echo "Invalid config line in $config_path" >&2
+      exit 1
+    fi
+    key="${line%%=*}"
+    value="${line#*=}"
+    key="${key#"${key%%[![:space:]]*}"}"
+    key="${key%"${key##*[![:space:]]}"}"
+    case "$key" in
+      LITELLM_MASTER_KEY|LITELLM_HOST|LITELLM_PORT|LITELLM_MODEL|\
+      LITELLM_WIRE_API|GITHUB_COPILOT_TOKEN_DIR|\
+      MRJUNEJUNE_INFERENCE_STATE|COPILOT_SESSION_IDLE_SECONDS|\
+      COPILOT_MAX_SESSIONS)
+        printf -v "$key" '%s' "$value"
+        ;;
+    esac
+  done < "$config_path"
+}
+
+dictation="$(find_runfile '*/dictation/server')"
+dictation_bin="$(find_runfile '*/dictation/dictation_bin')"
+canvas="$(find_runfile '*/infinite_canvas/dev_linux')"
+sidecar_launcher="$(find_runfile '*/mrjunejune/inference_sidecar_launcher.sh')"
+sidecar_zip="$(find_runfile '*/mrjunejune/inference/copilot_sidecar.zip')"
+litellm_zip="$(find_runfile '*/mrjunejune/inference/litellm_proxy.zip')"
+litellm_config="$(find_runfile '*/mrjunejune/inference/litellm_config.yaml')"
+copilot_cli="$(find_runfile '*copilot_cli_linux_x86_64/copilot')"
+python="$(find_runfile '*python_3_11_x86_64-unknown-linux-gnu/bin/python3')"
+
+config_file="$(find_config || true)"
+if [[ -z "$config_file" ]]; then
+  echo "Missing mrjunejune/.config." >&2
+  echo "Copy mrjunejune/.config.development to mrjunejune/.config." >&2
+  exit 1
+fi
+load_config "$config_file"
+
+state_root="${MRJUNEJUNE_INFERENCE_STATE:-${XDG_STATE_HOME:-$HOME/.local/state}/mrjunejune/inference}"
+token_dir="${GITHUB_COPILOT_TOKEN_DIR:-$state_root/litellm-copilot}"
+cache_root="$state_root/cache"
+mkdir -p "$state_root/copilot" "$token_dir" "$cache_root"
+chmod 700 "$state_root" "$state_root/copilot" "$token_dir" "$cache_root"
+
+if [[ ! -s "$token_dir/access-token" ]]; then
+  echo "GitHub Copilot is not authenticated." >&2
+  echo "Run: bazel run //mrjunejune:run_inference_stack -- --authenticate" >&2
+  exit 1
+fi
+
+if [[ -z "${LITELLM_MASTER_KEY:-}" ]]; then
+  umask 077
+  LITELLM_MASTER_KEY="sk-$("$python" -c 'import secrets; print(secrets.token_hex(24))')"
+fi
+
+litellm_host="${LITELLM_HOST:-127.0.0.1}"
+litellm_port="${LITELLM_PORT:-4000}"
+service_pids=()
+
+cleanup() {
+  local status=$?
+  trap - EXIT INT TERM
+  for pid in "${service_pids[@]}"; do
+    kill -- "-$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true
+  done
+  for pid in "${service_pids[@]}"; do
+    wait "$pid" 2>/dev/null || true
+  done
+  exit "$status"
+}
+
+trap cleanup EXIT
+trap 'exit 130' INT
+trap 'exit 143' TERM
+
+export GITHUB_COPILOT_TOKEN_DIR="$token_dir"
+export XDG_CACHE_HOME="$cache_root"
+export DICTATION_MODEL_DIR="${DICTATION_MODEL_DIR:-$HOME/.cache/zenbu/faster-whisper-small}"
+export LITELLM_MASTER_KEY
+setsid "$python" "$litellm_zip" \
+  --config "$litellm_config" \
+  --host "$litellm_host" \
+  --port "$litellm_port" &
+service_pids+=("$!")
+
+setsid "$dictation" "$dictation_bin" server &
+service_pids+=("$!")
+
+for _ in {1..150}; do
+  if curl --fail --silent \
+      --connect-timeout 1 \
+      --max-time 2 \
+      "http://${litellm_host}:${litellm_port}/health/readiness" \
+      >/dev/null; then
+    break
+  fi
+  if ! kill -0 "${service_pids[0]}" 2>/dev/null; then
+    echo "Copilot LiteLLM gateway exited before becoming ready." >&2
+    exit 1
+  fi
+  sleep 0.1
+done
+if ! curl --fail --silent \
+    --connect-timeout 1 \
+    --max-time 2 \
+    "http://${litellm_host}:${litellm_port}/health/readiness" \
+    >/dev/null; then
+  echo "Copilot LiteLLM readiness timed out." >&2
+  exit 1
+fi
+
+for _ in {1..120}; do
+  if curl --silent --fail --output /dev/null http://127.0.0.1:8090/; then
+    break
+  fi
+  if ! kill -0 "${service_pids[1]}" 2>/dev/null; then
+    echo "The dictation service exited before becoming ready." >&2
+    exit 1
+  fi
+  sleep 0.25
+done
+if ! curl --silent --fail --output /dev/null http://127.0.0.1:8090/; then
+  echo "Timed out waiting for dictation at http://127.0.0.1:8090." >&2
+  exit 1
+fi
+
+export MRJUNEJUNE_PYTHON_PATH="$python"
+export MRJUNEJUNE_SIDECAR_ZIP="$sidecar_zip"
+export COPILOT_SIDECAR_HOME="$state_root/copilot"
+export LITELLM_BASE_URL="http://${litellm_host}:${litellm_port}/v1"
+export LITELLM_MODEL="${LITELLM_MODEL:-jrpg-copilot}"
+export LITELLM_WIRE_API="${LITELLM_WIRE_API:-completions}"
+export LITELLM_API_KEY="$LITELLM_MASTER_KEY"
+export INFINITE_CANVAS_COPILOT_SIDECAR_PATH="$sidecar_launcher"
+export INFINITE_CANVAS_COPILOT_CLI_PATH="$copilot_cli"
+
+echo "Copilot orchestration is ready. Starting Infinite Canvas."
+canvas_status=0
+"$canvas" "$@" || canvas_status=$?
+exit "$canvas_status"