1+ // Copyright 2025, Command Line Inc.
2+ // SPDX-License-Identifier: Apache-2.0
3+
4+ import { waveAIHasSelection } from "@/app/aipanel/waveai-focus-utils" ;
5+ import { ContextMenuModel } from "@/app/store/contextmenu" ;
6+ import { RpcApi } from "@/app/store/wshclientapi" ;
7+ import { TabRpcClient } from "@/app/store/wshrpcutil" ;
8+ import { WaveAIModel } from "./waveai-model" ;
9+
10+ export async function handleWaveAIContextMenu ( e : React . MouseEvent , onClose ?: ( ) => void ) : Promise < void > {
11+ e . preventDefault ( ) ;
12+ e . stopPropagation ( ) ;
13+
14+ const model = WaveAIModel . getInstance ( ) ;
15+ const menu : ContextMenuItem [ ] = [ ] ;
16+
17+ const hasSelection = waveAIHasSelection ( ) ;
18+ if ( hasSelection ) {
19+ menu . push ( {
20+ role : "copy" ,
21+ } ) ;
22+ menu . push ( { type : "separator" } ) ;
23+ }
24+
25+ menu . push ( {
26+ label : "New Chat" ,
27+ click : ( ) => {
28+ model . clearChat ( ) ;
29+ } ,
30+ } ) ;
31+
32+ menu . push ( { type : "separator" } ) ;
33+
34+ const rtInfo = await RpcApi . GetRTInfoCommand ( TabRpcClient , {
35+ oref : model . orefContext ,
36+ } ) ;
37+
38+ const currentThinkingLevel = rtInfo ?. [ "waveai:thinkinglevel" ] ?? "medium" ;
39+ const defaultTokens = model . inBuilder ? 24576 : 4096 ;
40+ const currentMaxTokens = rtInfo ?. [ "waveai:maxoutputtokens" ] ?? defaultTokens ;
41+
42+ const thinkingLevelSubmenu : ContextMenuItem [ ] = [
43+ {
44+ label : "Low" ,
45+ type : "checkbox" ,
46+ checked : currentThinkingLevel === "low" ,
47+ click : ( ) => {
48+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
49+ oref : model . orefContext ,
50+ data : { "waveai:thinkinglevel" : "low" } ,
51+ } ) ;
52+ } ,
53+ } ,
54+ {
55+ label : "Medium" ,
56+ type : "checkbox" ,
57+ checked : currentThinkingLevel === "medium" ,
58+ click : ( ) => {
59+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
60+ oref : model . orefContext ,
61+ data : { "waveai:thinkinglevel" : "medium" } ,
62+ } ) ;
63+ } ,
64+ } ,
65+ {
66+ label : "High" ,
67+ type : "checkbox" ,
68+ checked : currentThinkingLevel === "high" ,
69+ click : ( ) => {
70+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
71+ oref : model . orefContext ,
72+ data : { "waveai:thinkinglevel" : "high" } ,
73+ } ) ;
74+ } ,
75+ } ,
76+ ] ;
77+
78+ const maxTokensSubmenu : ContextMenuItem [ ] = [ ] ;
79+
80+ if ( model . inBuilder ) {
81+ maxTokensSubmenu . push (
82+ {
83+ label : "24k" ,
84+ type : "checkbox" ,
85+ checked : currentMaxTokens === 24576 ,
86+ click : ( ) => {
87+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
88+ oref : model . orefContext ,
89+ data : { "waveai:maxoutputtokens" : 24576 } ,
90+ } ) ;
91+ } ,
92+ } ,
93+ {
94+ label : "64k (Pro)" ,
95+ type : "checkbox" ,
96+ checked : currentMaxTokens === 65536 ,
97+ click : ( ) => {
98+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
99+ oref : model . orefContext ,
100+ data : { "waveai:maxoutputtokens" : 65536 } ,
101+ } ) ;
102+ } ,
103+ }
104+ ) ;
105+ } else {
106+ maxTokensSubmenu . push (
107+ {
108+ label : "4k" ,
109+ type : "checkbox" ,
110+ checked : currentMaxTokens === 4096 ,
111+ click : ( ) => {
112+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
113+ oref : model . orefContext ,
114+ data : { "waveai:maxoutputtokens" : 4096 } ,
115+ } ) ;
116+ } ,
117+ } ,
118+ {
119+ label : "16k (Pro)" ,
120+ type : "checkbox" ,
121+ checked : currentMaxTokens === 16384 ,
122+ click : ( ) => {
123+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
124+ oref : model . orefContext ,
125+ data : { "waveai:maxoutputtokens" : 16384 } ,
126+ } ) ;
127+ } ,
128+ } ,
129+ {
130+ label : "64k (Pro)" ,
131+ type : "checkbox" ,
132+ checked : currentMaxTokens === 65536 ,
133+ click : ( ) => {
134+ RpcApi . SetRTInfoCommand ( TabRpcClient , {
135+ oref : model . orefContext ,
136+ data : { "waveai:maxoutputtokens" : 65536 } ,
137+ } ) ;
138+ } ,
139+ }
140+ ) ;
141+ }
142+
143+ menu . push ( {
144+ label : "Thinking Level" ,
145+ submenu : thinkingLevelSubmenu ,
146+ } ) ;
147+
148+ menu . push ( {
149+ label : "Max Output Tokens" ,
150+ submenu : maxTokensSubmenu ,
151+ } ) ;
152+
153+ menu . push ( { type : "separator" } ) ;
154+
155+ menu . push ( {
156+ label : "Hide Wave AI" ,
157+ click : ( ) => {
158+ onClose ?.( ) ;
159+ } ,
160+ } ) ;
161+
162+ ContextMenuModel . showContextMenu ( menu , e ) ;
163+ }
0 commit comments