|
|
@@ -71,8 +71,6 @@ export async function presentAssistantMessage(cline: Task) {
|
|
|
cline.presentAssistantMessageLocked = true
|
|
|
cline.presentAssistantMessageHasPendingUpdates = false
|
|
|
|
|
|
- const cachedModelId = cline.api.getModel().id
|
|
|
-
|
|
|
if (cline.currentStreamingContentIndex >= cline.assistantMessageContent.length) {
|
|
|
// This may happen if the last content block was completed before
|
|
|
// streaming could finish. If streaming is finished, and we're out of
|
|
|
@@ -341,7 +339,8 @@ export async function presentAssistantMessage(cline: Task) {
|
|
|
return `[${block.name} for '${block.params.command}']`
|
|
|
case "read_file":
|
|
|
// Check if this model should use the simplified description
|
|
|
- if (shouldUseSingleFileRead(cachedModelId)) {
|
|
|
+ const modelId = cline.api.getModel().id
|
|
|
+ if (shouldUseSingleFileRead(modelId)) {
|
|
|
return getSimpleReadFileToolDescription(block.name, block.params)
|
|
|
} else {
|
|
|
// Prefer native typed args when available; fall back to legacy params
|
|
|
@@ -476,6 +475,14 @@ export async function presentAssistantMessage(cline: Task) {
|
|
|
const toolCallId = (block as any).id
|
|
|
const toolProtocol = toolCallId ? TOOL_PROTOCOL.NATIVE : TOOL_PROTOCOL.XML
|
|
|
|
|
|
+ // Check experimental setting for multiple native tool calls
|
|
|
+ const provider = cline.providerRef.deref()
|
|
|
+ const state = await provider?.getState()
|
|
|
+ const isMultipleNativeToolCallsEnabled = experiments.isEnabled(
|
|
|
+ state?.experiments ?? {},
|
|
|
+ EXPERIMENT_IDS.MULTIPLE_NATIVE_TOOL_CALLS,
|
|
|
+ )
|
|
|
+
|
|
|
const pushToolResult = (content: ToolResponse) => {
|
|
|
if (toolProtocol === TOOL_PROTOCOL.NATIVE) {
|
|
|
// For native protocol, only allow ONE tool_result per tool call
|
|
|
@@ -531,10 +538,20 @@ export async function presentAssistantMessage(cline: Task) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Once a tool result has been collected, ignore all other tool
|
|
|
- // uses since we should only ever present one tool result per
|
|
|
- // message.
|
|
|
- cline.didAlreadyUseTool = true
|
|
|
+ // For XML protocol: Only one tool per message is allowed
|
|
|
+ // For native protocol with experimental flag enabled: Multiple tools can be executed in sequence
|
|
|
+ // For native protocol with experimental flag disabled: Single tool per message (default safe behavior)
|
|
|
+ if (toolProtocol === TOOL_PROTOCOL.XML) {
|
|
|
+ // Once a tool result has been collected, ignore all other tool
|
|
|
+ // uses since we should only ever present one tool result per
|
|
|
+ // message (XML protocol only).
|
|
|
+ cline.didAlreadyUseTool = true
|
|
|
+ } else if (toolProtocol === TOOL_PROTOCOL.NATIVE && !isMultipleNativeToolCallsEnabled) {
|
|
|
+ // For native protocol with experimental flag disabled, enforce single tool per message
|
|
|
+ cline.didAlreadyUseTool = true
|
|
|
+ }
|
|
|
+ // If toolProtocol is NATIVE and isMultipleNativeToolCallsEnabled is true,
|
|
|
+ // allow multiple tool calls in sequence (don't set didAlreadyUseTool)
|
|
|
}
|
|
|
|
|
|
const askApproval = async (
|
|
|
@@ -791,7 +808,8 @@ export async function presentAssistantMessage(cline: Task) {
|
|
|
break
|
|
|
case "read_file":
|
|
|
// Check if this model should use the simplified single-file read tool
|
|
|
- if (shouldUseSingleFileRead(cachedModelId)) {
|
|
|
+ const modelId = cline.api.getModel().id
|
|
|
+ if (shouldUseSingleFileRead(modelId)) {
|
|
|
await simpleReadFileTool(
|
|
|
cline,
|
|
|
block,
|