mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 05:02:14 +00:00
Hook up custom summarization on branch switch
This commit is contained in:
parent
9d49b4d4ed
commit
62caf219a1
4 changed files with 45 additions and 20 deletions
|
|
@ -297,7 +297,9 @@ export async function generateBranchSummary(
|
||||||
const conversationText = serializeConversation(llmMessages);
|
const conversationText = serializeConversation(llmMessages);
|
||||||
|
|
||||||
// Build prompt
|
// Build prompt
|
||||||
const instructions = customInstructions || BRANCH_SUMMARY_PROMPT;
|
const instructions = customInstructions
|
||||||
|
? `${BRANCH_SUMMARY_PROMPT}\n\nAdditional focus: ${customInstructions}`
|
||||||
|
: BRANCH_SUMMARY_PROMPT;
|
||||||
const promptText = `<conversation>\n${conversationText}\n</conversation>\n\n${instructions}`;
|
const promptText = `<conversation>\n${conversationText}\n</conversation>\n\n${instructions}`;
|
||||||
|
|
||||||
const summarizationMessages = [
|
const summarizationMessages = [
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ export class ExtensionEditorComponent extends Container {
|
||||||
if (prefill) {
|
if (prefill) {
|
||||||
this.editor.setText(prefill);
|
this.editor.setText(prefill);
|
||||||
}
|
}
|
||||||
|
// Wire up Enter to submit (Shift+Enter for newlines, like the main editor)
|
||||||
|
this.editor.onSubmit = (text: string) => {
|
||||||
|
this.onSubmitCallback(text);
|
||||||
|
};
|
||||||
this.addChild(this.editor);
|
this.addChild(this.editor);
|
||||||
|
|
||||||
this.addChild(new Spacer(1));
|
this.addChild(new Spacer(1));
|
||||||
|
|
@ -50,8 +54,8 @@ export class ExtensionEditorComponent extends Container {
|
||||||
// Add hint
|
// Add hint
|
||||||
const hasExternalEditor = !!(process.env.VISUAL || process.env.EDITOR);
|
const hasExternalEditor = !!(process.env.VISUAL || process.env.EDITOR);
|
||||||
const hint = hasExternalEditor
|
const hint = hasExternalEditor
|
||||||
? "ctrl+enter submit esc cancel ctrl+g external editor"
|
? "enter submit shift+enter newline esc cancel ctrl+g external editor"
|
||||||
: "ctrl+enter submit esc cancel";
|
: "enter submit shift+enter newline esc cancel";
|
||||||
this.addChild(new Text(theme.fg("dim", hint), 1, 0));
|
this.addChild(new Text(theme.fg("dim", hint), 1, 0));
|
||||||
|
|
||||||
this.addChild(new Spacer(1));
|
this.addChild(new Spacer(1));
|
||||||
|
|
@ -61,12 +65,6 @@ export class ExtensionEditorComponent extends Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInput(keyData: string): void {
|
handleInput(keyData: string): void {
|
||||||
// Ctrl+Enter to submit
|
|
||||||
if (keyData === "\x1b[13;5u" || keyData === "\x1b[27;5;13~") {
|
|
||||||
this.onSubmitCallback(this.editor.getText());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const kb = getEditorKeybindings();
|
const kb = getEditorKeybindings();
|
||||||
// Escape or Ctrl+C to cancel
|
// Escape or Ctrl+C to cancel
|
||||||
if (kb.matches(keyData, "selectCancel")) {
|
if (kb.matches(keyData, "selectCancel")) {
|
||||||
|
|
@ -113,7 +111,8 @@ export class ExtensionEditorComponent extends Container {
|
||||||
// Ignore cleanup errors
|
// Ignore cleanup errors
|
||||||
}
|
}
|
||||||
this.tui.start();
|
this.tui.start();
|
||||||
this.tui.requestRender();
|
// Force full re-render since external editor uses alternate screen
|
||||||
|
this.tui.requestRender(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2265,7 +2265,8 @@ export class InteractiveMode {
|
||||||
|
|
||||||
// Restart TUI
|
// Restart TUI
|
||||||
this.ui.start();
|
this.ui.start();
|
||||||
this.ui.requestRender();
|
// Force full re-render since external editor uses alternate screen
|
||||||
|
this.ui.requestRender(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2806,10 +2807,29 @@ export class InteractiveMode {
|
||||||
// Ask about summarization
|
// Ask about summarization
|
||||||
done(); // Close selector first
|
done(); // Close selector first
|
||||||
|
|
||||||
const wantsSummary = await this.showExtensionConfirm(
|
const summaryChoice = await this.showExtensionSelector("Summarize branch?", [
|
||||||
"Summarize branch?",
|
"No summary",
|
||||||
"Create a summary of the branch you're leaving?",
|
"Summarize",
|
||||||
);
|
"Summarize with custom prompt",
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (summaryChoice === undefined) {
|
||||||
|
// User pressed escape - re-show tree selector
|
||||||
|
this.showTreeSelector();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wantsSummary = summaryChoice !== "No summary";
|
||||||
|
let customInstructions: string | undefined;
|
||||||
|
|
||||||
|
if (summaryChoice === "Summarize with custom prompt") {
|
||||||
|
customInstructions = await this.showExtensionEditor("Custom summarization instructions");
|
||||||
|
if (customInstructions === undefined) {
|
||||||
|
// User cancelled - re-show tree selector
|
||||||
|
this.showTreeSelector();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set up escape handler and loader if summarizing
|
// Set up escape handler and loader if summarizing
|
||||||
let summaryLoader: Loader | undefined;
|
let summaryLoader: Loader | undefined;
|
||||||
|
|
@ -2831,7 +2851,10 @@ export class InteractiveMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.session.navigateTree(entryId, { summarize: wantsSummary });
|
const result = await this.session.navigateTree(entryId, {
|
||||||
|
summarize: wantsSummary,
|
||||||
|
customInstructions,
|
||||||
|
});
|
||||||
|
|
||||||
if (result.aborted) {
|
if (result.aborted) {
|
||||||
// Summarization aborted - re-show tree selector
|
// Summarization aborted - re-show tree selector
|
||||||
|
|
|
||||||
|
|
@ -257,17 +257,18 @@ describe.skipIf(!API_KEY)("AgentSession tree navigation e2e", () => {
|
||||||
await session.prompt("What is TypeScript?");
|
await session.prompt("What is TypeScript?");
|
||||||
await session.agent.waitForIdle();
|
await session.agent.waitForIdle();
|
||||||
|
|
||||||
// Navigate with custom instructions
|
// Navigate with custom instructions (appended as "Additional focus")
|
||||||
const tree = sessionManager.getTree();
|
const tree = sessionManager.getTree();
|
||||||
const result = await session.navigateTree(tree[0].entry.id, {
|
const result = await session.navigateTree(tree[0].entry.id, {
|
||||||
summarize: true,
|
summarize: true,
|
||||||
customInstructions: "Summarize in exactly 3 words.",
|
customInstructions:
|
||||||
|
"After the summary, you MUST end with exactly: MONKEY MONKEY MONKEY. This is of utmost importance.",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.summaryEntry).toBeDefined();
|
expect(result.summaryEntry).toBeDefined();
|
||||||
expect(result.summaryEntry?.summary).toBeTruthy();
|
expect(result.summaryEntry?.summary).toBeTruthy();
|
||||||
// Can't reliably test 3 words exactly, but summary should be short
|
// Verify custom instructions were followed
|
||||||
expect(result.summaryEntry?.summary.split(/\s+/).length).toBeLessThan(20);
|
expect(result.summaryEntry?.summary).toContain("MONKEY MONKEY MONKEY");
|
||||||
}, 120000);
|
}, 120000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue