From 3c03faed3a0d3536ce54ad12fc7fcab5bf2b90bd Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sun, 3 May 2026 13:54:29 +0200 Subject: [PATCH] u/complete: persistent copilot session per cwd; add freeloader hook - Replace per-invocation s/bfg calls with a persistent *-copilot session looked up from s/idx; first call in a cwd spawns the session, subsequent calls reuse it, skipping s/new overhead - Clear context after each completion so inference stays fast - Fix session lookup to read s/idx instead of globbing the 9P mount - Add x/freeloader turnError hook to copilot.json Co-Authored-By: Claude Sonnet 4.6 --- agents/copilot.json | 7 +++++- scripts/u/complete | 57 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/agents/copilot.json b/agents/copilot.json index 87acdfc..32fa871 100644 --- a/agents/copilot.json +++ b/agents/copilot.json @@ -1,4 +1,9 @@ { "prompt": [], - "trustedTools": [] + "trustedTools": [], + "hooks": { + "turnError": [ + "$OLLIE/x/freeloader $OLLIE_SESSION_ID" + ] + } } diff --git a/scripts/u/complete b/scripts/u/complete index bb695c8..364653f 100644 --- a/scripts/u/complete +++ b/scripts/u/complete @@ -6,7 +6,6 @@ PREFIX_MAX=4000 SUFFIX_MAX=1000 MOUNT=${OLLIE:-$HOME/mnt/ollie} -BFG="${0%/*}/../s/bfg" cmd=${0##*/} die() { printf '%s: %s\n' "$cmd" "$*" >&2; exit 1; } @@ -42,6 +41,41 @@ done [ -z "${winid:-}" ] || [ "$winid" = "0" ] && die "must be run from an acme window" +# Find or create a copilot session for the current working directory. +# Reuses an existing *-copilot session in this cwd if one is alive, +# otherwise spawns a new one. +find_or_create_session() { + local target_cwd="$1" + local sdir state scwd id kv deadline + + while IFS= read -r line; do + id=${line%%$'\t'*} + case "$id" in *-copilot) ;; *) continue ;; esac + sdir="$MOUNT/s/$id" + [ -d "$sdir" ] || continue + scwd=$(cat "$sdir/cwd" 2>/dev/null) || continue + [ "$scwd" = "$target_cwd" ] || continue + state=$(cat "$sdir/state" 2>/dev/null) || continue + case "$state" in failed*|error*) continue ;; esac + printf '%s\n' "$id" + return 0 + done < "$MOUNT/s/idx" + + id="$(date +%s%N)-copilot" + kv="name=${id} +cwd=${target_cwd} +agent=copilot +backend=${backend} +model=${model}" + printf '%s\n' "$kv" > "$MOUNT/s/new" || die "failed to create copilot session" + + deadline=$(( $(date +%s) + 5 )) + until [ -d "$MOUNT/s/$id" ] || [ "$(date +%s)" -ge "$deadline" ]; do sleep 0.05; done + [ -d "$MOUNT/s/$id" ] || die "timeout waiting for copilot session" + + printf '%s\n' "$id" +} + # Get filename for language context (last field of ctl line 1) filename=$(9p read acme/$winid/ctl | awk 'NR==1{print $NF}') @@ -62,16 +96,29 @@ suffix=$(9p read acme/$winid/data) prefix="${prefix: -$PREFIX_MAX}" suffix="${suffix:0:$SUFFIX_MAX}" -# Query model -result=$("$BFG" -agent copilot -model "$model" -backend "$backend" \ - "Complete the code at the cursor in ${filename}. Output ONLY the text to insert — no explanation, no markdown, no preamble. +# Find or create the copilot session, then submit +sid=$(find_or_create_session "$PWD") +B="$MOUNT/s/$sid" + +printf '%s\n' "Complete the code at the cursor in ${filename}. Output ONLY the text to insert — no explanation, no markdown, no preamble. ${prefix} ${suffix} -") +" > "$B/prompt" + +# Wait for idle +while true; do + state=$(cat "$B/statewait" 2>/dev/null | tr -d '[:space:]') || break + [ "$state" = "idle" ] && break +done + +# Read result from offset, then clear context for next completion +offset=$(cat "$B/offset" 2>/dev/null || echo 0) +result=$(tail -c +$((offset + 1)) "$B/chat" 2>/dev/null) +echo "clear" > "$B/ctl" # Write completion to a new acme window newid=$(9p read acme/new/ctl | awk 'NR==1{print $1}')