Skip to content

feat: support additionalContext in PreCompact hook#308297

Draft
roblourens wants to merge 2 commits intomainfrom
vscode-copilot-chat/migrate-4980
Draft

feat: support additionalContext in PreCompact hook#308297
roblourens wants to merge 2 commits intomainfrom
vscode-copilot-chat/migrate-4980

Conversation

@roblourens
Copy link
Copy Markdown
Member

Migrated from microsoft/vscode-copilot-chat#4980
Original author: @abwuge


Allow PreCompact hook to inject additional context into the summarization prompt, matching the pattern used by other hooks (PreToolUse, PostToolUse, SessionStart, SubagentStart, UserPromptSubmit).

Changes:

  • Add IPreCompactHookSpecificCommandOutput type in hookCommandTypes.ts
  • Add PreCompactHookOutput interface in chatHookService.ts
  • Modify executePreCompactHook() to collect additionalContext from hook results
  • Merge hook additionalContext into summarizationInstructions in summarizeHistory()
  • Add unit tests for prompt rendering with summarizationInstructions
  • Add integration tests for PreCompact hook flow in preCompactHook.spec.tsx

abwuge added 2 commits April 4, 2026 14:35
Allow PreCompact hook to inject additional context into the
summarization prompt, matching the pattern used by other hooks
(PreToolUse, PostToolUse, SessionStart, SubagentStart, UserPromptSubmit).

Changes:
- Add IPreCompactHookSpecificCommandOutput type in hookCommandTypes.ts
- Add PreCompactHookOutput interface in chatHookService.ts
- Modify executePreCompactHook() to collect additionalContext from hook results
- Merge hook additionalContext into summarizationInstructions in summarizeHistory()
- Add unit tests for prompt rendering with summarizationInstructions
- Add integration tests for PreCompact hook flow in preCompactHook.spec.tsx
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for PreCompact hooks to contribute additionalContext that is merged into the conversation compaction/summarization prompt, aligning PreCompact with other hook types that can inject prompt context.

Changes:

  • Introduces PreCompact hook-specific output typing (additionalContext) for hook command results.
  • Executes PreCompact hooks before summarization and merges returned additionalContext into summarizationInstructions.
  • Adds unit and integration tests validating prompt rendering and PreCompact hook flow.
Show a summary per file
File Description
extensions/copilot/src/platform/chat/common/hookCommandTypes.ts Adds IPreCompactHookSpecificCommandOutput type to the hook command JSON contract types.
extensions/copilot/src/platform/chat/common/chatHookService.ts Adds PreCompactHookOutput interface describing nested hookSpecificOutput.additionalContext.
extensions/copilot/src/extension/prompts/node/agent/summarizedConversationHistory.tsx Runs PreCompact hooks before summarization and merges hook-provided context into summarization instructions; updates prompt heading text.
extensions/copilot/src/extension/prompts/node/agent/test/summarization.spec.tsx Adds tests for rendering the “additional summarization instructions” section when provided/omitted.
extensions/copilot/src/extension/prompts/node/agent/test/preCompactHook.spec.tsx Adds integration tests ensuring PreCompact is invoked and its additionalContext influences the summarization prompt.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 2

Comment on lines +24 to +26
import { LanguageModelTextPart, LanguageModelToolResult } from '../../../../../vscodeTypes';
import { MockChatHookService } from '../../../../intents/test/node/toolCallingLoopHooks.spec';
import { ChatVariablesCollection } from '../../../../prompt/common/chatVariablesCollection';
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid importing MockChatHookService from another *.spec.ts file. Importing a spec as a module can cause that spec’s tests to be registered/executed as a dependency (and then again when the runner loads it as a test file), which can lead to duplicated suites and flaky ordering. Move MockChatHookService into a dedicated test helper module (non-*.spec.*) and import it from both specs.

Copilot uses AI. Check for mistakes.
Comment on lines 678 to 686
if (result.resultKind === 'error') {
const errorMessage = typeof result.output === 'string' ? result.output : 'Unknown error';
this.logService.error(`[ConversationHistorySummarizer] PreCompact hook error: ${errorMessage}`);
} else if (result.resultKind === 'success' && result.output && typeof result.output === 'object') {
const output = result.output as PreCompactHookOutput;
if (output.hookSpecificOutput?.additionalContext) {
allAdditionalContext.push(output.hookSpecificOutput.additionalContext);
}
}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

executePreCompactHook manually iterates hook results and only logs resultKind === 'error'. This drops warning results (and any stopReason/warningMessage) on the floor, unlike other hook call sites (e.g. SessionStart/SubagentStart) that use processHookResults(..., ignoreErrors: true) to consistently handle warnings/errors while still proceeding. Consider switching to processHookResults here (with outputStream: undefined and ignoreErrors: true) and collecting hookSpecificOutput.additionalContext in onSuccess.

Suggested change
if (result.resultKind === 'error') {
const errorMessage = typeof result.output === 'string' ? result.output : 'Unknown error';
this.logService.error(`[ConversationHistorySummarizer] PreCompact hook error: ${errorMessage}`);
} else if (result.resultKind === 'success' && result.output && typeof result.output === 'object') {
const output = result.output as PreCompactHookOutput;
if (output.hookSpecificOutput?.additionalContext) {
allAdditionalContext.push(output.hookSpecificOutput.additionalContext);
}
}
if (result.resultKind === 'success' && result.output && typeof result.output === 'object') {
const output = result.output as PreCompactHookOutput;
if (output.hookSpecificOutput?.additionalContext) {
allAdditionalContext.push(output.hookSpecificOutput.additionalContext);
}
}
const warningMessage = 'warningMessage' in result && typeof result.warningMessage === 'string' ? result.warningMessage : undefined;
const stopReason = 'stopReason' in result && typeof result.stopReason === 'string' ? result.stopReason : undefined;
if (result.resultKind === 'error') {
const errorMessage = typeof result.output === 'string' ? result.output : 'Unknown error';
this.logService.error(`[ConversationHistorySummarizer] PreCompact hook error: ${errorMessage}`);
if (warningMessage) {
this.logService.warn(`[ConversationHistorySummarizer] PreCompact hook warning: ${warningMessage}`);
}
if (stopReason) {
this.logService.warn(`[ConversationHistorySummarizer] PreCompact hook stop reason: ${stopReason}`);
}
} else if (result.resultKind === 'warning') {
const resultWarningMessage = typeof result.output === 'string' ? result.output : warningMessage ?? 'Unknown warning';
this.logService.warn(`[ConversationHistorySummarizer] PreCompact hook warning: ${resultWarningMessage}`);
if (stopReason) {
this.logService.warn(`[ConversationHistorySummarizer] PreCompact hook stop reason: ${stopReason}`);
}
}

Copilot uses AI. Check for mistakes.
@roblourens roblourens marked this pull request as draft April 7, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants