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 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-05-03 13:54:29 +02:00
parent cddda76a3f
commit 3c03faed3a
2 changed files with 58 additions and 6 deletions

View File

@ -1,4 +1,9 @@
{
"prompt": [],
"trustedTools": []
"trustedTools": [],
"hooks": {
"turnError": [
"$OLLIE/x/freeloader $OLLIE_SESSION_ID"
]
}
}

View File

@ -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>
${prefix}
</prefix>
<suffix>
${suffix}
</suffix>")
</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}')