@@ -108,6 +108,9 @@ struct ToolConfirmationView: View {
108108 private var mcpServerName : String ? { ToolAutoApprovalManager . extractMCPServerName ( from: titleText) }
109109 private var conversationId : String { tool. invokeParams? . conversationId ?? " " }
110110 private var invokeMessage : String { tool. invokeParams? . message ?? " " }
111+ private var fetchWebPageURLs : [ String ] {
112+ ToolAutoApprovalManager . extractFetchWebPageURLs ( from: tool. invokeParams? . input)
113+ }
111114 private var isSensitiveFileOperation : Bool { ToolAutoApprovalManager . isSensitiveFileOperation ( message: invokeMessage) }
112115 private var sensitiveFileInfo : ToolAutoApprovalManager . SensitiveFileConfirmationInfo {
113116 ToolAutoApprovalManager . extractSensitiveFileConfirmationInfo ( from: invokeMessage)
@@ -117,13 +120,20 @@ struct ToolConfirmationView: View {
117120 private var shouldShowSensitiveFileSplitButton : Bool {
118121 mcpServerName == nil && isSensitiveFileOperation && !conversationId. isEmpty
119122 }
123+ private var shouldShowFetchWebPageSplitButton : Bool {
124+ ToolAutoApprovalManager . isFetchWebPageOperation ( name: toolName)
125+ && !conversationId. isEmpty
126+ && !fetchWebPageURLs. isEmpty
127+ }
120128
121129 @ViewBuilder
122130 private var confirmationActionView : some View {
123131 if FeatureFlagNotifierImpl . shared. featureFlags. agentModeAutoApproval &&
124132 CopilotPolicyNotifierImpl . shared. copilotPolicy. agentModeAutoApprovalEnabled {
125133 if tool. isToolcallingLoopContinueTool {
126134 continueButton
135+ } else if shouldShowFetchWebPageSplitButton {
136+ fetchWebPageSplitButton
127137 } else if shouldShowSensitiveFileSplitButton {
128138 sensitiveFileSplitButton
129139 } else if shouldShowMCPSplitButton, let serverName = mcpServerName {
@@ -166,6 +176,38 @@ struct ToolConfirmationView: View {
166176 . buttonStyle ( . borderedProminent)
167177 }
168178
179+ private var fetchWebPageMenuItems : [ SplitButtonMenuItem ] {
180+ [
181+ SplitButtonMenuItem (
182+ title: fetchWebPageURLs. count == 1
183+ ? " Allow this URL in this Session "
184+ : " Allow these URLs in this Session "
185+ ) {
186+ chat. send (
187+ . toolCallAcceptedWithApproval(
188+ tool. id,
189+ . fetchWebPage(
190+ conversationId: conversationId,
191+ urls: fetchWebPageURLs
192+ )
193+ )
194+ )
195+ } ,
196+ ]
197+ }
198+
199+ private var fetchWebPageSplitButton : some View {
200+ SplitButton (
201+ title: " Allow Once " ,
202+ isDisabled: false ,
203+ primaryAction: {
204+ chat. send ( . toolCallAccepted( tool. id) )
205+ } ,
206+ menuItems: fetchWebPageMenuItems,
207+ style: . prominent
208+ )
209+ }
210+
169211 private var sensitiveFileMenuItems : [ SplitButtonMenuItem ] {
170212 var items : [ SplitButtonMenuItem ] = [ ]
171213
@@ -325,6 +367,23 @@ struct ToolConfirmationView: View {
325367 ThemedMarkdownText ( text: tool. invokeParams? . message ?? " " , chat: chat)
326368 . frame ( maxWidth: . infinity, alignment: . leading)
327369
370+ if ToolAutoApprovalManager . isFetchWebPageOperation ( name: toolName) ,
371+ !fetchWebPageURLs. isEmpty {
372+ VStack ( alignment: . leading, spacing: 4 ) {
373+ Text ( fetchWebPageURLs. count == 1 ? " URL " : " URLs " )
374+ . scaledFont ( size: chatFontSize - 1 , weight: . semibold)
375+ . foregroundStyle ( . primary)
376+
377+ ForEach ( fetchWebPageURLs, id: \. self) { url in
378+ Text ( url)
379+ . textSelection ( . enabled)
380+ . scaledFont ( size: chatFontSize - 1 )
381+ . foregroundStyle ( . primary)
382+ }
383+ }
384+ . frame ( maxWidth: . infinity, alignment: . leading)
385+ }
386+
328387 HStack {
329388 Button ( action: {
330389 chat. send ( . toolCallCancelled( tool. id) )
0 commit comments