Skip to content

Commit 1ce60a0

Browse files
authored
feat: select assistant polishes (#7218)
* add login logout buttons and remove padding * remove logout button from list * create a new assistant file when signed out * added tooltip and hover
1 parent c37c811 commit 1ce60a0

File tree

6 files changed

+113
-32
lines changed

6 files changed

+113
-32
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { IDE } from "..";
2+
import { joinPathsToUri } from "../util/uri";
3+
4+
const DEFAULT_ASSISTANT_FILE = `# This is an example assistant configuration file
5+
# It is used to define custom AI assistants within Continue
6+
# Each assistant file can be accessed by selecting it from the assistant dropdown
7+
8+
# To learn more, see the full assistant reference: https://docs.continue.dev/reference
9+
10+
name: Example Assistant
11+
version: 1.0.0
12+
schema: v1
13+
14+
# Models define which AI models this assistant can use
15+
models:
16+
- name: my gpt-5
17+
provider: openai
18+
model: gpt-5
19+
apiKey: YOUR_API_KEY_HERE
20+
21+
# Context providers define what information the assistant can access
22+
context:
23+
- provider: code
24+
- provider: docs
25+
- provider: diff
26+
- provider: terminal
27+
- provider: problems
28+
- provider: folder
29+
- provider: codebase
30+
`;
31+
32+
export async function createNewAssistantFile(
33+
ide: IDE,
34+
assistantPath: string | undefined,
35+
): Promise<void> {
36+
const workspaceDirs = await ide.getWorkspaceDirs();
37+
if (workspaceDirs.length === 0) {
38+
throw new Error(
39+
"No workspace directories found. Make sure you've opened a folder in your IDE.",
40+
);
41+
}
42+
43+
const baseDirUri = joinPathsToUri(
44+
workspaceDirs[0],
45+
assistantPath ?? ".continue/assistants",
46+
);
47+
48+
// Find the first available filename
49+
let counter = 0;
50+
let assistantFileUri: string;
51+
do {
52+
const suffix = counter === 0 ? "" : `-${counter}`;
53+
assistantFileUri = joinPathsToUri(
54+
baseDirUri,
55+
`new-assistant${suffix}.yaml`,
56+
);
57+
counter++;
58+
} while (await ide.fileExists(assistantFileUri));
59+
60+
await ide.writeFile(assistantFileUri, DEFAULT_ASSISTANT_FILE);
61+
await ide.openFile(assistantFileUri);
62+
}

core/core.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import {
5151
import { BLOCK_TYPES, ConfigYaml } from "@continuedev/config-yaml";
5252
import { getDiffFn, GitDiffCache } from "./autocomplete/snippets/gitDiffCache";
5353
import { stringifyMcpPrompt } from "./commands/slash/mcpSlashCommand";
54+
import { createNewAssistantFile } from "./config/createNewAssistantFile";
5455
import { isLocalDefinitionFile } from "./config/loadLocalAssistants";
5556
import { CodebaseRulesCache } from "./config/markdown/loadCodebaseRules";
5657
import {
@@ -354,6 +355,13 @@ export class Core {
354355
);
355356
});
356357

358+
on("config/newAssistantFile", async (msg) => {
359+
await createNewAssistantFile(this.ide, undefined);
360+
await this.configHandler.reloadConfig(
361+
"Assistant file created (config/newAssistantFile message)",
362+
);
363+
});
364+
357365
on("config/addLocalWorkspaceBlock", async (msg) => {
358366
await createNewWorkspaceBlockFile(this.ide, msg.data.blockType);
359367
await this.configHandler.reloadConfig(

core/protocol/core.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ import {
4949
ControlPlaneSessionInfo,
5050
} from "../control-plane/AuthTypes";
5151
import { FreeTrialStatus } from "../control-plane/client";
52-
import { NextEditOutcome } from "../nextEdit/types";
5352
import { ProcessedItem } from "../nextEdit/NextEditPrefetchQueue";
53+
import { NextEditOutcome } from "../nextEdit/types";
5454

5555
export enum OnboardingModes {
5656
API_KEY = "API Key",
@@ -86,6 +86,7 @@ export type ToCoreFromIdeOrWebviewProtocol = {
8686
];
8787
"config/addLocalWorkspaceBlock": [{ blockType: BlockType }, void];
8888
"config/newPromptFile": [undefined, void];
89+
"config/newAssistantFile": [undefined, void];
8990
"config/ideSettingsUpdate": [IdeSettings, void];
9091
"config/getSerializedProfileInfo": [
9192
undefined,

core/protocol/passThrough.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const WEBVIEW_TO_CORE_PASS_THROUGH: (keyof ToCoreFromWebviewProtocol)[] =
1818
"devdata/log",
1919
"config/addModel",
2020
"config/newPromptFile",
21+
"config/newAssistantFile",
2122
"config/ideSettingsUpdate",
2223
"config/addLocalWorkspaceBlock",
2324
"config/getSerializedProfileInfo",

extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/constants/MessageTypes.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class MessageTypes {
8383
"devdata/log",
8484
"config/addModel",
8585
"config/newPromptFile",
86+
"config/newAssistantFile",
8687
"config/ideSettingsUpdate",
8788
"config/addLocalWorkspaceBlock",
8889
"config/getSerializedProfileInfo",

gui/src/components/AssistantAndOrgListbox/index.tsx

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { ArrowPathIcon, PlusIcon } from "@heroicons/react/24/outline";
1+
import {
2+
ArrowPathIcon,
3+
ArrowRightEndOnRectangleIcon,
4+
ArrowRightStartOnRectangleIcon,
5+
PlusIcon,
6+
} from "@heroicons/react/24/outline";
27
import { AuthType, isOnPremSession } from "core/control-plane/AuthTypes";
38
import { useContext, useEffect, useRef } from "react";
49
import { useAuth } from "../../context/Auth";
@@ -10,7 +15,7 @@ import {
1015
} from "../../redux/slices/profilesSlice";
1116
import { getMetaKeyLabel, isMetaEquivalentKeyPressed } from "../../util";
1217
import { cn } from "../../util/cn";
13-
import { useLump } from "../mainInput/Lump/LumpContext";
18+
import { ToolTip } from "../gui/Tooltip";
1419
import {
1520
Listbox,
1621
ListboxOption,
@@ -27,7 +32,6 @@ export function AssistantAndOrgListbox() {
2732
const listboxRef = useRef<HTMLDivElement>(null);
2833
const currentOrg = useAppSelector(selectCurrentOrg);
2934
const ideMessenger = useContext(IdeMessengerContext);
30-
const { isToolbarExpanded } = useLump();
3135
const {
3236
profiles,
3337
selectedProfile,
@@ -38,7 +42,6 @@ export function AssistantAndOrgListbox() {
3842
refreshProfiles,
3943
} = useAuth();
4044
const configLoading = useAppSelector((store) => store.config.loading);
41-
const smallFont = useFontSize(-3);
4245
const tinyFont = useFontSize(-4);
4346
const shouldRenderOrgInfo =
4447
session && organizations.length > 1 && !isOnPremSession(session);
@@ -50,10 +53,14 @@ export function AssistantAndOrgListbox() {
5053
}
5154

5255
function onNewAssistant() {
53-
void ideMessenger.request("controlPlane/openUrl", {
54-
path: "/new",
55-
orgSlug: currentOrg?.slug,
56-
});
56+
if (session) {
57+
void ideMessenger.request("controlPlane/openUrl", {
58+
path: "/new",
59+
orgSlug: currentOrg?.slug,
60+
});
61+
} else {
62+
void ideMessenger.request("config/newAssistantFile", undefined);
63+
}
5764
close();
5865
}
5966

@@ -108,12 +115,29 @@ export function AssistantAndOrgListbox() {
108115
<div className="relative" ref={listboxRef}>
109116
<SelectedAssistantButton selectedProfile={selectedProfile} />
110117
<Transition>
111-
<ListboxOptions className="-translate-x-1.5 pb-0">
112-
<div className="border-border border-x-0 border-t-0 border-solid px-2 py-3">
113-
<div className="flex flex-col gap-2 pb-1 pl-1">
114-
{session && session?.AUTH_TYPE !== AuthType.OnPrem && (
115-
<span className="text-description-muted flex items-center pb-1">
116-
{session?.account.id}
118+
<ListboxOptions
119+
className="-translate-x-1.5 pb-0"
120+
style={{ zIndex: 200 }}
121+
>
122+
<div className="border-border border-x-0 border-t-0 border-solid px-2 py-2">
123+
<div className="flex flex-col gap-2 pl-1">
124+
{session ? (
125+
<span className="text-description-muted flex items-center justify-between gap-x-1">
126+
{session?.AUTH_TYPE !== AuthType.OnPrem &&
127+
session?.account.id}
128+
<ArrowRightStartOnRectangleIcon
129+
className="h-3 w-3 cursor-pointer hover:brightness-125"
130+
onClick={onLogout}
131+
data-tooltip-id="logout-tooltip"
132+
/>
133+
<ToolTip id="logout-tooltip">Logout</ToolTip>
134+
</span>
135+
) : (
136+
<span
137+
className="text-description-muted flex cursor-pointer items-center justify-end gap-x-1 hover:brightness-125"
138+
onClick={() => login(false)}
139+
>
140+
Log In <ArrowRightEndOnRectangleIcon className="h-3 w-3" />
117141
</span>
118142
)}
119143
{shouldRenderOrgInfo && (
@@ -138,7 +162,7 @@ export function AssistantAndOrgListbox() {
138162
value="new-assistant"
139163
fontSizeModifier={-2}
140164
className="border-border border-b px-2 py-1.5"
141-
onClick={session ? onNewAssistant : () => login(false)}
165+
onClick={onNewAssistant}
142166
>
143167
<span
144168
className="text-description flex flex-row items-center"
@@ -170,22 +194,6 @@ export function AssistantAndOrgListbox() {
170194
</span>
171195
</ListboxOption>
172196

173-
{session && (
174-
<ListboxOption
175-
value="log-out"
176-
fontSizeModifier={-2}
177-
className="border-border border-b px-3 py-1.5"
178-
onClick={onLogout}
179-
>
180-
<div
181-
className="text-description flex flex-row items-center"
182-
style={{ fontSize: tinyFont }}
183-
>
184-
Log out
185-
</div>
186-
</ListboxOption>
187-
)}
188-
189197
<div
190198
className="text-description border-border flex items-center justify-between gap-1.5 border-x-0 border-b-0 border-t border-solid px-2 py-2"
191199
style={{ fontSize: tinyFont }}

0 commit comments

Comments
 (0)