Skip to content

Commit f9e0500

Browse files
committed
rename search context to search scope
1 parent a5562d7 commit f9e0500

File tree

15 files changed

+153
-164
lines changed

15 files changed

+153
-164
lines changed

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CreateUIMessage } from 'ai';
88
import { useRouter, useSearchParams } from 'next/navigation';
99
import { useEffect, useState } from 'react';
1010
import { useChatId } from '../../useChatId';
11-
import { ContextItem } from '@/features/chat/components/chatBox/contextSelector';
11+
import { SearchScopeItem } from '@/features/chat/components/chatBox/searchScopeSelector';
1212

1313
interface ChatThreadPanelProps {
1414
languageModels: LanguageModelInfo[];
@@ -37,9 +37,9 @@ export const ChatThreadPanel = ({
3737
// Use the last user's last message to determine what repos and contexts we should select by default.
3838
const lastUserMessage = messages.findLast((message) => message.role === "user");
3939
const defaultSelectedRepos = lastUserMessage?.metadata?.selectedRepos ?? [];
40-
const defaultSelectedContexts = lastUserMessage?.metadata?.selectedContexts ?? [];
40+
const defaultSelectedReposets = lastUserMessage?.metadata?.selectedReposets ?? [];
4141

42-
const [selectedItems, setSelectedItems] = useState<ContextItem[]>([
42+
const [selectedItems, setSelectedItems] = useState<SearchScopeItem[]>([
4343
...defaultSelectedRepos.map(repoName => {
4444
const repoInfo = repos.find(r => r.repoName === repoName);
4545
return {
@@ -49,13 +49,13 @@ export const ChatThreadPanel = ({
4949
codeHostType: repoInfo?.codeHostType || ''
5050
};
5151
}),
52-
...defaultSelectedContexts.map(contextName => {
53-
const context = searchContexts.find(c => c.name === contextName);
52+
...defaultSelectedReposets.map(reposetName => {
53+
const reposet = searchContexts.find(c => c.name === reposetName);
5454
return {
55-
type: 'context' as const,
56-
value: contextName,
57-
name: contextName,
58-
repoCount: context?.repoNames.length || 0
55+
type: 'reposet' as const,
56+
value: reposetName,
57+
name: reposetName,
58+
repoCount: reposet?.repoNames.length || 0
5959
};
6060
})
6161
]);
@@ -67,7 +67,7 @@ export const ChatThreadPanel = ({
6767
}
6868

6969
try {
70-
const { inputMessage, selectedRepos, selectedContexts } = JSON.parse(setChatState) as SetChatStatePayload;
70+
const { inputMessage, selectedRepos, selectedReposets } = JSON.parse(setChatState) as SetChatStatePayload;
7171
setInputMessage(inputMessage);
7272
setSelectedItems([
7373
...selectedRepos.map(repoName => {
@@ -79,13 +79,13 @@ export const ChatThreadPanel = ({
7979
codeHostType: repoInfo?.codeHostType || ''
8080
};
8181
}),
82-
...selectedContexts.map(contextName => {
83-
const context = searchContexts.find(c => c.name === contextName);
82+
...selectedReposets.map(reposetName => {
83+
const reposet = searchContexts.find(c => c.name === reposetName);
8484
return {
85-
type: 'context' as const,
86-
value: contextName,
87-
name: contextName,
88-
repoCount: context?.repoNames.length || 0
85+
type: 'reposet' as const,
86+
value: reposetName,
87+
name: reposetName,
88+
repoCount: reposet?.repoNames.length || 0
8989
};
9090
})
9191
]);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { RepositoryQuery, SearchContextQuery } from "@/lib/types";
1010
import { useCallback, useState } from "react";
1111
import { Descendant } from "slate";
1212
import { useLocalStorage } from "usehooks-ts";
13-
import { ContextItem } from "@/features/chat/components/chatBox/contextSelector";
13+
import { SearchScopeItem } from "@/features/chat/components/chatBox/searchScopeSelector";
1414

1515
interface NewChatPanelProps {
1616
languageModels: LanguageModelInfo[];
@@ -25,7 +25,7 @@ export const NewChatPanel = ({
2525
searchContexts,
2626
order,
2727
}: NewChatPanelProps) => {
28-
const [selectedItems, setSelectedItems] = useLocalStorage<ContextItem[]>("selectedContextItems", [], { initializeWithValue: false });
28+
const [selectedItems, setSelectedItems] = useLocalStorage<SearchScopeItem[]>("selectedContextItems", [], { initializeWithValue: false });
2929
const { createNewChatThread, isLoading } = useCreateNewChatThread();
3030
const [isContextSelectorOpen, setIsContextSelectorOpen] = useState(false);
3131

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { RepositoryQuery, SearchContextQuery } from "@/lib/types";
99
import { useState } from "react";
1010
import { SearchModeSelector, SearchModeSelectorProps } from "./toolbar";
1111
import { useLocalStorage } from "usehooks-ts";
12-
import { ContextItem } from "@/features/chat/components/chatBox/contextSelector";
12+
import { SearchScopeItem } from "@/features/chat/components/chatBox/searchScopeSelector";
1313
import { DemoExamples } from "@/types";
1414
import { AskSourcebotDemoCards } from "./askSourcebotDemoCards";
1515

@@ -34,7 +34,7 @@ export const AgenticSearch = ({
3434
demoExamples,
3535
}: AgenticSearchProps) => {
3636
const { createNewChatThread, isLoading } = useCreateNewChatThread();
37-
const [selectedItems, setSelectedItems] = useLocalStorage<ContextItem[]>("selectedContextItems", [], { initializeWithValue: false });
37+
const [selectedItems, setSelectedItems] = useLocalStorage<SearchScopeItem[]>("selectedContextItems", [], { initializeWithValue: false });
3838
const [isContextSelectorOpen, setIsContextSelectorOpen] = useState(false);
3939

4040
return (
@@ -74,10 +74,6 @@ export const AgenticSearch = ({
7474
{demoExamples && (
7575
<AskSourcebotDemoCards
7676
demoExamples={demoExamples}
77-
selectedItems={selectedItems}
78-
setSelectedItems={setSelectedItems}
79-
searchContexts={searchContexts}
80-
repos={repos}
8177
/>
8278
)}
8379
</div >

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

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Search, LibraryBigIcon, Code, Info } from "lucide-react";
66
import { Badge } from "@/components/ui/badge";
77
import { Card } from "@/components/ui/card";
88
import { CardContent } from "@/components/ui/card";
9-
import { DemoExamples, DemoSearchExample, DemoSearchContext } from "@/types";
9+
import { DemoExamples, DemoSearchExample, DemoSearchScope } from "@/types";
1010
import { cn, getCodeHostIcon } from "@/lib/utils";
1111
import useCaptureEvent from "@/hooks/useCaptureEvent";
1212
import { SearchScopeInfoCard } from "@/components/searchScopeInfoCard";
@@ -19,7 +19,7 @@ export const AskSourcebotDemoCards = ({
1919
demoExamples,
2020
}: AskSourcebotDemoCardsProps) => {
2121
const captureEvent = useCaptureEvent();
22-
const [selectedFilterContext, setSelectedFilterContext] = useState<number | null>(null);
22+
const [selectedFilterSearchScope, setSelectedFilterSearchScope] = useState<number | null>(null);
2323

2424
const handleExampleClick = (example: DemoSearchExample) => {
2525
captureEvent('wa_demo_search_example_card_pressed', {
@@ -32,16 +32,16 @@ export const AskSourcebotDemoCards = ({
3232
}
3333
}
3434

35-
const getContextIcon = (context: DemoSearchContext, size: number = 20, isSelected: boolean = false) => {
35+
const getSearchScopeIcon = (searchScope: DemoSearchScope, size: number = 20, isSelected: boolean = false) => {
3636
const sizeClass = size === 12 ? "h-3 w-3" : "h-5 w-5";
3737
const colorClass = isSelected ? "text-primary-foreground" : "text-muted-foreground";
3838

39-
if (context.type === "set") {
39+
if (searchScope.type === "reposet") {
4040
return <LibraryBigIcon className={cn(sizeClass, colorClass)} />;
4141
}
4242

43-
if (context.codeHostType) {
44-
const codeHostIcon = getCodeHostIcon(context.codeHostType);
43+
if (searchScope.codeHostType) {
44+
const codeHostIcon = getCodeHostIcon(searchScope.codeHostType);
4545
if (codeHostIcon) {
4646
// When selected, icons need to match the inverted badge colors
4747
// In light mode selected: light icon on dark bg (invert)
@@ -53,7 +53,7 @@ export const AskSourcebotDemoCards = ({
5353
return (
5454
<Image
5555
src={codeHostIcon.src}
56-
alt={`${context.codeHostType} icon`}
56+
alt={`${searchScope.codeHostType} icon`}
5757
width={size}
5858
height={size}
5959
className={cn(sizeClass, selectedIconClass)}
@@ -92,7 +92,7 @@ export const AskSourcebotDemoCards = ({
9292
</div>
9393
</div>
9494

95-
{/* Search Context Filter */}
95+
{/* Search Scope Filter */}
9696
<div className="flex flex-wrap items-center justify-center gap-2 mb-6">
9797
<div className="flex items-center gap-2 mr-2">
9898
<div className="relative group">
@@ -102,42 +102,42 @@ export const AskSourcebotDemoCards = ({
102102
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-border"></div>
103103
</div>
104104
</div>
105-
<span className="text-sm font-medium text-muted-foreground">Search Context:</span>
105+
<span className="text-sm font-medium text-muted-foreground">Search Scope:</span>
106106
</div>
107107
<Badge
108-
variant={selectedFilterContext === null ? "default" : "secondary"}
109-
className={`cursor-pointer transition-all duration-200 hover:shadow-sm ${selectedFilterContext === null ? "bg-primary text-primary-foreground" : "hover:bg-secondary/80"
108+
variant={selectedFilterSearchScope === null ? "default" : "secondary"}
109+
className={`cursor-pointer transition-all duration-200 hover:shadow-sm ${selectedFilterSearchScope === null ? "bg-primary text-primary-foreground" : "hover:bg-secondary/80"
110110
}`}
111111
onClick={() => {
112-
setSelectedFilterContext(null);
112+
setSelectedFilterSearchScope(null);
113113
}}
114114
>
115115
All
116116
</Badge>
117-
{demoExamples.searchContexts.map((context) => (
117+
{demoExamples.searchScopes.map((searchScope) => (
118118
<Badge
119-
key={context.id}
120-
variant={selectedFilterContext === context.id ? "default" : "secondary"}
121-
className={`cursor-pointer transition-all duration-200 hover:shadow-sm flex items-center gap-1 ${selectedFilterContext === context.id ? "bg-primary text-primary-foreground" : "hover:bg-secondary/80"
119+
key={searchScope.id}
120+
variant={selectedFilterSearchScope === searchScope.id ? "default" : "secondary"}
121+
className={`cursor-pointer transition-all duration-200 hover:shadow-sm flex items-center gap-1 ${selectedFilterSearchScope === searchScope.id ? "bg-primary text-primary-foreground" : "hover:bg-secondary/80"
122122
}`}
123123
onClick={() => {
124-
setSelectedFilterContext(context.id);
124+
setSelectedFilterSearchScope(searchScope.id);
125125
}}
126126
>
127-
{getContextIcon(context, 12, selectedFilterContext === context.id)}
128-
{context.displayName}
127+
{getSearchScopeIcon(searchScope, 12, selectedFilterSearchScope === searchScope.id)}
128+
{searchScope.displayName}
129129
</Badge>
130130
))}
131131
</div>
132132

133133
<div className="flex flex-wrap justify-center gap-3">
134134
{demoExamples.searchExamples
135135
.filter((example) => {
136-
if (selectedFilterContext === null) return true;
137-
return example.searchContext.includes(selectedFilterContext);
136+
if (selectedFilterSearchScope === null) return true;
137+
return example.searchScopes.includes(selectedFilterSearchScope);
138138
})
139139
.map((example) => {
140-
const searchContexts = demoExamples.searchContexts.filter((context) => example.searchContext.includes(context.id))
140+
const searchScopes = demoExamples.searchScopes.filter((searchScope) => example.searchScopes.includes(searchScope.id))
141141
return (
142142
<Card
143143
key={example.url}
@@ -147,10 +147,10 @@ export const AskSourcebotDemoCards = ({
147147
<CardContent className="p-4">
148148
<div className="space-y-3">
149149
<div className="flex items-center justify-between">
150-
{searchContexts.map((context) => (
151-
<Badge key={context.value} variant="secondary" className="text-[10px] px-1.5 py-0.5 h-4 flex items-center gap-1">
152-
{getContextIcon(context, 12)}
153-
{context.displayName}
150+
{searchScopes.map((searchScope) => (
151+
<Badge key={searchScope.value} variant="secondary" className="text-[10px] px-1.5 py-0.5 h-4 flex items-center gap-1">
152+
{getSearchScopeIcon(searchScope, 12)}
153+
{searchScope.displayName}
154154
</Badge>
155155
))}
156156
</div>

packages/web/src/app/api/(server)/chat/route.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ export async function POST(req: Request) {
6464
return serviceErrorResponse(schemaValidationError(parsed.error));
6565
}
6666

67-
const { messages, id, selectedRepos, selectedContexts, languageModelId } = parsed.data;
67+
const { messages, id, selectedRepos, selectedReposets, languageModelId } = parsed.data;
6868
const response = await chatHandler({
6969
messages,
7070
id,
7171
selectedRepos,
72-
selectedContexts,
72+
selectedReposets,
7373
languageModelId,
7474
}, domain);
7575

@@ -94,11 +94,11 @@ interface ChatHandlerProps {
9494
messages: SBChatMessage[];
9595
id: string;
9696
selectedRepos: string[];
97-
selectedContexts?: string[];
97+
selectedReposets?: string[];
9898
languageModelId: string;
9999
}
100100

101-
const chatHandler = ({ messages, id, selectedRepos, selectedContexts, languageModelId }: ChatHandlerProps, domain: string) => sew(async () =>
101+
const chatHandler = ({ messages, id, selectedRepos, selectedReposets, languageModelId }: ChatHandlerProps, domain: string) => sew(async () =>
102102
withAuth((userId) =>
103103
withOrgMembership(userId, domain, async ({ org }) => {
104104
const chat = await prisma.chat.findUnique({
@@ -190,23 +190,23 @@ const chatHandler = ({ messages, id, selectedRepos, selectedContexts, languageMo
190190

191191
// Expand search contexts to repos
192192
let expandedRepos = [...selectedRepos];
193-
if (selectedContexts && selectedContexts.length > 0) {
194-
const searchContexts = await prisma.searchContext.findMany({
193+
if (selectedReposets && selectedReposets.length > 0) {
194+
const searchReposets = await prisma.searchContext.findMany({
195195
where: {
196196
orgId: org.id,
197-
name: { in: selectedContexts }
197+
name: { in: selectedReposets }
198198
},
199199
include: {
200200
repos: true
201201
}
202202
});
203203

204-
const contextRepos = searchContexts.flatMap(context =>
205-
context.repos.map(repo => repo.name)
204+
const reposetRepos = searchReposets.flatMap(reposet =>
205+
reposet.repos.map(repo => repo.name)
206206
);
207207

208208
// Combine and deduplicate repos
209-
expandedRepos = Array.from(new Set([...selectedRepos, ...contextRepos]));
209+
expandedRepos = Array.from(new Set([...selectedRepos, ...reposetRepos]));
210210
}
211211

212212
const researchStream = await createAgentStream({
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { AtSignIcon } from "lucide-react";
2+
3+
export const AtMentionInfoCard = () => {
4+
return (
5+
<div className="bg-popover border border-border rounded-lg shadow-lg p-4 w-80 max-w-[90vw]">
6+
<div className="flex items-center gap-2 mb-3 pb-2 border-b border-border/50">
7+
<AtSignIcon className="h-4 w-4 text-primary" />
8+
<h4 className="text-sm font-semibold text-popover-foreground">Mention</h4>
9+
</div>
10+
<div className="text-sm text-popover-foreground leading-relaxed">
11+
When asking Sourcebot a question, you can @ mention files to include them in the context of the search.
12+
</div>
13+
</div>
14+
);
15+
};

packages/web/src/components/searchScopeInfoCard.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import Image from "next/image";
2-
import { LibraryBigIcon, Code, Layers } from "lucide-react";
2+
import { LibraryBigIcon, Code, ScanSearchIcon } from "lucide-react";
33
import { cn, getCodeHostIcon } from "@/lib/utils";
44

55
export const SearchScopeInfoCard = () => {
66
return (
77
<div className="bg-popover border border-border rounded-lg shadow-lg p-4 w-80 max-w-[90vw]">
88
<div className="flex items-center gap-2 mb-3 pb-2 border-b border-border/50">
9-
<Layers className="h-4 w-4 text-primary" />
10-
<h4 className="text-sm font-semibold text-popover-foreground">Search Context</h4>
9+
<ScanSearchIcon className="h-4 w-4 text-primary" />
10+
<h4 className="text-sm font-semibold text-popover-foreground">Search Scope</h4>
1111
</div>
1212
<div className="text-sm text-popover-foreground leading-relaxed">
13-
When asking Sourcebot a question, you can select one or more search contexts to constrain its scope. There
14-
are two different types of search contexts:
13+
When asking Sourcebot a question, you can select one or more scopes to constrain the search.
14+
There are two different types of search scopes:
1515
<div className="mt-3 space-y-2">
1616
<div className="flex items-center gap-2">
1717
{(() => {
@@ -32,7 +32,7 @@ export const SearchScopeInfoCard = () => {
3232
</div>
3333
<div className="flex items-center gap-2">
3434
<LibraryBigIcon className="h-4 w-4 text-muted-foreground flex-shrink-0" />
35-
<span><strong>Set</strong>: A set of repositories, indicated by the library icon.</span>
35+
<span><strong>Reposet</strong>: A set of repositories, indicated by the library icon.</span>
3636
</div>
3737
</div>
3838
</div>

0 commit comments

Comments
 (0)