Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -561,17 +561,17 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
context = this.currentThinkingValue.substring(0, 1000);
}

const prompt = `Summarize the following actions in a SINGLE sentence (under 10 words) using past tense. Follow these rules strictly:
const prompt = `Summarize the following content in a SINGLE sentence (under 10 words) using past tense. Follow these rules strictly:

OUTPUT FORMAT:
- MUST be a single sentence
- MUST be under 10 words
- No quotes, no trailing punctuation

GENERAL:
- The actions may include tool calls (file edits, reads, searches, terminal commands) AND/OR non-tool reasoning/analysis
- If there are ONLY thinking headers or reasoning (no tool calls), summarize WHAT was considered/planned, NOT what was done
- For thinking-only summaries, use phrases like: "Considered...", "Planned...", "Analyzed approach for...", "Reviewed options for..."
- The content may include tool invocations (file edits, reads, searches, terminal commands), reasoning headers, or raw thinking text
- For reasoning headers or thinking text (no tool calls), summarize WHAT was considered/analyzed, NOT that thinking occurred
- For thinking-only summaries, use phrases like: "Considered...", "Planned...", "Analyzed...", "Reviewed..."

TOOL NAME FILTERING:
- NEVER include tool names like "Replace String in File", "Multi Replace String in File", "Create File", "Read File", etc. in the output
Expand All @@ -584,8 +584,8 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
- For creates: "Created", "Added", "Generated"
- For searches: "Searched for", "Looked up", "Investigated"
- For terminal: "Ran command", "Executed"
- For thinking-only (no tools): "Considered", "Planned", "Analyzed approach", "Reviewed options"
- Choose the synonym that best fits the context of what was done
- For reasoning/thinking: "Considered", "Planned", "Analyzed", "Reviewed", "Evaluated"
- Choose the synonym that best fits the context

RULES FOR TOOL CALLS:
1. If the SAME file was both edited AND read: Use a combined phrase like "Reviewed and updated <filename>"
Expand All @@ -598,11 +598,19 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
8. After the file info, you may add a brief summary of other actions if space permits
9. NEVER say "1 file" - always use the actual filename when there's only one file

RULES FOR THINKING-ONLY (no tool calls):
1. If the input contains only reasoning/analysis headers without actual tool invocations, summarize the planning/consideration
RULES FOR REASONING HEADERS (no tool calls):
1. If the input contains reasoning/analysis headers without actual tool invocations, summarize the main topic and what was considered
2. Use past tense verbs that indicate thinking, not doing: "Considered", "Planned", "Analyzed", "Evaluated"
3. Focus on WHAT was being thought about, not that thinking occurred

RULES FOR RAW THINKING TEXT:
1. Extract the main topic or question being considered from the text
2. Identify any specific files, functions, or concepts mentioned
3. Summarize as "Analyzed <topic>" or "Considered <specific thing>"
4. If discussing code structure: "Reviewed <component/architecture>"
5. If discussing a problem: "Analyzed <problem description>"
6. If discussing implementation: "Planned <feature/change>"

EXAMPLES WITH TOOLS:
- "Read HomePage.tsx, Edited HomePage.tsx" → "Reviewed and updated HomePage.tsx"
- "Edited HomePage.tsx" → "Updated HomePage.tsx"
Expand All @@ -618,14 +626,20 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
- "Edited Button.tsx, Edited Button.css, Edited index.ts" → "Modified 3 files"
- "Searched codebase for error handling" → "Looked up error handling"

EXAMPLES WITHOUT TOOLS (thinking-only):
EXAMPLES WITH REASONING HEADERS (no tools):
- "Analyzing component architecture" → "Considered component architecture"
- "Planning refactor strategy" → "Planned refactor strategy"
- "Reviewing error handling approach, Considering edge cases" → "Analyzed error handling approach"
- "Understanding the codebase structure" → "Reviewed codebase structure"
- "Thinking about implementation options" → "Considered implementation options"

