Skip to content

Commit f6bd593

Browse files
authored
AI model compatibility, other misc fixes for release (#2641)
1 parent 0c60f2c commit f6bd593

File tree

11 files changed

+263
-152
lines changed

11 files changed

+263
-152
lines changed

docs/docs/waveai-modes.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ Wave AI now supports provider-based configuration which automatically applies se
2828

2929
### Supported Providers
3030

31-
- **`openai`** - OpenAI API (automatically configures endpoint and secret name)
32-
- **`openrouter`** - OpenRouter API (automatically configures endpoint and secret name)
33-
- **`google`** - Google AI (Gemini)
34-
- **`azure`** - Azure OpenAI Service (modern API)
35-
- **`azure-legacy`** - Azure OpenAI Service (legacy deployment API)
36-
- **`custom`** - Custom API endpoint (fully manual configuration)
31+
- **`openai`** - OpenAI API (automatically configures endpoint and secret name) [[see example](#openai)]
32+
- **`openrouter`** - OpenRouter API (automatically configures endpoint and secret name) [[see example](#openrouter)]
33+
- **`google`** - Google AI (Gemini) [[see example](#google-ai-gemini)]
34+
- **`azure`** - Azure OpenAI Service (modern API) [[see example](#azure-openai-modern-api)]
35+
- **`azure-legacy`** - Azure OpenAI Service (legacy deployment API) [[see example](#azure-openai-legacy-deployment-api)]
36+
- **`custom`** - Custom API endpoint (fully manual configuration) [[see examples](#local-model-examples)]
3737

3838
### Supported API Types
3939

frontend/app/aipanel/aimode.tsx

Lines changed: 178 additions & 103 deletions
Large diffs are not rendered by default.

frontend/app/aipanel/aipanelinput.tsx

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import { formatFileSizeError, isAcceptableFile, validateFileSize } from "@/app/aipanel/ai-utils";
55
import { waveAIHasFocusWithin } from "@/app/aipanel/waveai-focus-utils";
66
import { type WaveAIModel } from "@/app/aipanel/waveai-model";
7+
import { Tooltip } from "@/element/tooltip";
78
import { cn } from "@/util/util";
89
import { useAtom, useAtomValue } from "jotai";
910
import { memo, useCallback, useEffect, useRef } from "react";
@@ -145,31 +146,35 @@ export const AIPanelInput = memo(({ onSubmit, status, model }: AIPanelInputProps
145146
style={{ fontSize: "13px" }}
146147
rows={2}
147148
/>
148-
<button
149-
type="button"
150-
onClick={handleUploadClick}
151-
className={cn(
152-
"absolute bottom-6 right-1 w-3.5 h-3.5 transition-colors flex items-center justify-center text-gray-400 hover:text-accent cursor-pointer"
153-
)}
154-
>
155-
<i className="fa fa-paperclip text-xs"></i>
156-
</button>
157-
<button
158-
type="submit"
159-
disabled={status !== "ready" || !input.trim()}
160-
className={cn(
161-
"absolute bottom-2 right-1 w-3.5 h-3.5 transition-colors flex items-center justify-center",
162-
status !== "ready" || !input.trim()
163-
? "text-gray-400"
164-
: "text-accent/80 hover:text-accent cursor-pointer"
165-
)}
166-
>
167-
{status === "streaming" ? (
168-
<i className="fa fa-spinner fa-spin text-xs"></i>
169-
) : (
170-
<i className="fa fa-paper-plane text-xs"></i>
171-
)}
172-
</button>
149+
<Tooltip content="Attach files" placement="top" divClassName="absolute bottom-6.5 right-1">
150+
<button
151+
type="button"
152+
onClick={handleUploadClick}
153+
className={cn(
154+
"w-5 h-5 transition-colors flex items-center justify-center text-gray-400 hover:text-accent cursor-pointer"
155+
)}
156+
>
157+
<i className="fa fa-paperclip text-sm"></i>
158+
</button>
159+
</Tooltip>
160+
<Tooltip content="Send message (Enter)" placement="top" divClassName="absolute bottom-1.5 right-1">
161+
<button
162+
type="submit"
163+
disabled={status !== "ready" || !input.trim()}
164+
className={cn(
165+
"w-5 h-5 transition-colors flex items-center justify-center",
166+
status !== "ready" || !input.trim()
167+
? "text-gray-400"
168+
: "text-accent/80 hover:text-accent cursor-pointer"
169+
)}
170+
>
171+
{status === "streaming" ? (
172+
<i className="fa fa-spinner fa-spin text-sm"></i>
173+
) : (
174+
<i className="fa fa-paper-plane text-sm"></i>
175+
)}
176+
</button>
177+
</Tooltip>
173178
</div>
174179
</form>
175180
</div>

frontend/app/aipanel/aipanelmessages.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export const AIPanelMessages = memo(({ messages, status, onContextMenu }: AIPane
6262
onContextMenu={onContextMenu}
6363
>
6464
<div className="mb-2">
65-
<AIModeDropdown />
65+
<AIModeDropdown compatibilityMode={true} />
6666
</div>
6767
{messages.map((message, index) => {
6868
const isLastMessage = index === messages.length - 1;

frontend/app/aipanel/waveai-model.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,16 @@ export class WaveAIModel {
547547
await createBlock(blockDef, false, true);
548548
}
549549

550+
async openWaveAIConfig() {
551+
const blockDef: BlockDef = {
552+
meta: {
553+
view: "waveconfig",
554+
file: "waveai.json",
555+
},
556+
};
557+
await createBlock(blockDef, false, true);
558+
}
559+
550560
openRestoreBackupModal(toolcallid: string) {
551561
globalStore.set(this.restoreBackupModalToolCallId, toolcallid);
552562
}

frontend/app/view/waveconfig/waveconfig-model.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { RpcApi } from "@/app/store/wshclientapi";
88
import { TabRpcClient } from "@/app/store/wshrpcutil";
99
import { SecretsContent } from "@/app/view/waveconfig/secretscontent";
1010
import { WaveConfigView } from "@/app/view/waveconfig/waveconfig";
11-
import { WaveAIVisualContent } from "@/app/view/waveconfig/waveaivisual";
11+
import { isWindows } from "@/util/platformutil";
1212
import { base64ToString, stringToBase64 } from "@/util/util";
1313
import { atom, type PrimitiveAtom } from "jotai";
1414
import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
@@ -22,6 +22,7 @@ export type ConfigFile = {
2222
path: string;
2323
language?: string;
2424
deprecated?: boolean;
25+
description?: string;
2526
docsUrl?: string;
2627
validator?: ConfigValidator;
2728
isSecrets?: boolean;
@@ -77,10 +78,11 @@ const configFiles: ConfigFile[] = [
7778
path: "connections.json",
7879
language: "json",
7980
docsUrl: "https://docs.waveterm.dev/connections",
81+
description: isWindows() ? "SSH hosts and WSL distros" : "SSH hosts",
8082
hasJsonView: true,
8183
},
8284
{
83-
name: "Widgets",
85+
name: "Sidebar Widgets",
8486
path: "widgets.json",
8587
language: "json",
8688
docsUrl: "https://docs.waveterm.dev/customwidgets",
@@ -90,12 +92,14 @@ const configFiles: ConfigFile[] = [
9092
name: "Wave AI Modes",
9193
path: "waveai.json",
9294
language: "json",
95+
description: "Local models and BYOK",
96+
docsUrl: "https://docs.waveterm.dev/waveai-modes",
9397
validator: validateWaveAiJson,
9498
hasJsonView: true,
9599
// visualComponent: WaveAIVisualContent,
96100
},
97101
{
98-
name: "Backgrounds",
102+
name: "Tab Backgrounds",
99103
path: "presets/bg.json",
100104
language: "json",
101105
docsUrl: "https://docs.waveterm.dev/presets#background-configurations",

frontend/app/view/waveconfig/waveconfig.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,16 @@ const ConfigSidebar = memo(({ model }: ConfigSidebarProps) => {
4141
<div
4242
key={file.path}
4343
onClick={() => handleFileSelect(file)}
44-
className={`px-4 py-2 border-b border-border cursor-pointer transition-colors whitespace-nowrap overflow-hidden text-ellipsis ${
44+
className={`px-4 py-2 border-b border-border cursor-pointer transition-colors ${
4545
selectedFile?.path === file.path ? "bg-accentbg text-primary" : "hover:bg-secondary/50"
4646
}`}
4747
>
48-
{file.name}
48+
<div className="whitespace-nowrap overflow-hidden text-ellipsis">{file.name}</div>
49+
{file.description && (
50+
<div className="text-xs text-muted mt-0.5 whitespace-nowrap overflow-hidden text-ellipsis">
51+
{file.description}
52+
</div>
53+
)}
4954
</div>
5055
))}
5156
{deprecatedConfigFiles.length > 0 && (
@@ -168,15 +173,16 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps<WaveConfigVi
168173
{selectedFile.name}
169174
</div>
170175
{selectedFile.docsUrl && (
171-
<a
172-
href={`${selectedFile.docsUrl}?ref=waveconfig`}
173-
target="_blank"
174-
rel="noopener noreferrer"
175-
className="!text-muted-foreground hover:!text-primary transition-colors ml-1 shrink-0 cursor-pointer"
176-
title="View documentation"
177-
>
178-
<i className="fa fa-book text-sm" />
179-
</a>
176+
<Tooltip content="View documentation">
177+
<a
178+
href={`${selectedFile.docsUrl}?ref=waveconfig`}
179+
target="_blank"
180+
rel="noopener noreferrer"
181+
className="!text-muted-foreground hover:!text-primary transition-colors ml-1 shrink-0 cursor-pointer"
182+
>
183+
<i className="fa fa-book text-sm" />
184+
</a>
185+
</Tooltip>
180186
)}
181187
<div className="text-xs text-muted-foreground font-mono pb-0.5 ml-1 truncate @max-w450:hidden">
182188
{selectedFile.path}

frontend/types/gotypes.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ declare global {
3030
"ai:azureresourcename"?: string;
3131
"ai:azuredeployment"?: string;
3232
"ai:capabilities"?: string[];
33+
"ai:switchcompat"?: string[];
3334
"waveai:cloud"?: boolean;
3435
"waveai:premium"?: boolean;
3536
};

pkg/wconfig/defaultconfig/waveai.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"ai:apitype": "openai-responses",
99
"ai:model": "gpt-5-mini",
1010
"ai:thinkinglevel": "low",
11-
"ai:capabilities": ["tools", "images", "pdfs"]
11+
"ai:capabilities": ["tools", "images", "pdfs"],
12+
"ai:switchcompat": ["wavecloud"]
1213
},
1314
"waveai@balanced": {
1415
"display:name": "Balanced",
@@ -20,7 +21,8 @@
2021
"ai:model": "gpt-5.1",
2122
"ai:thinkinglevel": "low",
2223
"ai:capabilities": ["tools", "images", "pdfs"],
23-
"waveai:premium": true
24+
"waveai:premium": true,
25+
"ai:switchcompat": ["wavecloud"]
2426
},
2527
"waveai@deep": {
2628
"display:name": "Deep",
@@ -32,6 +34,7 @@
3234
"ai:model": "gpt-5.1",
3335
"ai:thinkinglevel": "medium",
3436
"ai:capabilities": ["tools", "images", "pdfs"],
35-
"waveai:premium": true
37+
"waveai:premium": true,
38+
"ai:switchcompat": ["wavecloud"]
3639
}
3740
}

pkg/wconfig/settingsconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ type AIModeConfigType struct {
279279
AzureResourceName string `json:"ai:azureresourcename,omitempty"`
280280
AzureDeployment string `json:"ai:azuredeployment,omitempty"`
281281
Capabilities []string `json:"ai:capabilities,omitempty" jsonschema:"enum=pdfs,enum=images,enum=tools"`
282+
SwitchCompat []string `json:"ai:switchcompat,omitempty"`
282283
WaveAICloud bool `json:"waveai:cloud,omitempty"`
283284
WaveAIPremium bool `json:"waveai:premium,omitempty"`
284285
}

0 commit comments

Comments
 (0)