Skip to content

Commit 0d894cf

Browse files
small nits with example queries
1 parent c9a7fcc commit 0d894cf

File tree

11 files changed

+117
-56
lines changed

11 files changed

+117
-56
lines changed

packages/web/src/app/[domain]/chat/[id]/components/chatThreadPanel.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
'use client';
22

33
import { ResizablePanel } from '@/components/ui/resizable';
4-
import { ChatBoxToolbarProps } from '@/features/chat/components/chatBox/chatBoxToolbar';
54
import { ChatThread } from '@/features/chat/components/chatThread';
6-
import { SBChatMessage, SET_CHAT_STATE_QUERY_PARAM, SetChatStatePayload } from '@/features/chat/types';
5+
import { LanguageModelInfo, SBChatMessage, SET_CHAT_STATE_QUERY_PARAM, SetChatStatePayload } from '@/features/chat/types';
6+
import { RepositoryQuery } from '@/lib/types';
77
import { CreateUIMessage } from 'ai';
88
import { useRouter, useSearchParams } from 'next/navigation';
99
import { useEffect, useState } from 'react';
1010
import { useChatId } from '../../useChatId';
1111

1212
interface ChatThreadPanelProps {
13-
chatBoxToolbarProps: Omit<ChatBoxToolbarProps, "selectedRepos" | "onSelectedReposChange">;
13+
languageModels: LanguageModelInfo[];
14+
repos: RepositoryQuery[];
1415
order: number;
1516
messages: SBChatMessage[];
1617
isChatReadonly: boolean;
1718
}
1819

