feat: add /compact (#289)

Added the ability to compact. Not sure if I should switch the model over
to gpt-4.1 for longer context or if keeping the current model is fine.
Also I'm not sure if setting the compacted to system is best practice,
would love feedback 😄

Mentioned in this issue: https://github.com/openai/codex/issues/230
This commit is contained in:
Thomas
2025-04-18 15:48:30 +10:00
committed by GitHub
parent 35d47a5ab4
commit 9a948836bf
5 changed files with 135 additions and 1 deletions

View File

@@ -42,6 +42,7 @@ export default function TerminalChatInput({
openModelOverlay,
openApprovalOverlay,
openHelpOverlay,
onCompact,
interruptAgent,
active,
}: {
@@ -61,6 +62,7 @@ export default function TerminalChatInput({
openModelOverlay: () => void;
openApprovalOverlay: () => void;
openHelpOverlay: () => void;
onCompact: () => void;
interruptAgent: () => void;
active: boolean;
}): React.ReactElement {
@@ -166,6 +168,12 @@ export default function TerminalChatInput({
return;
}
if (inputValue === "/compact") {
setInput("");
onCompact();
return;
}
if (inputValue.startsWith("/model")) {
setInput("");
openModelOverlay();
@@ -295,6 +303,7 @@ export default function TerminalChatInput({
openModelOverlay,
openHelpOverlay,
history, // Add history to the dependency array
onCompact,
],
);
@@ -366,7 +375,8 @@ export default function TerminalChatInput({
<>
{" — "}
<Text color="red">
{Math.round(contextLeftPercent)}% context left
{Math.round(contextLeftPercent)}% context left send
"/compact" to condense context
</Text>
</>
)}

View File

@@ -17,6 +17,7 @@ import { useTerminalSize } from "../../hooks/use-terminal-size.js";
import { AgentLoop } from "../../utils/agent/agent-loop.js";
import { isLoggingEnabled, log } from "../../utils/agent/log.js";
import { ReviewDecision } from "../../utils/agent/review.js";
import { generateCompactSummary } from "../../utils/compact-summary.js";
import { OPENAI_BASE_URL } from "../../utils/config.js";
import { createInputItem } from "../../utils/input-utils.js";
import { getAvailableModels } from "../../utils/model-utils.js";
@@ -138,6 +139,34 @@ export default function TerminalChat({
initialApprovalPolicy,
);
const [thinkingSeconds, setThinkingSeconds] = useState(0);
const handleCompact = async () => {
setLoading(true);
try {
const summary = await generateCompactSummary(items, model);
setItems([
{
id: `compact-${Date.now()}`,
type: "message",
role: "assistant",
content: [{ type: "output_text", text: summary }],
} as ResponseItem,
]);
} catch (err) {
setItems((prev) => [
...prev,
{
id: `compact-error-${Date.now()}`,
type: "message",
role: "system",
content: [
{ type: "input_text", text: `Failed to compact context: ${err}` },
],
} as ResponseItem,
]);
} finally {
setLoading(false);
}
};
const {
requestConfirmation,
confirmationPrompt,
@@ -453,6 +482,7 @@ export default function TerminalChat({
openModelOverlay={() => setOverlayMode("model")}
openApprovalOverlay={() => setOverlayMode("approval")}
openHelpOverlay={() => setOverlayMode("help")}
onCompact={handleCompact}
active={overlayMode === "none"}
interruptAgent={() => {
if (!agent) {

View File

@@ -52,6 +52,9 @@ export default function HelpOverlay({
<Text>
<Text color="cyan">/clearhistory</Text> clear command history
</Text>
<Text>
<Text color="cyan">/compact</Text> condense context into a summary
</Text>
<Box marginTop={1}>
<Text bold dimColor>