mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-11-28 05:00:26 +08:00
188 lines
6 KiB
TypeScript
188 lines
6 KiB
TypeScript
// Copyright 2025, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { waveAIHasSelection } from "@/app/aipanel/waveai-focus-utils";
|
|
import { ContextMenuModel } from "@/app/store/contextmenu";
|
|
import { atoms, isDev } from "@/app/store/global";
|
|
import { globalStore } from "@/app/store/jotaiStore";
|
|
import { RpcApi } from "@/app/store/wshclientapi";
|
|
import { TabRpcClient } from "@/app/store/wshrpcutil";
|
|
import { WaveAIModel } from "./waveai-model";
|
|
|
|
export async function handleWaveAIContextMenu(e: React.MouseEvent, showCopy: boolean): Promise<void> {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
const model = WaveAIModel.getInstance();
|
|
const menu: ContextMenuItem[] = [];
|
|
|
|
if (showCopy) {
|
|
const hasSelection = waveAIHasSelection();
|
|
if (hasSelection) {
|
|
menu.push({
|
|
role: "copy",
|
|
});
|
|
menu.push({ type: "separator" });
|
|
}
|
|
}
|
|
|
|
menu.push({
|
|
label: "New Chat",
|
|
click: () => {
|
|
model.clearChat();
|
|
},
|
|
});
|
|
|
|
menu.push({ type: "separator" });
|
|
|
|
const rtInfo = await RpcApi.GetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
});
|
|
|
|
const rateLimitInfo = globalStore.get(atoms.waveAIRateLimitInfoAtom);
|
|
const hasPremium = !rateLimitInfo || rateLimitInfo.unknown || rateLimitInfo.preq > 0;
|
|
const currentAIMode = rtInfo?.["waveai:mode"] ?? (hasPremium ? "waveai@balanced" : "waveai@quick");
|
|
const defaultTokens = model.inBuilder ? 24576 : 4096;
|
|
const currentMaxTokens = rtInfo?.["waveai:maxoutputtokens"] ?? defaultTokens;
|
|
|
|
const aiModeSubmenu: ContextMenuItem[] = [
|
|
{
|
|
label: "Quick (gpt-5-mini)",
|
|
type: "checkbox",
|
|
checked: currentAIMode === "waveai@quick",
|
|
click: () => {
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:mode": "waveai@quick" },
|
|
});
|
|
},
|
|
},
|
|
{
|
|
label: hasPremium ? "Balanced (gpt-5.1, low thinking)" : "Balanced (premium)",
|
|
type: "checkbox",
|
|
checked: currentAIMode === "waveai@balanced",
|
|
enabled: hasPremium,
|
|
click: () => {
|
|
if (!hasPremium) return;
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:mode": "waveai@balanced" },
|
|
});
|
|
},
|
|
},
|
|
{
|
|
label: hasPremium ? "Deep (gpt-5.1, full thinking)" : "Deep (premium)",
|
|
type: "checkbox",
|
|
checked: currentAIMode === "waveai@deep",
|
|
enabled: hasPremium,
|
|
click: () => {
|
|
if (!hasPremium) return;
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:mode": "waveai@deep" },
|
|
});
|
|
},
|
|
},
|
|
];
|
|
|
|
const maxTokensSubmenu: ContextMenuItem[] = [];
|
|
|
|
if (model.inBuilder) {
|
|
maxTokensSubmenu.push(
|
|
{
|
|
label: "24k",
|
|
type: "checkbox",
|
|
checked: currentMaxTokens === 24576,
|
|
click: () => {
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:maxoutputtokens": 24576 },
|
|
});
|
|
},
|
|
},
|
|
{
|
|
label: "64k (Pro)",
|
|
type: "checkbox",
|
|
checked: currentMaxTokens === 65536,
|
|
click: () => {
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:maxoutputtokens": 65536 },
|
|
});
|
|
},
|
|
}
|
|
);
|
|
} else {
|
|
if (isDev()) {
|
|
maxTokensSubmenu.push({
|
|
label: "1k (Dev Testing)",
|
|
type: "checkbox",
|
|
checked: currentMaxTokens === 1024,
|
|
click: () => {
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:maxoutputtokens": 1024 },
|
|
});
|
|
},
|
|
});
|
|
}
|
|
maxTokensSubmenu.push(
|
|
{
|
|
label: "4k",
|
|
type: "checkbox",
|
|
checked: currentMaxTokens === 4096,
|
|
click: () => {
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:maxoutputtokens": 4096 },
|
|
});
|
|
},
|
|
},
|
|
{
|
|
label: "16k (Pro)",
|
|
type: "checkbox",
|
|
checked: currentMaxTokens === 16384,
|
|
click: () => {
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:maxoutputtokens": 16384 },
|
|
});
|
|
},
|
|
},
|
|
{
|
|
label: "64k (Pro)",
|
|
type: "checkbox",
|
|
checked: currentMaxTokens === 65536,
|
|
click: () => {
|
|
RpcApi.SetRTInfoCommand(TabRpcClient, {
|
|
oref: model.orefContext,
|
|
data: { "waveai:maxoutputtokens": 65536 },
|
|
});
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
menu.push({
|
|
label: "AI Mode",
|
|
submenu: aiModeSubmenu,
|
|
});
|
|
|
|
menu.push({
|
|
label: "Max Output Tokens",
|
|
submenu: maxTokensSubmenu,
|
|
});
|
|
|
|
if (model.canCloseWaveAIPanel()) {
|
|
menu.push({ type: "separator" });
|
|
|
|
menu.push({
|
|
label: "Hide Wave AI",
|
|
click: () => {
|
|
model.closeWaveAIPanel();
|
|
},
|
|
});
|
|
}
|
|
|
|
ContextMenuModel.showContextMenu(menu, e);
|
|
}
|