fix(web): map codex-enveloped compact-summary to the chat block (#1582)

* fix(web): map codex-enveloped compact-summary to the chat block

The merged #1570 renders Pi compaction summaries as a dedicated chat
block via the event envelope. A compact-summary arriving in the codex
payload envelope (older import paths, future producers) would still be
silently dropped by the codex-content filter; map it to the same
agent-event the live pi wrapper emits, mirroring the existing
context_compacted handling. Adds a normalizeAgent regression test and
tightens the /compact thinking-state test to assert the last keepAlive
flips true (RPC outstanding) then false (settled).

Verified: bun typecheck clean; web normalizeAgent 12/12, cli runPi
57/57 in an isolated TMPDIR.

* fix(web): remove duplicate showSessionSummaryInChat in markdown-a fixture

Regression from #1530: the fixture object literal sets the key twice,
which breaks `bun typecheck` on upstream/main (Test workflow failing on
push). One-line cleanup; no behavior change.

Verified: bun typecheck exit 0 across cli/web/hub.
This commit is contained in:
SSU-WEI HUANG
2026-08-16 22:35:31 +08:00
committed by GitHub
parent 901f17d0ca
commit 1f2fbcb142
4 changed files with 54 additions and 1 deletions
+11
View File
@@ -1332,6 +1332,11 @@ describe('Pi built-in slash commands', () => {
expect(harness.sent).not.toContainEqual(expect.objectContaining({ type: 'prompt' }));
const compact = harness.sent.find((item) => (item as { type?: string }).type === 'compact') as { id: string };
// The compact RPC holds the session in the thinking state for its
// whole duration (web would otherwise mark it idle after the hub's
// 15s queued-thinking grace).
const keepAliveCalls = harness.session.keepAlive.mock.calls;
expect(keepAliveCalls[keepAliveCalls.length - 1]?.[0]).toBe(true);
harness.onEvent!({
type: 'response', id: compact.id, command: 'compact', success: true,
data: { summary: 'API design focused summary', tokensBefore: 1000, estimatedTokensAfter: 120 },
@@ -1351,6 +1356,12 @@ describe('Pi built-in slash commands', () => {
}));
await vi.waitFor(() => expect(harness.session.keepAlive).toHaveBeenCalledWith(false, expect.anything(), expect.anything()));
// The thinking state is released once the RPC completes.
await vi.waitFor(() => {
const calls = harness.session.keepAlive.mock.calls;
expect(calls[calls.length - 1]?.[0]).toBe(false);
});
// The queued prompt may only flow once compaction completed.
await vi.waitFor(() => expect(harness.sent).toContainEqual(expect.objectContaining({
type: 'prompt', message: 'continue after compaction',