Skip to content
Merged
Show file tree
Hide file tree
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
32 changes: 8 additions & 24 deletions lib/messages/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
buildToolIdList,
createSyntheticAssistantMessageWithToolPart,
isIgnoredUserMessage,
hasReasoningInCurrentAssistantTurn,
} from "./utils"
import { getFilePathFromParameters, isProtectedFilePath } from "../protected-file-patterns"
import { getLastUserMessage } from "../shared-utils"
Expand Down Expand Up @@ -139,31 +138,16 @@ export const insertPruneToolContext = (
return
}

const userInfo = lastUserMessage.info as UserMessage
const providerID = userInfo.model.providerID
const modelID = userInfo.model.modelID
const isGitHubCopilot =
providerID === "github-copilot" || providerID === "github-copilot-enterprise"

// TODO: This can probably be improved further to only trigger for the appropriate thinking settings
// This setting is also potentially only necessary for claude subscription, API seems to not need this
// validation. See more here: https://platform.claude.com/docs/en/build-with-claude/extended-thinking
const isAnthropic = modelID.includes("claude")

if (isGitHubCopilot) {
const lastMessage = messages[messages.length - 1]
if (lastMessage?.info?.role === "user" && !isIgnoredUserMessage(lastMessage)) {
return
}
}

// Anthropic extended thinking models require a thinking block at the start of its turn
if (isAnthropic) {
if (!hasReasoningInCurrentAssistantTurn(messages)) {
return
}
// Never inject immediately following a user message - wait until assistant has started its turn
// This avoids interfering with model reasoning/thinking phases
// TODO: This can be skipped if there is a good way to check if the model has reasoning,
// can't find a good way to do this yet
const lastMessage = messages[messages.length - 1]
if (lastMessage?.info?.role === "user" && !isIgnoredUserMessage(lastMessage)) {
return
}

const userInfo = lastUserMessage.info as UserMessage
const variant = state.variant ?? userInfo.variant
messages.push(
createSyntheticAssistantMessageWithToolPart(lastUserMessage, prunableToolsContent, variant),
Expand Down
20 changes: 0 additions & 20 deletions lib/messages/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,23 +207,3 @@ export const isIgnoredUserMessage = (message: WithParts): boolean => {

return true
}

export const hasReasoningInCurrentAssistantTurn = (messages: WithParts[]): boolean => {
for (let i = messages.length - 1; i >= 0; i--) {
const message = messages[i]
if (message.info?.role === "user") {
if (isIgnoredUserMessage(message)) {
continue
}
return false
}
if (message.info?.role === "assistant" && message.parts) {
for (const part of message.parts) {
if (part.type === "reasoning") {
return true
}
}
}
}
return false
}