diff --git a/frontend/app/view/waveai/waveai.tsx b/frontend/app/view/waveai/waveai.tsx index 5519b745d..f31e676b3 100644 --- a/frontend/app/view/waveai/waveai.tsx +++ b/frontend/app/view/waveai/waveai.tsx @@ -106,14 +106,15 @@ export class WaveAiModel implements ViewModel { }); this.viewText = atom((get) => { const viewTextChildren: HeaderElem[] = []; - const settings = get(atoms.settingsAtom); - const isCloud = isBlank(settings?.["ai:apitoken"]) && isBlank(settings?.["ai:baseurl"]); + const aiOpts = this.getAiOpts(); + const aiName = this.getAiName(); + const isCloud = isBlank(aiOpts.apitoken) && isBlank(aiOpts.baseurl); let modelText = "gpt-4o-mini"; - if (!isCloud && !isBlank(settings?.["ai:model"])) { - if (!isBlank(settings?.["ai:name"])) { - modelText = settings["ai:name"]; + if (!isCloud && !isBlank(aiOpts.model)) { + if (!isBlank(aiName)) { + modelText = aiName; } else { - modelText = settings["ai:model"]; + modelText = aiOpts.model; } } if (isCloud) { @@ -124,8 +125,8 @@ export class WaveAiModel implements ViewModel { disabled: true, }); } else { - const baseUrl = settings["ai:baseurl"] ?? "OpenAI Default Endpoint"; - const modelName = settings["ai:model"]; + const baseUrl = aiOpts.baseurl ?? "OpenAI Default Endpoint"; + const modelName = aiOpts.model; if (baseUrl.startsWith("http://localhost") || baseUrl.startsWith("http://127.0.0.1")) { viewTextChildren.push({ elemtype: "iconbutton", @@ -172,6 +173,29 @@ export class WaveAiModel implements ViewModel { return false; } + getAiOpts(): OpenAIOptsType { + const blockMeta = globalStore.get(this.blockAtom)?.meta ?? {}; + const settings = globalStore.get(atoms.settingsAtom) ?? {}; + const opts: OpenAIOptsType = { + model: blockMeta["ai:model"] ?? settings["ai:model"] ?? null, + apitype: blockMeta["ai:apitype"] ?? settings["ai:apitype"] ?? null, + orgid: blockMeta["ai:orgid"] ?? settings["ai:orgid"] ?? null, + apitoken: blockMeta["ai:apitoken"] ?? settings["ai:apitoken"] ?? null, + apiversion: blockMeta["ai:apiversion"] ?? settings["ai:apiversion"] ?? null, + maxtokens: blockMeta["ai:maxtokens"] ?? settings["ai:maxtokens"] ?? null, + timeoutms: blockMeta["ai:timeoutms"] ?? settings["ai:timeoutms"] ?? 60000, + baseurl: blockMeta["ai:baseurl"] ?? settings["ai:baseurl"] ?? null, + }; + return opts; + } + + getAiName(): string { + const blockMeta = globalStore.get(this.blockAtom)?.meta ?? {}; + const settings = globalStore.get(atoms.settingsAtom) ?? {}; + const name = blockMeta["ai:name"] ?? settings["ai:name"] ?? null; + return name; + } + useWaveAi() { const messages = useAtomValue(this.messagesAtom); const addMessage = useSetAtom(this.addMessageAtom); @@ -189,17 +213,7 @@ export class WaveAiModel implements ViewModel { }; addMessage(newMessage); // send message to backend and get response - const settings = globalStore.get(atoms.settingsAtom) ?? {}; - const opts: OpenAIOptsType = { - model: settings["ai:model"], - apitype: settings["ai:apitype"], - orgid: settings["ai:orgid"], - apitoken: settings["ai:apitoken"], - apiversion: settings["ai:apiversion"], - maxtokens: settings["ai:maxtokens"], - timeoutms: settings["ai:timeoutms"] ?? 60000, - baseurl: settings["ai:baseurl"], - }; + const opts = this.getAiOpts(); const newPrompt: OpenAIPromptMessageType = { role: "user", content: text, diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index afe523925..0fcdc6fba 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -275,15 +275,15 @@ declare global { "display:order"?: number; icon?: string; "icon:color"?: string; - frame?: boolean; "frame:*"?: boolean; + frame?: boolean; "frame:bordercolor"?: string; "frame:bordercolor:focused"?: string; "frame:title"?: string; "frame:icon"?: string; "frame:text"?: string; - cmd?: string; "cmd:*"?: boolean; + cmd?: string; "cmd:interactive"?: boolean; "cmd:login"?: boolean; "cmd:runonstart"?: boolean; @@ -292,11 +292,21 @@ declare global { "cmd:env"?: {[key: string]: string}; "cmd:cwd"?: string; "cmd:nowsh"?: boolean; + "ai:*"?: boolean; + "ai:apitype"?: string; + "ai:baseurl"?: string; + "ai:apitoken"?: string; + "ai:name"?: string; + "ai:model"?: string; + "ai:orgid"?: string; + "ai:apiversion"?: string; + "ai:maxtokens"?: number; + "ai:timeoutms"?: number; "graph:*"?: boolean; "graph:numpoints"?: number; "graph:metrics"?: string[]; - bg?: string; "bg:*"?: boolean; + bg?: string; "bg:opacity"?: number; "bg:blendmode"?: string; "term:*"?: boolean; diff --git a/pkg/waveobj/metaconsts.go b/pkg/waveobj/metaconsts.go index 02a738d7f..e12e04d67 100644 --- a/pkg/waveobj/metaconsts.go +++ b/pkg/waveobj/metaconsts.go @@ -29,16 +29,16 @@ const ( MetaKey_Icon = "icon" MetaKey_IconColor = "icon:color" - MetaKey_Frame = "frame" MetaKey_FrameClear = "frame:*" + MetaKey_Frame = "frame" MetaKey_FrameBorderColor = "frame:bordercolor" MetaKey_FrameBorderColor_Focused = "frame:bordercolor:focused" MetaKey_FrameTitle = "frame:title" MetaKey_FrameIcon = "frame:icon" MetaKey_FrameText = "frame:text" - MetaKey_Cmd = "cmd" MetaKey_CmdClear = "cmd:*" + MetaKey_Cmd = "cmd" MetaKey_CmdInteractive = "cmd:interactive" MetaKey_CmdLogin = "cmd:login" MetaKey_CmdRunOnStart = "cmd:runonstart" @@ -48,12 +48,23 @@ const ( MetaKey_CmdCwd = "cmd:cwd" MetaKey_CmdNoWsh = "cmd:nowsh" + MetaKey_AiClear = "ai:*" + MetaKey_AiApiType = "ai:apitype" + MetaKey_AiBaseURL = "ai:baseurl" + MetaKey_AiApiToken = "ai:apitoken" + MetaKey_AiName = "ai:name" + MetaKey_AiModel = "ai:model" + MetaKey_AiOrgID = "ai:orgid" + MetaKey_AIApiVersion = "ai:apiversion" + MetaKey_AiMaxTokens = "ai:maxtokens" + MetaKey_AiTimeoutMs = "ai:timeoutms" + MetaKey_GraphClear = "graph:*" MetaKey_GraphNumPoints = "graph:numpoints" MetaKey_GraphMetrics = "graph:metrics" - MetaKey_Bg = "bg" MetaKey_BgClear = "bg:*" + MetaKey_Bg = "bg" MetaKey_BgOpacity = "bg:opacity" MetaKey_BgBlendMode = "bg:blendmode" diff --git a/pkg/waveobj/wtypemeta.go b/pkg/waveobj/wtypemeta.go index 0fce994cd..b8e9b6e98 100644 --- a/pkg/waveobj/wtypemeta.go +++ b/pkg/waveobj/wtypemeta.go @@ -28,16 +28,16 @@ type MetaTSType struct { Icon string `json:"icon,omitempty"` IconColor string `json:"icon:color,omitempty"` - Frame bool `json:"frame,omitempty"` FrameClear bool `json:"frame:*,omitempty"` + Frame bool `json:"frame,omitempty"` FrameBorderColor string `json:"frame:bordercolor,omitempty"` FrameBorderColor_Focused string `json:"frame:bordercolor:focused,omitempty"` FrameTitle string `json:"frame:title,omitempty"` FrameIcon string `json:"frame:icon,omitempty"` FrameText string `json:"frame:text,omitempty"` - Cmd string `json:"cmd,omitempty"` CmdClear bool `json:"cmd:*,omitempty"` + Cmd string `json:"cmd,omitempty"` CmdInteractive bool `json:"cmd:interactive,omitempty"` CmdLogin bool `json:"cmd:login,omitempty"` CmdRunOnStart bool `json:"cmd:runonstart,omitempty"` @@ -47,13 +47,25 @@ type MetaTSType struct { CmdCwd string `json:"cmd:cwd,omitempty"` CmdNoWsh bool `json:"cmd:nowsh,omitempty"` + // AI options match settings + AiClear bool `json:"ai:*,omitempty"` + AiApiType string `json:"ai:apitype,omitempty"` + AiBaseURL string `json:"ai:baseurl,omitempty"` + AiApiToken string `json:"ai:apitoken,omitempty"` + AiName string `json:"ai:name,omitempty"` + AiModel string `json:"ai:model,omitempty"` + AiOrgID string `json:"ai:orgid,omitempty"` + AIApiVersion string `json:"ai:apiversion,omitempty"` + AiMaxTokens float64 `json:"ai:maxtokens,omitempty"` + AiTimeoutMs float64 `json:"ai:timeoutms,omitempty"` + GraphClear bool `json:"graph:*,omitempty"` GraphNumPoints int `json:"graph:numpoints,omitempty"` GraphMetrics []string `json:"graph:metrics,omitempty"` // for tabs - Bg string `json:"bg,omitempty"` BgClear bool `json:"bg:*,omitempty"` + Bg string `json:"bg,omitempty"` BgOpacity float64 `json:"bg:opacity,omitempty"` BgBlendMode string `json:"bg:blendmode,omitempty"`