name: "Context compaction e2e test"
description: |
Verify that the context compaction feature works correctly:
- Start server with a very low RECURSIVE_COMPACT_THRESHOLD (100 chars)
so compaction fires after the first long response.
- Send two messages in the same session.
- The first response is long enough to exceed the threshold.
- The second message must succeed — proving the agent is still functional
after compaction and does not crash or return an error.
The compactor is enabled via RECURSIVE_COMPACT_THRESHOLD env var.
sequential: true
setup:
- name: "Kill any leftover server on port 9099"
ignoreError: true
exec:
container: recursive-e2e
command: |
pkill -f 'http --addr 0.0.0.0:9099' 2>/dev/null || true
sleep 1
echo cleaned
- name: "Reset state files"
ignoreError: true
exec:
container: recursive-e2e
command: rm -f /tmp/compact-result.txt /tmp/compact-http.log && echo reset
- name: "Start HTTP server on port 9099 with low compaction threshold"
exec:
container: recursive-e2e
command: |
nohup env RECURSIVE_COMPACT_THRESHOLD=100 recursive \
--api-base http://aimock:4010/v1 \
--api-key mock-key -m mock-chat \
http --addr 0.0.0.0:9099 \
> /tmp/compact-http.log 2>&1 &
sleep 2
echo started
- name: "Sanity: GET /health returns ok"
exec:
container: recursive-e2e
command: curl -sf http://localhost:9099/health
expect:
exitCode: 0
output:
contains: "ok"
- name: "Create a session and run two turns to trigger compaction"
exec:
container: recursive-e2e
command: |
# Create session
SESSION=$(curl -sf -X POST http://localhost:9099/sessions | jq -r '.id')
echo "session=$SESSION"
# Turn 1: long response to exceed 100-char threshold
RESP1=$(curl -sf -X POST http://localhost:9099/sessions/$SESSION/messages \
-H 'Content-Type: application/json' \
-d '{"message":"compaction-turn-1"}')
echo "turn1_role=$(echo $RESP1 | jq -r '.role')"
echo "turn1_ok=$(echo $RESP1 | jq -r '.content' | grep -c 'compaction' || echo 0)"
# Turn 2: after compaction — must still work
RESP2=$(curl -sf -X POST http://localhost:9099/sessions/$SESSION/messages \
-H 'Content-Type: application/json' \
-d '{"message":"compaction-turn-2"}')
echo "turn2_role=$(echo $RESP2 | jq -r '.role')"
echo "turn2_ok=$(echo $RESP2 | jq -r '.content' | grep -c 'Compaction' || echo 0)"
# Save results
printf "session=%s\nturn1_role=%s\nturn2_role=%s\n" \
"$SESSION" \
"$(echo $RESP1 | jq -r '.role')" \
"$(echo $RESP2 | jq -r '.role')" \
> /tmp/compact-result.txt
cat /tmp/compact-result.txt
expect:
exitCode: 0
output:
contains:
- "session="
- "turn1_role=assistant"
- "turn2_role=assistant"
cases:
- name: "Turn 1 completes successfully (triggering compaction)"
file:
container: recursive-e2e
path: /tmp/compact-result.txt
exists: true
contains: "turn1_role=assistant"
- name: "Turn 2 completes successfully after compaction"
file:
container: recursive-e2e
path: /tmp/compact-result.txt
exists: true
contains: "turn2_role=assistant"
teardown:
- name: "Stop HTTP server on 9099 and clean up"
ignoreError: true
exec:
container: recursive-e2e
command: |
pkill -f 'http --addr 0.0.0.0:9099' 2>/dev/null || true
rm -f /tmp/compact-result.txt /tmp/compact-http.log
echo stopped