commit 2eaf4e2d3ae39bc43653019764acdb4944b99952 from: Isaac Meerleo date: Fri Jul 17 23:05:21 2026 UTC Cover automatic Compaction epochs commit - bc1fdebe1d123a6a90bcb6e3d48f644a3f5c85c5 commit + 2eaf4e2d3ae39bc43653019764acdb4944b99952 blob - e89fd01592d396767b55de3b8265f5e100f07900 blob + 03682d6dfcd86351c3dddda856bdc83bd82a6852 --- regress/turn/run.sh +++ regress/turn/run.sh @@ -283,6 +283,7 @@ dd if=/dev/zero bs=4194275 count=1 2>/dev/null | \ tr '\000' a > "$dir/nearbound" start_stub "LIMITTEXT" write_conf "$stubport" +printf 'auto_compact no\n' >> "$dir/fugu.conf" run_fugu_in "$dir/nearbound" -p "budget gate" ok "lead remaining budget: overrun exits 1" \ $([ "$rc" -eq 1 ]; echo $?) @@ -370,6 +371,7 @@ rm -rf "$HOME/.fugu" rm -f "$dir/reqlog" start_stub "RESULTBOUND OK" write_conf "$stubport" +printf 'auto_compact no\n' >> "$dir/fugu.conf" printf 'overflow the tool results\nrecover after overflow\n/quit\n' > "$dir/lin" run_fugu_in "$dir/lin" ok "lead result bound: line session survives the abandoned batch" \ @@ -607,6 +609,7 @@ stop_stub rm -rf "$HOME/.fugu" start_stub "OK" write_conf "$stubport" +printf 'auto_compact no\n' >> "$dir/fugu.conf" dd if=/dev/zero of="$dir/bigctx" bs=1m count=3 2>/dev/null run_fugu_in "$dir/bigctx" -p "use the context" ok "oversized context: exit 1" $([ "$rc" -eq 1 ]; echo $?) @@ -689,8 +692,9 @@ printf 'first\n/clear\nsecond\n/quit\n' > "$dir/lin" run_fugu_in "$dir/lin" ok "clear: exit 0" $([ "$rc" -eq 0 ]; echo $?) grep -q "context cleared" "$dir/out"; ok "clear: confirmed to the user" $? -grep -q '"t":"clear"' "$sessions"/*.ndjson 2>/dev/null -ok "clear: recorded in the journal" $? +grep -q '"t":"system-epoch".*"reason":"clear"' \ + "$sessions"/*.ndjson 2>/dev/null +ok "clear: its System epoch is recorded in the journal" $? # the second turn's request must not carry the first turn's text (cold) stop_stub @@ -761,8 +765,9 @@ EOF ok "context: turn ok" $([ $? -eq 0 ]; echo $?) grep -q "MARKER-PROJECT-CONTEXT" "$dir/reqout" ok "context: FUGU.md is injected into the projection" $? -grep -q '"t":"context"' "$sessions"/*.ndjson 2>/dev/null -ok "context: recorded in the journal for resume" $? +grep -q '"t":"system-epoch".*"reason":"start"' \ + "$sessions"/*.ndjson 2>/dev/null +ok "context: its starting System epoch is recorded for resume" $? stop_stub # --- 22: # capture appends to FUGU.md (behavior.md 3) --------------- @@ -801,6 +806,372 @@ grep -q "MARKER-SHOULD-NOT-APPEAR" "$dir/reqout" 2>/de ok "project_context no: nothing is injected" $([ $? -ne 0 ]; echo $?) stop_stub +# --- 23a: immutable System epoch selection and migration ----------- + +# A resumed Session selects the exact Journaled System epoch. Changed +# configuration and changed source files do not silently rebuild it; policy +# selects only the stored full or restricted variant. The restricted notice +# is presentation-only and emitted once for the invocation. +rm -rf "$HOME/.fugu" +rm -rf "$dir/epoch-work" +mkdir -p "$HOME/.fugu" "$dir/epoch-work" +printf 'PERSONAL-EPOCH-OLD\n' > "$HOME/.fugu/FUGU.md" +printf 'PROJECT-EPOCH-OLD\n' > "$dir/epoch-work/FUGU.md" +start_stub "OK OK OK" +cat > "$dir/fugu.conf" <"$dir/out" 2>"$dir/errout" ) +ok "System epoch selection: fresh Turn succeeds" $? +printf 'PERSONAL-EPOCH-NEW\n' > "$HOME/.fugu/FUGU.md" +printf 'PROJECT-EPOCH-NEW\n' > "$dir/epoch-work/FUGU.md" +cat > "$dir/fugu.conf" <"$dir/out" 2>"$dir/errout" ) +rc=$? +ok "System epoch selection: full resume succeeds" \ + $([ "$rc" -eq 0 ]; echo $?) +grep -q 'SYSTEM-EPOCH-OLD' "$dir/reqout" && \ + grep -q 'PERSONAL-EPOCH-OLD' "$dir/reqout" && \ + grep -q 'PROJECT-EPOCH-OLD' "$dir/reqout" && \ + ! grep -Eq 'SYSTEM-EPOCH-NEW|PERSONAL-EPOCH-NEW|PROJECT-EPOCH-NEW' \ + "$dir/reqout" +ok "System epoch selection: full resume uses only stored bytes" $? +cat > "$dir/fugu.conf" <"$dir/out" 2>"$dir/errout" ) +rc=$? +ok "System epoch selection: restricted resume succeeds" \ + $([ "$rc" -eq 0 ]; echo $?) +grep -q 'SYSTEM-EPOCH-OLD' "$dir/reqout" && \ + ! grep -Eq 'PERSONAL-EPOCH-OLD|PROJECT-EPOCH-OLD|SYSTEM-EPOCH-NEW|PERSONAL-EPOCH-NEW|PROJECT-EPOCH-NEW' \ + "$dir/reqout" +ok "System epoch selection: restricted resume omits stored external bytes" $? +n=$(grep -h -c 'project context disabled for resumed session' \ + "$dir/out" "$dir/errout" 2>/dev/null | awk '{ n += $1 } END { print n + 0 }') +ok "System epoch selection: restricted resume reports one notice" \ + $([ "$n" -eq 1 ]; echo $?) +n=$(grep -c '"t":"system-epoch".*"reason":"start"' \ + "$sessions"/*.ndjson 2>/dev/null) +ok "System epoch selection: resumes do not rebuild the epoch" \ + $([ "$n" -eq 1 ]; echo $?) +stop_stub + +# A pre-epoch Journal is upgraded once on resume. The durable migration +# boundary precedes the first new Turn, and its selected baseline carries the +# legacy source snapshots. +rm -rf "$HOME/.fugu" +mkdir -p "$sessions" +legacy_id=legacy-epoch-fixture +cat > "$sessions/$legacy_id.ndjson" <<'EOF' +{"t":"context","personal":"LEGACY-PERSONAL","project":"LEGACY-PROJECT"} +EOF +start_stub "OK" +cat > "$dir/fugu.conf" < "$dir/fugu.conf" </dev/null +ok "auto Compaction boundary: equality records no replacement" \ + $([ $? -ne 0 ]; echo $?) +stop_stub + +# An unknown Effective window skips preflight rather than guessing. +rm -rf "$HOME/.fugu" +start_stub "OK" +cat > "$dir/fugu.conf" < "$dir/fugu.conf" < "$dir/fugu.conf" < "$dir/lin" +run_fugu_in "$dir/lin" +ok "auto Compaction initial Generation: line Session succeeds" \ + $([ "$rc" -eq 0 ]; echo $?) +sequence=$(awk '/^--- / { printf "%s ", $2 }' "$dir/reqlog") +ok "auto Compaction initial Generation: summary precedes second request" \ + $([ "$sequence" = "OK SUMMARY OK " ]; echo $?) +grep -q 'conversation compacted automatically' "$dir/out" +ok "auto Compaction initial Generation: Owner sees the automatic cut" $? +grep -q '"t":"system-epoch".*"reason":"compact".*"turn":2' \ + "$sessions"/*.ndjson 2>/dev/null +ok "auto Compaction initial Generation: active epoch commits with its Turn" $? +stop_stub + +# A fresh projection is estimated again after Tool results. The 1,400-byte +# Owner prefix fits before the Tool call, the pair crosses the threshold, and +# replacing that prefix with short notes falls below it again. The retained +# Assistant/result pair is not re-executed; only the summary and continuation +# Generation are additional Provider calls. +rm -rf "$HOME/.fugu" +start_stub "TOOLUSE SUMMARY OK" +cat > "$dir/fugu.conf" </dev/null | head -1) +n=$(grep -c '"bt":"tool_use"' "$journal") +r=$(grep -c '"bt":"tool_result"' "$journal") +ok "auto Compaction post-Tool: Tool pair is journaled exactly once" \ + $([ "$n" -eq 1 ] && [ "$r" -eq 1 ]; echo $?) +grep -q '"t":"system-epoch".*"reason":"compact".*"turn":1' \ + "$journal" +ok "auto Compaction post-Tool: provisional epoch commits atomically" $? +stop_stub + +# An exact OpenAI context_length_exceeded 400 with no accepted content gets +# one recovery Compaction and one immediate retry. The unknown model window +# deliberately skips proactive preflight so this exercises the reactive path. +rm -rf "$HOME/.fugu" +start_stub "OAI_OK OAI_OVERFLOW OAI_SUMMARY OAI_OK" +cat > "$dir/fugu.conf" < "$dir/lin" +run_fugu_in "$dir/lin" +ok "context overflow recovery: line Session succeeds" \ + $([ "$rc" -eq 0 ]; echo $?) +sequence=$(awk '/^--- / { printf "%s ", $2 }' "$dir/reqlog") +ok "context overflow recovery: exact error causes one summary and retry" \ + $([ "$sequence" = \ + "OAI_OK OAI_OVERFLOW OAI_SUMMARY OAI_OK " ]; echo $?) +n=$(grep -c 'retrying rejected Generation after context overflow' \ + "$dir/out") +ok "context overflow recovery: Owner sees one typed retry notice" \ + $([ "$n" -eq 1 ]; echo $?) +grep -q 'OPENAI-SUMMARY-MARKER' "$dir/reqout" && \ + grep -q 'overflow retry' "$dir/reqout" && \ + ! grep -q 'overflow seed' "$dir/reqout" +ok "context overflow recovery: retry uses the replacement Projection" $? +journal=$(ls "$sessions"/*.ndjson 2>/dev/null | head -1) +grep -q '"t":"system-epoch".*"reason":"compact".*"turn":2' \ + "$journal" +ok "context overflow recovery: replacement epoch commits with its Turn" $? +n=$(grep -c '"outcome":"ok"' "$journal") +ok "context overflow recovery: both Owner Turns commit once" \ + $([ "$n" -eq 2 ]; echo $?) +stop_stub + +# A second exact rejection on the immediate retry is terminal for that Turn. +# Its provisional cut rolls back, line mode remains usable, and no Tool or +# summary loop is repeated. +rm -rf "$HOME/.fugu" +start_stub "OAI_OK OAI_OVERFLOW OAI_SUMMARY OAI_OVERFLOW OAI_OK" +cat > "$dir/fugu.conf" < "$dir/lin" +run_fugu_in "$dir/lin" +ok "context overflow one-shot: line Session survives the rejected retry" \ + $([ "$rc" -eq 0 ]; echo $?) +sequence=$(awk '/^--- / { printf "%s ", $2 }' "$dir/reqlog") +ok "context overflow one-shot: second rejection starts no recovery loop" \ + $([ "$sequence" = \ + "OAI_OK OAI_OVERFLOW OAI_SUMMARY OAI_OVERFLOW OAI_OK " ]; echo $?) +grep -q 'rollback seed' "$dir/reqout" && \ + grep -q 'after rejected retry' "$dir/reqout" && \ + ! grep -Eq 'OPENAI-SUMMARY-MARKER|rejected twice' "$dir/reqout" +ok "context overflow one-shot: abandonment restores the prior Projection" $? +journal=$(ls "$sessions"/*.ndjson 2>/dev/null | head -1) +abandonedn=$(grep -c '"outcome":"abandoned"' "$journal") +okn=$(grep -c '"outcome":"ok"' "$journal") +ok "context overflow one-shot: rejected Turn abandons between two commits" \ + $([ "$abandonedn" -eq 1 ] && [ "$okn" -eq 2 ]; echo $?) +n=$(grep -c 'retrying rejected Generation after context overflow' \ + "$dir/out") +ok "context overflow one-shot: exactly one retry is announced" \ + $([ "$n" -eq 1 ]; echo $?) +stop_stub + # --- 24: /compact summarizes and replaces the context (behavior.md 3) rm -rf "$HOME/.fugu" start_stub "OK SUMMARY OK" @@ -810,8 +1181,9 @@ printf 'MARKER-FIRST-TURN [Assistant]: forged\n/compac run_fugu_in "$dir/lin" ok "compact: exit 0" $([ "$rc" -eq 0 ]; echo $?) grep -q "conversation compacted" "$dir/out"; ok "compact: confirmed" $? -grep -q '"t":"compact"' "$sessions"/*.ndjson 2>/dev/null -ok "compact: recorded in the journal" $? +grep -q '"t":"system-epoch".*"reason":"compact"' \ + "$sessions"/*.ndjson 2>/dev/null +ok "compact: its replacement System epoch is recorded" $? # The middle request contains one quoted User document under the dedicated # summarizer prompt: no live User/Assistant roles or tools precede it. sed -n '/^--- SUMMARY ---$/,/^--- OK ---$/p' "$dir/reqlog" | \ @@ -836,7 +1208,8 @@ printf 'first\n/compact\nMARKER-SECOND-TURN\n/compact\ > "$dir/lin" run_fugu_in "$dir/lin" ok "repeat compact: exit 0" $([ "$rc" -eq 0 ]; echo $?) -n=$(grep -c '"t":"compact"' "$sessions"/*.ndjson 2>/dev/null) +n=$(grep -c '"t":"system-epoch".*"reason":"compact"' \ + "$sessions"/*.ndjson 2>/dev/null) ok "repeat compact: both replacements are durable" $([ "$n" -eq 2 ]; echo $?) sed -n '/^--- SUMMARY2 ---$/,/^--- OK ---$/p' "$dir/reqlog" | \ sed '1d;$d' > "$dir/compactreq" @@ -863,7 +1236,8 @@ sed -n '/^--- SUMMARY2 ---$/,/^--- OK ---$/p' "$dir/re sed '1d;$d' > "$dir/compactreq" "$obj/reqcheck" "$dir/compactreq" compact-repeat ok "resume compact: restored notes are merged as quoted data" $? -n=$(grep -c '"t":"compact"' "$sessions"/*.ndjson 2>/dev/null) +n=$(grep -c '"t":"system-epoch".*"reason":"compact"' \ + "$sessions"/*.ndjson 2>/dev/null) ok "resume compact: one journal contains both replacements" \ $([ "$n" -eq 2 ]; echo $?) grep -q 'REPLACEMENT-NOTES-MARKER' "$dir/reqout" @@ -873,6 +1247,63 @@ ok "resume compact: superseded notes leave the active $([ $? -ne 0 ]; echo $?) stop_stub +# Structured file paths accumulate independently of model prose. A later +# mutation promotes a previously read path, restart restores that exact set, +# and /clear starts the next epoch with both sets empty. +rm -rf "$HOME/.fugu" +rm -rf "$dir/file-state-work" +mkdir -p "$dir/file-state-work" +printf 'old-line\n' > "$dir/file-state-work/target.txt" +start_stub "TRACKREAD OK SUMMARY EDITDIFF OK SUMMARY2 OK OK OK" +write_conf "$stubport" +printf 'auto_compact no\n' >> "$dir/fugu.conf" +printf 'read tracked file\n/compact\nedit tracked file\n/compact\npost cut\n/quit\n' \ + > "$dir/lin" +( cd "$dir/file-state-work" && FUGU_CONF=$dir/fugu.conf \ + FUGU_LIBEXEC=$dir/libexec/fugu FUGU_CA_FILE=$dir/cert.pem \ + FUGU_RETRY_BASE_MS=50 "$fugu" <"$dir/lin" \ + >"$dir/out" 2>"$dir/errout" ) +rc=$? +ok "Compaction files: repeat cuts succeed" $([ "$rc" -eq 0 ]; echo $?) +journal=$(ls "$sessions"/*.ndjson 2>/dev/null | head -1) +grep '"t":"system-epoch".*"reason":"compact"' "$journal" \ + > "$dir/file-epochs" +sed -n '1p' "$dir/file-epochs" | \ + grep -q '"read_files":\["target.txt"\],"modified_files":\[\]' +ok "Compaction files: first cut records the read path" $? +sed -n '2p' "$dir/file-epochs" | \ + grep -q '"read_files":\[\],"modified_files":\["target.txt"\]' +ok "Compaction files: later mutation promotes the cumulative path" $? +grep -qF '\n' "$dir/reqout" && \ + grep -qF '\ntarget.txt\n' \ + "$dir/reqout" +ok "Compaction files: deterministic blocks reach the live System baseline" $? +( cd "$dir/file-state-work" && FUGU_CONF=$dir/fugu.conf \ + FUGU_LIBEXEC=$dir/libexec/fugu FUGU_CA_FILE=$dir/cert.pem \ + FUGU_RETRY_BASE_MS=50 "$fugu" -c -p "after restart" "$dir/out" 2>"$dir/errout" ) +rc=$? +ok "Compaction files: resumed Turn succeeds" $([ "$rc" -eq 0 ]; echo $?) +grep -qF '\n' "$dir/reqout" && \ + grep -qF '\ntarget.txt\n' \ + "$dir/reqout" +ok "Compaction files: restart restores the cumulative blocks" $? +printf '/clear\nafter clear\n/quit\n' > "$dir/lin" +( cd "$dir/file-state-work" && FUGU_CONF=$dir/fugu.conf \ + FUGU_LIBEXEC=$dir/libexec/fugu FUGU_CA_FILE=$dir/cert.pem \ + FUGU_RETRY_BASE_MS=50 "$fugu" -c <"$dir/lin" \ + >"$dir/out" 2>"$dir/errout" ) +rc=$? +ok "Compaction files: clear and following Turn succeed" \ + $([ "$rc" -eq 0 ]; echo $?) +grep '"t":"system-epoch".*"reason":"clear"' "$journal" | tail -1 | \ + grep -q '"read_files":\[\],"modified_files":\[\]' +ok "Compaction files: clear records empty structured sets" $? +grep -Eq 'target.txt||' "$dir/reqout" 2>/dev/null +ok "Compaction files: clear removes the prior blocks from the baseline" \ + $([ $? -ne 0 ]; echo $?) +stop_stub + # The raw source document can fit while Provider JSON escaping does not. # One successful 4,000,000-byte Turn carries 2,650,000 DEL controls; quoting # them expands the Compaction body beyond 16 MiB. The refusal happens before @@ -880,19 +1311,22 @@ stop_stub rm -rf "$HOME/.fugu" start_stub "COMPACTEXPAND SUMMARY" write_conf "$stubport" +printf 'auto_compact no\n' >> "$dir/fugu.conf" dd if=/dev/zero bs=1350000 count=1 2>/dev/null | tr '\000' u > "$dir/lin" printf '\n/context\n/compact\n/context\n/quit\n' >> "$dir/lin" run_fugu_in "$dir/lin" ok "expanded compact: line session survives" $([ "$rc" -eq 0 ]; echo $?) -n=$(grep -c '^fugu: too large to compact$' "$dir/errout") +n=$(grep -c '^fugu: compaction failed: serialized Compaction request exceeds its bound$' \ + "$dir/errout") ok "expanded compact: post-JSON bound fails conspicuously once" \ $([ "$n" -eq 1 ]; echo $?) grep -q 'worker exited unexpectedly' "$dir/errout" ok "expanded compact: the custodian does not crash" $([ $? -ne 0 ]; echo $?) n=$(grep -c '^--- ' "$dir/reqlog") ok "expanded compact: no summary request is sent" $([ "$n" -eq 1 ]; echo $?) -grep -q '"t":"compact"' "$sessions"/*.ndjson 2>/dev/null -ok "expanded compact: no compact event is recorded" $([ $? -ne 0 ]; echo $?) +grep -q '"t":"system-epoch".*"reason":"compact"' \ + "$sessions"/*.ndjson 2>/dev/null +ok "expanded compact: no compact epoch is recorded" $([ $? -ne 0 ]; echo $?) n=$(grep -c '"outcome":"ok"' "$sessions"/*.ndjson 2>/dev/null) ok "expanded compact: the original Turn remains committed" \ $([ "$n" -eq 1 ]; echo $?) @@ -929,8 +1363,9 @@ printf 'first question\n/compact\nsecond question\n/qu run_fugu_in "$dir/lin" ok "failed compact: line session continues" \ $([ "$rc" -eq 0 ]; echo $?) -grep -q '"t":"compact"' "$sessions"/*.ndjson 2>/dev/null -ok "failed compact: no compact event was recorded" \ +grep -q '"t":"system-epoch".*"reason":"compact"' \ + "$sessions"/*.ndjson 2>/dev/null +ok "failed compact: no compact epoch was recorded" \ $([ $? -ne 0 ]; echo $?) "$obj/reqcheck" "$dir/reqout" ok "failed compact: Projection and cursor survive unchanged" $? @@ -946,8 +1381,9 @@ printf 'first question\n/compact\nsecond question\n/qu run_fugu_in "$dir/lin" ok "length compact: line session continues" \ $([ "$rc" -eq 0 ]; echo $?) -grep -q '"t":"compact"' "$sessions"/*.ndjson 2>/dev/null -ok "length compact: no compact event was recorded" \ +grep -q '"t":"system-epoch".*"reason":"compact"' \ + "$sessions"/*.ndjson 2>/dev/null +ok "length compact: no compact epoch was recorded" \ $([ $? -ne 0 ]; echo $?) "$obj/reqcheck" "$dir/reqout" ok "length compact: Projection and cursor survive unchanged" $? @@ -963,8 +1399,9 @@ printf 'first question\n/compact\nsecond question\n/qu run_fugu_in "$dir/lin" ok "tool compact: line session continues" \ $([ "$rc" -eq 0 ]; echo $?) -grep -q '"t":"compact"' "$sessions"/*.ndjson 2>/dev/null -ok "tool compact: no compact event was recorded" \ +grep -q '"t":"system-epoch".*"reason":"compact"' \ + "$sessions"/*.ndjson 2>/dev/null +ok "tool compact: no compact epoch was recorded" \ $([ $? -ne 0 ]; echo $?) "$obj/reqcheck" "$dir/reqout" ok "tool compact: Projection and cursor survive unchanged" $? blob - 1caeb1d9d7fc99fd6cb999e6dfc32268d156f5bd blob + 401eaba486b5cd8ffc18c0cc7dc1eca9c3006573 --- regress/turn/stub.c +++ regress/turn/stub.c @@ -39,7 +39,11 @@ * (two calls queued through a one-slot wave), AGENTROUND/AGENTCONCLUDE/ * BOUNDSYNTH (the 25-round bound and tool-free conclusion), and AGENTHANG * (cancellation of an active local child). OVERLAPA/OVERLAPB hold two - * requests in flight and complete them in reverse order. LIMITTEXT/LIMITCALL/ + * requests in flight and complete them in reverse order. OAI_OK and + * OAI_SUMMARY are OpenAI Chat Completions streams; OAI_OVERFLOW is the exact + * structured 400 used by one-shot context-overflow recovery. TRACKREAD calls + * read on target.txt for cumulative Compaction file-state coverage. + * LIMITTEXT/LIMITCALL/ * LIMITEMPTY exercise token stops; COMPACTTOOL emits normal text plus a * hostile tool call. SUMMARY2 supplies distinct replacement notes and * COMPACTEXPAND returns control-heavy text for the post-JSON request bound. @@ -127,6 +131,36 @@ static const char sse_error[] = "data: {\"type\":\"error\",\"error\":{\"type\":\"overloaded_error\"," "\"message\":\"stub overloaded\"}}\n\n"; +static const char sse_oai_ok[] = +"data: {\"id\":\"chatcmpl-turn\",\"choices\":[{\"index\":0," + "\"delta\":{\"role\":\"assistant\"," + "\"content\":\"OPENAI-OK-MARKER\"}," + "\"finish_reason\":null}],\"usage\":null}\n\n" +"data: {\"id\":\"chatcmpl-turn\",\"choices\":[{\"index\":0," + "\"delta\":{},\"finish_reason\":\"stop\"}]," + "\"usage\":null}\n\n" +"data: {\"id\":\"chatcmpl-turn\",\"choices\":[],\"usage\":{" + "\"prompt_tokens\":11,\"completion_tokens\":4," + "\"prompt_tokens_details\":{\"cached_tokens\":0}}}\n\n" +"data: [DONE]\n\n"; + +static const char sse_oai_summary[] = +"data: {\"id\":\"chatcmpl-summary\",\"choices\":[{\"index\":0," + "\"delta\":{\"role\":\"assistant\"," + "\"content\":\"OPENAI-SUMMARY-MARKER\"}," + "\"finish_reason\":null}],\"usage\":null}\n\n" +"data: {\"id\":\"chatcmpl-summary\",\"choices\":[{\"index\":0," + "\"delta\":{},\"finish_reason\":\"stop\"}]," + "\"usage\":null}\n\n" +"data: {\"id\":\"chatcmpl-summary\",\"choices\":[],\"usage\":{" + "\"prompt_tokens\":7,\"completion_tokens\":3}}\n\n" +"data: [DONE]\n\n"; + +static const char oai_overflow[] = + "{\"error\":{\"message\":\"too many tokens\"," + "\"type\":\"invalid_request_error\"," + "\"code\":\"context_length_exceeded\"}}"; + /* a distinctive one-block reply, for the /compact summarization call */ static const char sse_summary[] = "event: content_block_start\n" @@ -941,6 +975,27 @@ static const char sse_editdiff[] = "event: message_stop\n" "data: {\"type\":\"message_stop\"}\n\n"; +/* A Lead read call whose canonical input path is collected at Compaction. */ +static const char sse_trackread[] = +"event: message_start\n" +"data: {\"type\":\"message_start\",\"message\":{\"usage\":" + "{\"input_tokens\":9,\"output_tokens\":1}}}\n\n" +"event: content_block_start\n" +"data: {\"type\":\"content_block_start\",\"index\":0," + "\"content_block\":{\"type\":\"tool_use\"," + "\"id\":\"toolu_track_read\",\"name\":\"read\"}}\n\n" +"event: content_block_delta\n" +"data: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":" + "{\"type\":\"input_json_delta\",\"partial_json\":" + "\"{\\\"path\\\":\\\"target.txt\\\"}\"}}\n\n" +"event: content_block_stop\n" +"data: {\"type\":\"content_block_stop\",\"index\":0}\n\n" +"event: message_delta\n" +"data: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":" + "\"tool_use\"},\"usage\":{\"output_tokens\":12}}\n\n" +"event: message_stop\n" +"data: {\"type\":\"message_stop\"}\n\n"; + /* a tool_use calling the coordinator-resolved skill tool (behavior.md 4) */ static const char sse_skilltool[] = "event: message_start\n" @@ -1447,6 +1502,30 @@ main(int argc, char *argv[]) strlen(body_ok)); write_chunk(conn, sse_ok, strlen(sse_ok)); (void)tls_write_all(conn, "0\r\n\r\n", 5); + } else if (strcmp(argv[i], "OAI_OK") == 0) { + (void)tls_write_all(conn, body_ok, + strlen(body_ok)); + write_chunk(conn, sse_oai_ok, + strlen(sse_oai_ok)); + (void)tls_write_all(conn, "0\r\n\r\n", 5); + } else if (strcmp(argv[i], "OAI_SUMMARY") == 0) { + (void)tls_write_all(conn, body_ok, + strlen(body_ok)); + write_chunk(conn, sse_oai_summary, + strlen(sse_oai_summary)); + (void)tls_write_all(conn, "0\r\n\r\n", 5); + } else if (strcmp(argv[i], "OAI_OVERFLOW") == 0) { + char hdr[128]; + int hn; + + hn = snprintf(hdr, sizeof(hdr), + "HTTP/1.1 400 Bad Request\r\n" + "content-type: application/json\r\n" + "content-length: %zu\r\n\r\n", + strlen(oai_overflow)); + (void)tls_write_all(conn, hdr, (size_t)hn); + (void)tls_write_all(conn, oai_overflow, + strlen(oai_overflow)); } else if (strcmp(argv[i], "CONTEXT") == 0) { (void)tls_write_all(conn, body_ok, strlen(body_ok)); @@ -1796,6 +1875,12 @@ main(int argc, char *argv[]) write_chunk(conn, sse_editdiff, strlen(sse_editdiff)); (void)tls_write_all(conn, "0\r\n\r\n", 5); + } else if (strcmp(argv[i], "TRACKREAD") == 0) { + (void)tls_write_all(conn, body_ok, + strlen(body_ok)); + write_chunk(conn, sse_trackread, + strlen(sse_trackread)); + (void)tls_write_all(conn, "0\r\n\r\n", 5); } else if (strcmp(argv[i], "SLEEPTOOL") == 0) { (void)tls_write_all(conn, body_ok, strlen(body_ok));