Hide OpenCode compact summaries from chat
This commit is contained in:
@@ -2510,6 +2510,10 @@ function appendOpenCodeMessagePartDelta(
|
|||||||
const knownPartType = partID ? state.partTypes.get(partID) : undefined;
|
const knownPartType = partID ? state.partTypes.get(partID) : undefined;
|
||||||
const isReasoning = knownPartType === "reasoning" || field === "reasoning";
|
const isReasoning = knownPartType === "reasoning" || field === "reasoning";
|
||||||
|
|
||||||
|
if (messageID && state.compactionSummaryMessageIds.has(messageID)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isReasoning) {
|
if (isReasoning) {
|
||||||
if (partID) {
|
if (partID) {
|
||||||
state.streamedPartKeys.add(`reasoning:${partID}`);
|
state.streamedPartKeys.add(`reasoning:${partID}`);
|
||||||
@@ -2527,6 +2531,10 @@ function appendOpenCodeMessagePartDelta(
|
|||||||
if (messageRole === "user") {
|
if (messageRole === "user") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (messageID && state.suppressAssistantMessagesUntilIdle?.active === true) {
|
||||||
|
state.compactionSummaryMessageIds.add(messageID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (partID) {
|
if (partID) {
|
||||||
state.streamedPartKeys.add(`text:${partID}`);
|
state.streamedPartKeys.add(`text:${partID}`);
|
||||||
}
|
}
|
||||||
|
|||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
|
||||||
|
import { mkdtempSync, rmSync } from "node:fs";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import path from "node:path";
|
||||||
|
import pino from "pino";
|
||||||
|
|
||||||
|
import type { AgentStreamEvent } from "../agent-sdk-types.js";
|
||||||
|
import {
|
||||||
|
canRunRealProvider,
|
||||||
|
createRealProviderClient,
|
||||||
|
getRealProviderConfig,
|
||||||
|
} from "../../daemon-e2e/real-provider-test-config.js";
|
||||||
|
import { OpenCodeServerManager } from "./opencode/server-manager.js";
|
||||||
|
|
||||||
|
const OPENCODE_REAL_TEST_MODEL = getRealProviderConfig("opencode").model;
|
||||||
|
const logger = pino({ level: "silent" });
|
||||||
|
|
||||||
|
function tmpCwd(): string {
|
||||||
|
return mkdtempSync(path.join(tmpdir(), "opencode-compact-dump-"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitForTurnToFinish(session: {
|
||||||
|
subscribe: (callback: (event: AgentStreamEvent) => void) => () => void;
|
||||||
|
}): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let unsubscribe: () => void = () => undefined;
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
unsubscribe();
|
||||||
|
reject(new Error("Timed out waiting for OpenCode compact turn to finish"));
|
||||||
|
}, 60_000);
|
||||||
|
unsubscribe = session.subscribe((event) => {
|
||||||
|
if (
|
||||||
|
event.type !== "turn_completed" &&
|
||||||
|
event.type !== "turn_failed" &&
|
||||||
|
event.type !== "turn_canceled"
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearTimeout(timeout);
|
||||||
|
unsubscribe();
|
||||||
|
if (event.type === "turn_failed") {
|
||||||
|
reject(new Error(event.error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dumpCompactEvents(events: AgentStreamEvent[]): void {
|
||||||
|
console.info(
|
||||||
|
"OPENCODE_COMPACT_EVENT_DUMP",
|
||||||
|
JSON.stringify(
|
||||||
|
events.map((event) => ({
|
||||||
|
type: event.type,
|
||||||
|
turnId: "turnId" in event ? event.turnId : undefined,
|
||||||
|
item: event.type === "timeline" ? event.item : undefined,
|
||||||
|
usage: event.type === "turn_completed" ? event.usage : undefined,
|
||||||
|
})),
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("OpenCode compact event dump (real)", () => {
|
||||||
|
let canRun = false;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
canRun = await canRunRealProvider("opencode");
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach((context) => {
|
||||||
|
if (!canRun) {
|
||||||
|
context.skip();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await OpenCodeServerManager.getInstance(logger).shutdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("dumps live events emitted by a real /compact turn", async () => {
|
||||||
|
const cwd = tmpCwd();
|
||||||
|
const client = createRealProviderClient("opencode", logger);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const session = await client.createSession({
|
||||||
|
provider: "opencode",
|
||||||
|
cwd,
|
||||||
|
model: OPENCODE_REAL_TEST_MODEL,
|
||||||
|
modeId: "build",
|
||||||
|
});
|
||||||
|
|
||||||
|
await session.run("Reply with exactly: COMPACT_SEED_OK");
|
||||||
|
|
||||||
|
const compactEvents: AgentStreamEvent[] = [];
|
||||||
|
const unsubscribe = session.subscribe((event) => {
|
||||||
|
compactEvents.push(event);
|
||||||
|
});
|
||||||
|
const compactFinished = waitForTurnToFinish(session);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await session.startTurn("/compact");
|
||||||
|
await compactFinished;
|
||||||
|
} finally {
|
||||||
|
unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpCompactEvents(compactEvents);
|
||||||
|
|
||||||
|
expect(compactEvents.some((event) => event.type === "turn_completed")).toBe(true);
|
||||||
|
expect(
|
||||||
|
compactEvents.filter(
|
||||||
|
(event) => event.type === "timeline" && event.item.type === "assistant_message",
|
||||||
|
),
|
||||||
|
).toEqual([]);
|
||||||
|
} finally {
|
||||||
|
rmSync(cwd, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
}, 120_000);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user