-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathAgentModeMenu.swift
More file actions
165 lines (144 loc) · 5.74 KB
/
AgentModeMenu.swift
File metadata and controls
165 lines (144 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import AppKit
import ConversationServiceProvider
// MARK: - Agent Mode Menu Builder
struct AgentModeMenu {
let builtInAgentModes: [ConversationMode]
let customAgents: [ConversationMode]
let selectedAgent: ConversationMode
let fontScale: Double
let onSelectAgent: (ConversationMode) -> Void
let onEditAgent: (ConversationMode) -> Void
let onDeleteAgent: (ConversationMode) -> Void
let onCreateAgent: () -> Void
func createMenu() -> NSMenu {
let menu = NSMenu()
let menuHasSelection = true // Always show checkmarks for clarity
// Calculate the maximum width needed across all items
let maxWidth = calculateMaxMenuItemWidth(menuHasSelection: menuHasSelection)
// Add built-in agent modes
addBuiltInModes(to: menu, menuHasSelection: menuHasSelection, width: maxWidth)
// Add custom agents if any
if !customAgents.isEmpty {
menu.addItem(.separator())
addCustomAgents(to: menu, menuHasSelection: menuHasSelection, width: maxWidth)
}
// Add create option
menu.addItem(.separator())
addCreateOption(to: menu, menuHasSelection: menuHasSelection, width: maxWidth)
return menu
}
private func calculateMaxMenuItemWidth(menuHasSelection: Bool) -> CGFloat {
var maxWidth: CGFloat = 0
// Check built-in modes
for mode in builtInAgentModes {
let width = AgentModeButtonMenuItem.calculateMenuItemWidth(
name: mode.name,
hasIcon: true,
isSelected: selectedAgent.id == mode.id,
menuHasSelection: menuHasSelection,
hasEditDelete: false,
fontScale: fontScale
)
maxWidth = max(maxWidth, width)
}
// Check custom agents
for agent in customAgents {
let width = AgentModeButtonMenuItem.calculateMenuItemWidth(
name: agent.name,
hasIcon: false,
isSelected: selectedAgent.id == agent.id,
menuHasSelection: menuHasSelection,
hasEditDelete: true,
fontScale: fontScale
)
maxWidth = max(maxWidth, width)
}
// Check create option
let createWidth = AgentModeButtonMenuItem.calculateMenuItemWidth(
name: "Create an agent",
hasIcon: true,
isSelected: false,
menuHasSelection: menuHasSelection,
hasEditDelete: false,
fontScale: fontScale
)
maxWidth = max(maxWidth, createWidth)
return maxWidth
}
private func addBuiltInModes(to menu: NSMenu, menuHasSelection: Bool, width: CGFloat) {
for mode in builtInAgentModes {
let agentItem = NSMenuItem()
// Determine icon: use checklist for Plan, Agent icon for others
let iconName = AgentModeIcon.icon(for: mode.name)
let agentView = AgentModeButtonMenuItem(
name: mode.name,
iconName: iconName,
isSelected: selectedAgent.id == mode.id,
menuHasSelection: menuHasSelection,
fontScale: fontScale,
fixedWidth: width,
onSelect: { [onSelectAgent] in
onSelectAgent(mode)
menu.cancelTracking()
}
)
agentView.toolTip = mode.description
agentItem.view = agentView
menu.addItem(agentItem)
}
}
private func addCustomAgents(to menu: NSMenu, menuHasSelection: Bool, width: CGFloat) {
for agent in customAgents {
let agentItem = NSMenuItem()
agentItem.representedObject = agent
// Create custom view for the menu item
let customView = AgentModeButtonMenuItem(
name: agent.name,
iconName: nil,
isSelected: selectedAgent.id == agent.id,
menuHasSelection: menuHasSelection,
fontScale: fontScale,
fixedWidth: width,
onSelect: { [onSelectAgent] in
onSelectAgent(agent)
menu.cancelTracking()
},
onEdit: { [onEditAgent] in
onEditAgent(agent)
menu.cancelTracking()
},
onDelete: { [onDeleteAgent] in
onDeleteAgent(agent)
menu.cancelTracking()
}
)
customView.toolTip = agent.description
agentItem.view = customView
menu.addItem(agentItem)
}
}
private func addCreateOption(to menu: NSMenu, menuHasSelection: Bool, width: CGFloat) {
let createItem = NSMenuItem()
let createView = AgentModeButtonMenuItem(
name: "Create an agent",
iconName: AgentModeIcon.plus,
isSelected: false,
menuHasSelection: menuHasSelection,
fontScale: fontScale,
fixedWidth: width,
onSelect: { [onCreateAgent] in
onCreateAgent()
menu.cancelTracking()
}
)
createItem.view = createView
menu.addItem(createItem)
}
func showMenu(relativeTo button: NSButton) {
let menu = createMenu()
// Show menu aligned to the button's edge, positioned below the button
let buttonFrame = button.frame
let menuOrigin = NSPoint(x: buttonFrame.minX, y: buttonFrame.maxY)
menu.popUp(positioning: menu.items.first, at: menuOrigin, in: button.superview)
}
}