Tool calls and reasoning: ${context}`;
EXAMPLES WITH RAW THINKING TEXT:
- "I need to understand how the authentication flow works in this app..." → "Analyzed authentication flow"
- "Let me think about how to refactor this component to be more maintainable..." → "Planned component refactoring"
- "The error seems to be coming from the database connection..." → "Investigated database connection issue"
- "Looking at the UserService class, I see it handles..." → "Reviewed UserService implementation"

Content: ${context}`;

const response = await this.languageModelsService.sendChatRequest(
models[0],
Expand Down Expand Up @@ -794,6 +808,84 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
toolCallLabel = message;

this.toolInvocations.push(toolInvocationOrMarkdown);

// track state for live/still streaming tools, excluding serialized tools
if (toolInvocationOrMarkdown.kind === 'toolInvocation') {
let currentToolLabel = toolCallLabel;
let isComplete = false;

const updateTitle = (updatedMessage: string) => {
if (updatedMessage && updatedMessage !== currentToolLabel) {
// replace old title if exists, otherwise add new
const oldIndex = this.extractedTitles.indexOf(currentToolLabel);
const updatedIndex = this.extractedTitles.indexOf(updatedMessage);

if (oldIndex !== -1) {
if (updatedIndex !== -1 && updatedIndex !== oldIndex) {
this.extractedTitles.splice(oldIndex, 1);
} else {
this.extractedTitles[oldIndex] = updatedMessage;
}
} else if (updatedIndex === -1) {
this.extractedTitles.push(updatedMessage);
}
currentToolLabel = updatedMessage;
this.lastExtractedTitle = updatedMessage;

// make sure not to set title if expanded
if (!this.fixedScrollingMode && !this._isExpanded.read(undefined)) {
this.setTitle(updatedMessage);
}
}
};

this._register(autorun(reader => {
if (isComplete) {
return;
}

const currentState = toolInvocationOrMarkdown.state.read(reader);

if (currentState.type === IChatToolInvocation.StateKind.Completed ||
currentState.type === IChatToolInvocation.StateKind.Cancelled) {
isComplete = true;
return;
}

// streaming
if (currentState.type === IChatToolInvocation.StateKind.Streaming) {
const streamingMessage = currentState.streamingMessage.read(reader);
if (streamingMessage) {
const updatedMessage = typeof streamingMessage === 'string' ? streamingMessage : streamingMessage.value;
updateTitle(updatedMessage);
}
return;
}

// executing (something like `Replacing 67 lines.....`)
if (currentState.type === IChatToolInvocation.StateKind.Executing) {
const progressData = currentState.progress.read(reader);
if (progressData.message) {
const updatedMessage = typeof progressData.message === 'string' ? progressData.message : progressData.message.value;
updateTitle(updatedMessage);
} else {
const invocationMsg = toolInvocationOrMarkdown.invocationMessage;
if (invocationMsg) {
const updatedMessage = typeof invocationMsg === 'string' ? invocationMsg : invocationMsg.value;
updateTitle(updatedMessage);
}
}
return;
}

// confirmations, failures, completed, other, etc
const invocationMsg = toolInvocationOrMarkdown.invocationMessage;
if (invocationMsg) {
const updatedMessage = typeof invocationMsg === 'string' ? invocationMsg : invocationMsg.value;
updateTitle(updatedMessage);
}
}));
}
} else if (toolInvocationOrMarkdown?.kind === 'markdownContent') {
const codeblockInfo = extractCodeblockUrisFromText(toolInvocationOrMarkdown.content.value);
if (codeblockInfo?.uri) {
Expand All @@ -811,6 +903,8 @@ export class ChatThinkingContentPart extends ChatCollapsibleContentPart implemen
this.extractedTitles.push(toolCallLabel);
}

this.lastExtractedTitle = toolCallLabel;

if (!this.fixedScrollingMode && !this._isExpanded.get()) {
this.setTitle(toolCallLabel);
}
Expand Down
Loading