Skip to content

Commit d272a4e

Browse files
authored
New AIPanel (#2370)
Massive PR, over 13k LOC updated, 128 commits to implement the first pass at the new Wave AI panel. Two backend adapters (OpenAI and Anthropic), layout changes to support the panel, keyboard shortcuts, and a huge focus/layout change to integrate the panel seamlessly into the UI. Also fixes some small issues found during the Wave AI journey (zoom fixes, documentation, more scss removal, circular dependency issues, settings, etc)
1 parent 5a95e82 commit d272a4e

166 files changed

Lines changed: 13482 additions & 2183 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.golangci.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
linters:
2+
disable:
3+
- unused
4+
- unusedfunc
5+
- unusedparams
6+
issues:
7+
exclude-rules:
8+
- linters:
9+
- unused
10+
text: "unused parameter"

.roo/rules/rules.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ It has a TypeScript/React frontend and a Go backend. They talk together over `ws
3939
- NEVER use cursor-help (it looks terrible)
4040
- useAtom() and useAtomValue() are react HOOKS, so they must be called at the component level not inline in JSX
4141
- If you use React.memo(), make sure to add a displayName for the component
42+
- In general, when writing functions, we prefer _early returns_ rather than putting the majority of a function inside of an if block.
4243

4344
### Styling
4445

4546
- We use **Tailwind v4** to style. Custom stuff is defined in frontend/tailwindsetup.css
46-
- _never_ use cursor-help (it looks terrible)
47+
- _never_ use cursor-help, or cursor-not-allowed (it looks terrible)
4748
- We have custom CSS setup as well, so it is a hybrid system. For new code we prefer tailwind, and are working to migrate code to all use tailwind.
4849

4950
### Code Generation
@@ -78,6 +79,7 @@ These files provide step-by-step instructions, code examples, and best practices
7879
- With React hooks, always complete all hook calls at the top level before any conditional returns (including jotai hook calls useAtom and useAtomValue); when a user explicitly tells you a function handles null inputs, trust them and stop trying to "protect" it with unnecessary checks or workarounds.
7980
- **Match response length to question complexity** - For simple, direct questions in Ask mode (especially those that can be answered in 1-2 sentences), provide equally brief answers. Save detailed explanations for complex topics or when explicitly requested.
8081
- **CRITICAL** - useAtomValue and useAtom are React HOOKS. They cannot be used inline in JSX code, they must appear at the top of a component in the hooks area of the react code.
82+
- for simple functions, we prefer `if (!cond) { return }; functionality;` pattern overn `if (cond) { functionality }` because it produces less indentation and is easier to follow.
8183

8284
### Strict Comment Rules
8385

@@ -98,6 +100,72 @@ These files provide step-by-step instructions, code examples, and best practices
98100
- **When in doubt, leave it out**. No comment is better than a redundant comment.
99101
- **Never add comments explaining code changes** - The code should speak for itself, and version control tracks changes. The one exception to this rule is if it is a very unobvious implementation. Something that someone would typically implement in a different (wrong) way. Then the comment helps us remember WHY we changed it to a less obvious implementation.
100102

103+
### Jotai Model Pattern (our rules)
104+
105+
- **Atoms live on the model.**
106+
- **Simple atoms:** define as **field initializers**.
107+
- **Atoms that depend on values/other atoms:** create in the **constructor**.
108+
- Models **never use React hooks**; they use `globalStore.get/set`.
109+
- It’s fine to call model methods from **event handlers** or **`useEffect`**.
110+
111+
```ts
112+
// model/MyModel.ts
113+
import { atom, type PrimitiveAtom } from "jotai";
114+
import { globalStore } from "@/app/store/jotaiStore";
115+
116+
export class MyModel {
117+
// simple atoms (field init)
118+
statusAtom = atom<"idle" | "running" | "error">("idle");
119+
outputAtom = atom("");
120+
121+
// ctor-built atoms (need types)
122+
lengthAtom!: PrimitiveAtom<number>; // read-only derived via atom(get=>...)
123+
thresholdedAtom!: PrimitiveAtom<boolean>;
124+
125+
constructor(initialThreshold = 20) {
126+
this.lengthAtom = atom((get) => get(this.outputAtom).length);
127+
this.thresholdedAtom = atom((get) => get(this.lengthAtom) > initialThreshold);
128+
}
129+
130+
async doWork() {
131+
globalStore.set(this.statusAtom, "running");
132+
try {
133+
for await (const chunk of this.stream()) {
134+
globalStore.set(this.outputAtom, (prev) => prev + chunk);
135+
}
136+
globalStore.set(this.statusAtom, "idle");
137+
} catch {
138+
globalStore.set(this.statusAtom, "error");
139+
}
140+
}
141+
142+
private async *stream() {
143+
/* ... */
144+
}
145+
}
146+
```
147+
148+
```tsx
149+
// component usage (events & effects OK)
150+
import { useAtomValue } from "jotai";
151+
152+
function Panel({ model }: { model: MyModel }) {
153+
const status = useAtomValue(model.statusAtom);
154+
const isBig = useAtomValue(model.thresholdedAtom);
155+
156+
const onClick = () => model.doWork();
157+
// useEffect(() => { model.doWork() }, [model])
158+
159+
return (
160+
<div>
161+
{status}{String(isBig)}
162+
</div>
163+
);
164+
}
165+
```
166+
167+
**Remember:** atoms on the model, simple-as-fields, ctor for dependent/derived, updates via `globalStore.set/get`.
168+
101169
### Tool Use
102170

103171
Do NOT use write_to_file unless it is a new file or very short. Always prefer to use replace_in_file. Often your diffs fail when a file may be out of date in your cache vs the actual on-disk format. You should RE-READ the file and try to create diffs again if your diffs fail rather than fall back to write_to_file. If you feel like your ONLY option is to use write_to_file please ask first.

Taskfile.yml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ tasks:
2626
- docsite:build:embedded
2727
- build:backend
2828
env:
29-
WCLOUD_ENDPOINT: "https://api-dev.waveterm.dev/central"
30-
WCLOUD_WS_ENDPOINT: "wss://wsapi-dev.waveterm.dev/"
29+
WAVETERM_ENVFILE: "{{.ROOT_DIR}}/.env"
30+
WCLOUD_ENDPOINT: "https://api-dev.waveterm.dev"
31+
WCLOUD_WS_ENDPOINT: "wss://wsapi-dev.waveterm.dev"
3132

3233
electron:start:
3334
desc: Run the Electron application directly.
@@ -39,6 +40,7 @@ tasks:
3940
- docsite:build:embedded
4041
- build:backend
4142
env:
43+
WAVETERM_ENVFILE: "{{.ROOT_DIR}}/.env"
4244
WCLOUD_ENDPOINT: "https://api-dev.waveterm.dev"
4345
WCLOUD_WS_ENDPOINT: "wss://wsapi-dev.waveterm.dev"
4446

@@ -49,6 +51,7 @@ tasks:
4951
- npm:install
5052
- build:backend:quickdev
5153
env:
54+
WAVETERM_ENVFILE: "{{.ROOT_DIR}}/.env"
5255
WCLOUD_ENDPOINT: "https://api-dev.waveterm.dev/central"
5356
WCLOUD_WS_ENDPOINT: "wss://wsapi-dev.waveterm.dev/"
5457

@@ -134,6 +137,12 @@ tasks:
134137
- docsite:build:embedded
135138
- build:backend
136139

140+
build:frontend:dev:
141+
desc: Build the frontend in development mode.
142+
cmd: npm run build:dev
143+
deps:
144+
- npm:install
145+
137146
build:backend:
138147
desc: Build the wavesrv and wsh components.
139148
cmds:
@@ -144,6 +153,14 @@ tasks:
144153
desc: Build only the wavesrv component for quickdev (arm64 macOS only, no generate, no wsh).
145154
cmds:
146155
- task: build:server:quickdev
156+
sources:
157+
- go.mod
158+
- go.sum
159+
- pkg/**/*.go
160+
- cmd/**/*.go
161+
- tsunami/go.mod
162+
- tsunami/go.sum
163+
- tsunami/**/*.go
147164

148165
build:schema:
149166
desc: Build the schema for configuration.
@@ -189,8 +206,6 @@ tasks:
189206
desc: Build the wavesrv component for quickdev (arm64 macOS only, no generate).
190207
platforms: [darwin]
191208
cmds:
192-
- cmd: "{{.RM}} dist/bin/wavesrv*"
193-
ignore_error: true
194209
- task: build:server:internal
195210
vars:
196211
ARCHS: arm64

0 commit comments

Comments
 (0)