1920
export const ChatThreadPanel = ({
20-
chatBoxToolbarProps,
21+
languageModels,
22+
repos,
2123
order,
2224
messages,
2325
isChatReadonly,
@@ -61,7 +63,8 @@ export const ChatThreadPanel = ({
6163
id={chatId}
6264
initialMessages={messages}
6365
inputMessage={inputMessage}
64-
chatBoxToolbarProps={chatBoxToolbarProps}
66+
languageModels={languageModels}
67+
repos={repos}
6568
selectedRepos={selectedRepos}
6669
onSelectedReposChange={setSelectedRepos}
6770
isChatReadonly={isChatReadonly}

packages/web/src/app/[domain]/chat/[id]/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ export default async function Page({ params }: PageProps) {
7272
/>
7373
<AnimatedResizableHandle />
7474
<ChatThreadPanel
75-
chatBoxToolbarProps={{
76-
languageModels,
77-
repos: indexedRepos,
78-
}}
75+
languageModels={languageModels}
76+
repos={indexedRepos}
7977
messages={messages}
8078
order={2}
8179
isChatReadonly={isReadonly}

packages/web/src/app/[domain]/chat/components/newChatPanel.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,28 @@
22

33
import { ResizablePanel } from "@/components/ui/resizable";
44
import { ChatBox } from "@/features/chat/components/chatBox";
5-
import { ChatBoxToolbar, ChatBoxToolbarProps } from "@/features/chat/components/chatBox/chatBoxToolbar";
5+
import { ChatBoxToolbar } from "@/features/chat/components/chatBox/chatBoxToolbar";
66
import { CustomSlateEditor } from "@/features/chat/customSlateEditor";
77
import { useCreateNewChatThread } from "@/features/chat/useCreateNewChatThread";
8+
import { LanguageModelInfo } from "@/features/chat/types";
9+
import { RepositoryQuery } from "@/lib/types";
810
import { useCallback, useState } from "react";
911
import { Descendant } from "slate";
1012

1113
interface NewChatPanelProps {
12-
chatBoxToolbarProps: Omit<ChatBoxToolbarProps, "selectedRepos" | "onSelectedReposChange">;
14+
languageModels: LanguageModelInfo[];
15+
repos: RepositoryQuery[];
1316
order: number;
1417
}
1518

1619
export const NewChatPanel = ({
17-
chatBoxToolbarProps,
20+
languageModels,
21+
repos,
1822
order,
1923
}: NewChatPanelProps) => {
2024
const [selectedRepos, setSelectedRepos] = useState<string[]>([]);
2125
const { createNewChatThread, isLoading } = useCreateNewChatThread();
26+
const [isRepoSelectorOpen, setIsRepoSelectorOpen] = useState(false);
2227

2328
const onSubmit = useCallback((children: Descendant[]) => {
2429
createNewChatThread(children, selectedRepos);
@@ -40,13 +45,16 @@ export const NewChatPanel = ({
4045
className="min-h-[80px]"
4146
preferredSuggestionsBoxPlacement="bottom-start"
4247
isRedirecting={isLoading}
43-
languageModels={chatBoxToolbarProps.languageModels}
48+
languageModels={languageModels}
4449
/>
4550
<div className="w-full flex flex-row items-center bg-accent rounded-b-md px-2">
4651
<ChatBoxToolbar
47-
{...chatBoxToolbarProps}
52+
languageModels={languageModels}
53+
repos={repos}
4854
selectedRepos={selectedRepos}
4955
onSelectedReposChange={setSelectedRepos}
56+
isRepoSelectorOpen={isRepoSelectorOpen}
57+
onRepoSelectorOpenChanged={setIsRepoSelectorOpen}
5058
/>
5159
</div>
5260
</CustomSlateEditor>

packages/web/src/app/[domain]/chat/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,8 @@ export default async function Page({ params }: PageProps) {
4747
/>
4848
<AnimatedResizableHandle />
4949
<NewChatPanel
50-
chatBoxToolbarProps={{
51-
languageModels,
52-
repos: indexedRepos,
53-
}}
50+
languageModels={languageModels}
51+
repos={indexedRepos}
5452
order={2}
5553
/>
5654
</ResizablePanelGroup>

packages/web/src/app/[domain]/components/homepage/agenticSearch.tsx

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@
33
import { Button } from "@/components/ui/button";
44
import { Separator } from "@/components/ui/separator";
55
import { ChatBox } from "@/features/chat/components/chatBox";
6+
import { ChatBoxToolbar } from "@/features/chat/components/chatBox/chatBoxToolbar";
7+
import { LanguageModelInfo } from "@/features/chat/types";
68
import { useCreateNewChatThread } from "@/features/chat/useCreateNewChatThread";
7-
import { FileIcon, LucideIcon, SearchCodeIcon, SearchIcon } from "lucide-react";
8-
import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
9-
import { SearchModeSelector, SearchModeSelectorProps } from "./toolbar";
10-
import { ReactEditor, useSlate } from "slate-react";
119
import { resetEditor } from "@/features/chat/utils";
12-
import { ChatBoxToolbar, ChatBoxToolbarProps } from "@/features/chat/components/chatBox/chatBoxToolbar";
13-
import { getDisplayTime } from "@/lib/utils";
1410
import { useDomain } from "@/hooks/useDomain";
11+
import { RepositoryQuery } from "@/lib/types";
12+
import { getDisplayTime } from "@/lib/utils";
13+
import { BrainIcon, FileIcon, LucideIcon, SearchIcon } from "lucide-react";
1514
import Link from "next/link";
15+
import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
16+
import { ReactEditor, useSlate } from "slate-react";
17+
import { SearchModeSelector, SearchModeSelectorProps } from "./toolbar";
1618

1719
// @todo: we should probably rename this to a different type since it sort-of clashes
1820
// with the Suggestion system we have built into the chat box.
@@ -24,7 +26,7 @@ const suggestionTypes: Record<SuggestionType, {
2426
description: string;
2527
}> = {
2628
understand: {
27-
icon: SearchCodeIcon,
29+
icon: BrainIcon,
2830
title: "Understand",
2931
description: "Understand the codebase",
3032
},
@@ -40,6 +42,7 @@ const suggestionTypes: Record<SuggestionType, {
4042
},
4143
}
4244

45+
4346
const Highlight = ({ children }: { children: React.ReactNode }) => {
4447
return (
4548
<span className="text-highlight">
@@ -48,26 +51,53 @@ const Highlight = ({ children }: { children: React.ReactNode }) => {
4851
)
4952
}
5053

51-
5254
const suggestions: Record<SuggestionType, {
5355
queryText: string;
5456
queryNode?: ReactNode;
57+
openRepoSelector?: boolean;
5558
}[]> = {
5659
understand: [
5760
{
58-
queryText: "How does authentication work in this codebase? @repo:",
59-
queryNode: <span>How does authentication work in this codebase? <Highlight>@repo:</Highlight></span>,
61+
queryText: "How does authentication work in this codebase?",
62+
openRepoSelector: true,
63+
},
64+
{
65+
queryText: "How are API endpoints structured and organized?",
66+
openRepoSelector: true,
67+
},
68+
{
69+
queryText: "How does the build and deployment process work?",
70+
openRepoSelector: true,
71+
},
72+
{
73+
queryText: "How is error handling implemented across the application?",
74+
openRepoSelector: true,
6075
},
6176
],
6277
find: [
6378
{
64-
queryText: "todo",
79+
queryText: "Find examples of different logging libraries used throughout the codebase.",
6580
},
81+
{
82+
queryText: "Find examples of potential security vulnerabilities or authentication issues.",
83+
},
84+
{
85+
queryText: "Find examples of API endpoints and route handlers.",
86+
}
6687
],
6788
summarize: [
6889
{
69-
queryText: "todo",
90+
queryText: "Summarize the purpose of this file @file:",
91+
queryNode: <span>Summarize the purpose of this file <Highlight>@file:</Highlight></span>
92+
},
93+
{
94+
queryText: "Summarize the project structure and architecture.",
95+
openRepoSelector: true,
7096
},
97+
{
98+
queryText: "Provide a quick start guide for ramping up on this codebase.",
99+
openRepoSelector: true,
100+
}
71101
],
72102
}
73103

@@ -76,7 +106,8 @@ const MAX_RECENT_CHAT_HISTORY_COUNT = 10;
76106

77107
interface AgenticSearchProps {
78108
searchModeSelectorProps: SearchModeSelectorProps;
79-
chatBoxToolbarProps: Omit<ChatBoxToolbarProps, "selectedRepos" | "onSelectedReposChange">;
109+
languageModels: LanguageModelInfo[];
110+
repos: RepositoryQuery[];
80111
chatHistory: {
81112
id: string;
82113
createdAt: Date;
@@ -86,7 +117,8 @@ interface AgenticSearchProps {
86117

87118
export const AgenticSearch = ({
88119
searchModeSelectorProps,
89-
chatBoxToolbarProps,
120+
languageModels,
121+
repos,
90122
chatHistory,
91123
}: AgenticSearchProps) => {
92124
const [selectedSuggestionType, _setSelectedSuggestionType] = useState<SuggestionType | undefined>(undefined);
@@ -95,6 +127,7 @@ export const AgenticSearch = ({
95127
const editor = useSlate();
96128
const [selectedRepos, setSelectedRepos] = useState<string[]>([]);
97129
const domain = useDomain();
130+
const [isRepoSelectorOpen, setIsRepoSelectorOpen] = useState(false);
98131

99132
const setSelectedSuggestionType = useCallback((type: SuggestionType | undefined) => {
100133
_setSelectedSuggestionType(type);
@@ -128,15 +161,18 @@ export const AgenticSearch = ({
128161
}}
129162
className="min-h-[50px]"
130163
isRedirecting={isLoading}
131-
languageModels={chatBoxToolbarProps.languageModels}
164+
languageModels={languageModels}
132165
/>
133166
<Separator />
134167
<div className="relative">
135168
<div className="w-full flex flex-row items-center bg-accent rounded-b-md px-2">
136169
<ChatBoxToolbar
137-
{...chatBoxToolbarProps}
170+
languageModels={languageModels}
171+
repos={repos}
138172
selectedRepos={selectedRepos}
139173
onSelectedReposChange={setSelectedRepos}
174+
isRepoSelectorOpen={isRepoSelectorOpen}
175+
onRepoSelectorOpenChanged={setIsRepoSelectorOpen}
140176
/>
141177
<SearchModeSelector
142178
{...searchModeSelectorProps}
@@ -152,15 +188,20 @@ export const AgenticSearch = ({
152188
<p className="text-muted-foreground text-sm mb-2">
153189
{suggestionTypes[selectedSuggestionType].title}
154190
</p>
155-
{suggestions[selectedSuggestionType].map(({ queryText, queryNode }, index) => (
191+
{suggestions[selectedSuggestionType].map(({ queryText, queryNode, openRepoSelector }, index) => (
156192
<div
157193
key={index}
158194
className="flex flex-row items-center gap-2 cursor-pointer hover:bg-muted rounded-md px-1 py-0.5"
159195
onClick={() => {
160196
resetEditor(editor);
161197
editor.insertText(queryText);
162198
setSelectedSuggestionType(undefined);
163-
ReactEditor.focus(editor);
199+
200+
if (openRepoSelector) {
201+
setIsRepoSelectorOpen(true);
202+
} else {
203+
ReactEditor.focus(editor);
204+
}
164205
}}
165206
>
166207
<SearchIcon className="w-4 h-4" />

packages/web/src/app/[domain]/components/homepage/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ export const Homepage = ({
7272
isAgenticSearchEnabled,
7373
onSearchModeChange: setSearchMode,
7474
}}
75-
chatBoxToolbarProps={{
76-
repos: initialRepos,
77-
languageModels,
78-
}}
75+
languageModels={languageModels}
76+
repos={initialRepos}
7977
chatHistory={chatHistory}
8078
/>
8179
</CustomSlateEditor>

packages/web/src/env.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export const env = createEnv({
110110
AWS_REGION: z.string().optional(),
111111

112112
SOURCEBOT_CHAT_MODEL_TEMPERATURE: numberSchema.default(0.3),
113-
SOURCEBOT_CHAT_MAX_STEP_COUNT: numberSchema.default(10),
113+
SOURCEBOT_CHAT_MAX_STEP_COUNT: numberSchema.default(20),
114114

115115
DEBUG_WRITE_CHAT_MESSAGES_TO_FILE: booleanSchema.default('false'),
116116
},

packages/web/src/features/chat/components/chatBox/chatBoxToolbar.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ export interface ChatBoxToolbarProps {
1919
repos: RepositoryQuery[];
2020
selectedRepos: string[];
2121
onSelectedReposChange: (repos: string[]) => void;
22+
isRepoSelectorOpen: boolean;
23+
onRepoSelectorOpenChanged: (isOpen: boolean) => void;
2224
}
2325

2426
export const ChatBoxToolbar = ({
2527
languageModels,
2628
repos,
2729
selectedRepos,
2830
onSelectedReposChange,
31+
isRepoSelectorOpen,
32+
onRepoSelectorOpenChanged,
2933
}: ChatBoxToolbarProps) => {
3034
const editor = useSlate();
3135

@@ -77,6 +81,8 @@ export const ChatBoxToolbar = ({
7781
repos={repos.map((repo) => repo.repoName)}
7882
selectedRepos={selectedRepos}
7983
onSelectedReposChange={onSelectedReposChange}
84+
isOpen={isRepoSelectorOpen}
85+
onOpenChanged={onRepoSelectorOpenChanged}
8086
/>
8187
</TooltipTrigger>
8288
<TooltipContent side="bottom">

packages/web/src/features/chat/components/chatBox/repoSelector.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ interface RepoSelectorProps extends React.ButtonHTMLAttributes<HTMLButtonElement
2929
selectedRepos: string[];
3030
onSelectedReposChange: (repos: string[]) => void;
3131
className?: string;
32+
isOpen: boolean;
33+
onOpenChanged: (isOpen: boolean) => void;
3234
}
3335

3436
export const RepoSelector = React.forwardRef<
@@ -41,17 +43,17 @@ export const RepoSelector = React.forwardRef<
4143
onSelectedReposChange,
4244
className,
4345
selectedRepos,
46+
isOpen,
47+
onOpenChanged,
4448
...props
4549
},
4650
ref
4751
) => {
48-
const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
49-
5052
const handleInputKeyDown = (
5153
event: React.KeyboardEvent<HTMLInputElement>
5254
) => {
5355
if (event.key === "Enter") {
54-
setIsPopoverOpen(true);
56+
onOpenChanged(true);
5557
} else if (event.key === "Backspace" && !event.currentTarget.value) {
5658
const newSelectedRepos = [...selectedRepos];
5759
newSelectedRepos.pop();
@@ -71,13 +73,13 @@ export const RepoSelector = React.forwardRef<
7173
};
7274

7375
const handleTogglePopover = () => {
74-
setIsPopoverOpen((prev) => !prev);
76+
onOpenChanged(!isOpen);
7577
};
7678

7779
return (
7880
<Popover
79-
open={isPopoverOpen}
80-
onOpenChange={setIsPopoverOpen}
81+
open={isOpen}
82+
onOpenChange={onOpenChanged}
8183
>
8284
<PopoverTrigger asChild>
8385
<Button
@@ -110,7 +112,7 @@ export const RepoSelector = React.forwardRef<
110112
<PopoverContent
111113
className="w-auto p-0"
112114
align="start"
113-
onEscapeKeyDown={() => setIsPopoverOpen(false)}
115+
onEscapeKeyDown={() => onOpenChanged(false)}
114116
>
115117
<Command>
116118
<CommandInput

0 commit comments

Comments
 (0)