Compare commits

...

1 Commits

Author SHA1 Message Date
celestial-vault b4be2c17ee extract isClaude4ModelFamily helper 2025-06-09 13:16:48 -07:00
2 changed files with 27 additions and 31 deletions
+20 -31
View File
@@ -113,6 +113,7 @@ import { isInTestMode } from "../../services/test/TestMode"
import { processFilesIntoText } from "@integrations/misc/extract-text"
import { featureFlagsService } from "@services/posthog/feature-flags/FeatureFlagsService"
import { StreamingJsonReplacer, ChangeLocation } from "@core/assistant-message/diff-json"
import { isClaude4ModelFamily } from "@/utils/model-utils"
export const USE_EXPERIMENTAL_CLAUDE4_FEATURES = false
@@ -1637,12 +1638,6 @@ export class Task {
}
}
private async isClaude4ModelFamily(): Promise<boolean> {
const model = this.api.getModel()
const modelId = model.id
return modelId.includes("sonnet-4") || modelId.includes("opus-4")
}
async *attemptApiRequest(previousApiReqIndex: number): ApiStream {
// Wait for MCP servers to be connected before generating system prompt
await pWaitFor(() => this.mcpHub.isConnecting !== true, { timeout: 10_000 }).catch(() => {
@@ -1656,8 +1651,8 @@ export class Task {
const supportsBrowserUse = modelSupportsBrowserUse && !disableBrowserTool // only enable browser use if the model supports it and the user hasn't disabled it
const isClaude4ModelFamily = await this.isClaude4ModelFamily()
let systemPrompt = await SYSTEM_PROMPT(cwd, supportsBrowserUse, this.mcpHub, this.browserSettings, isClaude4ModelFamily)
const isClaude4Model = isClaude4ModelFamily(this.api)
let systemPrompt = await SYSTEM_PROMPT(cwd, supportsBrowserUse, this.mcpHub, this.browserSettings, isClaude4Model)
let settingsCustomInstructions = this.customInstructions?.trim()
await this.migratePreferredLanguageToolSetting()
@@ -1938,7 +1933,6 @@ export class Task {
// Get final list of replacements
const allReplacements = this.streamingJsonReplacer.getSuccessfullyParsedItems()
// console.log(`Total replacements applied: ${allReplacements.length}`)
// Cleanup
this.streamingJsonReplacer = undefined
@@ -1968,7 +1962,6 @@ export class Task {
if (this.didCompleteReadingStream) {
this.userMessageContentReady = true
}
// console.log("no more content blocks to stream! this shouldn't happen?")
this.presentAssistantMessageLocked = false
return
//throw new Error("No more content blocks to stream! This shouldn't happen...") // remove and just return after testing
@@ -2104,11 +2097,11 @@ export class Task {
break
}
const pushToolResult = (content: ToolResponse, isClaude4ModelFamily: boolean = false) => {
const pushToolResult = (content: ToolResponse, isClaude4Model: boolean = false) => {
if (typeof content === "string") {
const resultText = content || "(tool did not return anything)"
if (isClaude4ModelFamily && USE_EXPERIMENTAL_CLAUDE4_FEATURES) {
if (isClaude4Model && USE_EXPERIMENTAL_CLAUDE4_FEATURES) {
// Claude 4 family: Use function_results format
this.userMessageContent.push({
type: "text",
@@ -2194,7 +2187,7 @@ export class Task {
}
}
const handleError = async (action: string, error: Error, isClaude4ModelFamily: boolean = false) => {
const handleError = async (action: string, error: Error, isClaude4Model: boolean = false) => {
if (this.abandoned) {
console.log("Ignoring error since task was abandoned (i.e. from task cancellation after resetting)")
return
@@ -2205,7 +2198,7 @@ export class Task {
`Error ${action}:\n${error.message ?? JSON.stringify(serializeError(error), null, 2)}`,
)
pushToolResult(formatResponse.toolError(errorString), isClaude4ModelFamily)
pushToolResult(formatResponse.toolError(errorString), isClaude4Model)
}
// If block is partial, remove partial closing tag so its not presented to user
@@ -2283,9 +2276,9 @@ export class Task {
const currentFullJson = block.params.diff
// Check if we should use streaming (e.g., for specific models)
const isClaude4ModelFamily = await this.isClaude4ModelFamily()
const isClaude4Model = isClaude4ModelFamily(this.api)
// Going through claude family of models
if (isClaude4ModelFamily && USE_EXPERIMENTAL_CLAUDE4_FEATURES && currentFullJson) {
if (isClaude4Model && USE_EXPERIMENTAL_CLAUDE4_FEATURES && currentFullJson) {
console.log("[EDIT] Streaming JSON replacement")
const streamingResult = await this.handleStreamingJsonReplacement(
block,
@@ -2677,7 +2670,7 @@ export class Task {
}
}
case "list_files": {
const isClaude4ModelFamily = await this.isClaude4ModelFamily()
const isClaude4Model = isClaude4ModelFamily(this.api)
const relDirPath: string | undefined = block.params.path
const recursiveRaw: string | undefined = block.params.recursive
const recursive = recursiveRaw?.toLowerCase() === "true"
@@ -2703,10 +2696,7 @@ export class Task {
} else {
if (!relDirPath) {
this.consecutiveMistakeCount++
pushToolResult(
await this.sayAndCreateMissingParamError("list_files", "path"),
isClaude4ModelFamily,
)
pushToolResult(await this.sayAndCreateMissingParamError("list_files", "path"), isClaude4Model)
await this.saveCheckpoint()
break
}
@@ -2757,12 +2747,12 @@ export class Task {
true,
)
}
pushToolResult(result, isClaude4ModelFamily)
pushToolResult(result, isClaude4Model)
await this.saveCheckpoint()
break
}
} catch (error) {
await handleError("listing files", error, isClaude4ModelFamily)
await handleError("listing files", error, isClaude4Model)
await this.saveCheckpoint()
break
}
@@ -2850,7 +2840,7 @@ export class Task {
}
}
case "search_files": {
const isClaude4ModelFamily = await this.isClaude4ModelFamily()
const isClaude4Model = isClaude4ModelFamily(this.api)
const relDirPath: string | undefined = block.params.path
const regex: string | undefined = block.params.regex
const filePattern: string | undefined = block.params.file_pattern
@@ -2880,7 +2870,7 @@ export class Task {
this.consecutiveMistakeCount++
pushToolResult(
await this.sayAndCreateMissingParamError("search_files", "path"),
isClaude4ModelFamily,
isClaude4Model,
)
await this.saveCheckpoint()
break
@@ -2889,7 +2879,7 @@ export class Task {
this.consecutiveMistakeCount++
pushToolResult(
await this.sayAndCreateMissingParamError("search_files", "regex"),
isClaude4ModelFamily,
isClaude4Model,
)
await this.saveCheckpoint()
break
@@ -2940,12 +2930,12 @@ export class Task {
true,
)
}
pushToolResult(results, isClaude4ModelFamily)
pushToolResult(results, isClaude4Model)
await this.saveCheckpoint()
break
}
} catch (error) {
await handleError("searching files", error, isClaude4ModelFamily)
await handleError("searching files", error, isClaude4Model)
await this.saveCheckpoint()
break
}
@@ -4520,9 +4510,8 @@ export class Task {
assistantMessage += chunk.text
// parse raw assistant message into content blocks
const prevLength = this.assistantMessageContent.length
const isClaude4ModelFamily = await this.isClaude4ModelFamily()
if (isClaude4ModelFamily && USE_EXPERIMENTAL_CLAUDE4_FEATURES) {
const isClaude4Model = isClaude4ModelFamily(this.api)
if (isClaude4Model && USE_EXPERIMENTAL_CLAUDE4_FEATURES) {
this.assistantMessageContent = parseAssistantMessageV3(assistantMessage)
} else {
this.assistantMessageContent = parseAssistantMessageV2(assistantMessage)
+7
View File
@@ -0,0 +1,7 @@
import { ApiHandler } from "@api/index"
export function isClaude4ModelFamily(api: ApiHandler): boolean {
const model = api.getModel()
const modelId = model.id
return modelId.includes("sonnet-4") || modelId.includes("opus-4")
}