mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-08 05:39:13 +00:00
Merge pull request #1014 from khoj-ai/features/improve-agent-management
- Add support for seeing all steps of the agent modification flow via tabs at the top of the modal - Separate knowledge base & tool selection into two separate parts
This commit is contained in:
@@ -91,6 +91,8 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover
|
|||||||
import ShareLink from "@/app/components/shareLink/shareLink";
|
import ShareLink from "@/app/components/shareLink/shareLink";
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
|
|
||||||
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
|
||||||
export interface AgentData {
|
export interface AgentData {
|
||||||
slug: string;
|
slug: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -427,7 +429,9 @@ export function AgentCard(props: AgentCardProps) {
|
|||||||
</div>
|
</div>
|
||||||
{props.editCard ? (
|
{props.editCard ? (
|
||||||
<DialogContent
|
<DialogContent
|
||||||
className={"lg:max-w-screen-lg overflow-y-scroll max-h-screen"}
|
className={
|
||||||
|
"lg:max-w-screen-lg py-4 overflow-y-scroll h-4/6 rounded-lg flex flex-col"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
Edit <b>{props.data.name}</b>
|
Edit <b>{props.data.name}</b>
|
||||||
@@ -534,12 +538,13 @@ export function AgentModificationForm(props: AgentModificationFormProps) {
|
|||||||
{ name: "persona", label: "Personality" },
|
{ name: "persona", label: "Personality" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const advancedFields = [
|
const toolsFields = [
|
||||||
{ name: "files", label: "Knowledge Base" },
|
|
||||||
{ name: "input_tools", label: "Input Tools" },
|
{ name: "input_tools", label: "Input Tools" },
|
||||||
{ name: "output_modes", label: "Output Modes" },
|
{ name: "output_modes", label: "Output Modes" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const knowledgeBaseFields = [{ name: "files", label: "Knowledge Base" }];
|
||||||
|
|
||||||
const customizationFields = [
|
const customizationFields = [
|
||||||
{ name: "color", label: "Color" },
|
{ name: "color", label: "Color" },
|
||||||
{ name: "icon", label: "Icon" },
|
{ name: "icon", label: "Icon" },
|
||||||
@@ -548,9 +553,10 @@ export function AgentModificationForm(props: AgentModificationFormProps) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const formGroups = [
|
const formGroups = [
|
||||||
{ fields: basicFields, label: "Basic Settings" },
|
{ fields: basicFields, label: "Basic Settings", tabName: "basic" },
|
||||||
{ fields: customizationFields, label: "Customization & Access" },
|
{ fields: customizationFields, label: "Customization & Access", tabName: "customize" },
|
||||||
{ fields: advancedFields, label: "Advanced Settings" },
|
{ fields: knowledgeBaseFields, label: "Knowledge Base", tabName: "knowledge" },
|
||||||
|
{ fields: toolsFields, label: "Tools Settings", tabName: "tools" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -749,7 +755,7 @@ export function AgentModificationForm(props: AgentModificationFormProps) {
|
|||||||
control={props.form.control}
|
control={props.form.control}
|
||||||
name="chat_model"
|
name="chat_model"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="space-y-1 grid gap-2">
|
<FormItem className="my-3 grid gap-2">
|
||||||
<FormLabel>Chat Model</FormLabel>
|
<FormLabel>Chat Model</FormLabel>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
{!props.isSubscribed ? (
|
{!props.isSubscribed ? (
|
||||||
@@ -796,7 +802,7 @@ export function AgentModificationForm(props: AgentModificationFormProps) {
|
|||||||
control={props.form.control}
|
control={props.form.control}
|
||||||
name="privacy_level"
|
name="privacy_level"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="space-y-1 grid gap-2">
|
<FormItem className="my-3 grid gap-2">
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
<div>Privacy Level</div>
|
<div>Privacy Level</div>
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
@@ -1080,7 +1086,7 @@ export function AgentModificationForm(props: AgentModificationFormProps) {
|
|||||||
control={props.form.control}
|
control={props.form.control}
|
||||||
name="input_tools"
|
name="input_tools"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex flex-col gap-2">
|
<FormItem className="flex flex-col gap-2 my-2">
|
||||||
<FormLabel>Restrict Input Tools</FormLabel>
|
<FormLabel>Restrict Input Tools</FormLabel>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
Which knowledge retrieval tools should this agent be limited to?
|
Which knowledge retrieval tools should this agent be limited to?
|
||||||
@@ -1166,7 +1172,7 @@ export function AgentModificationForm(props: AgentModificationFormProps) {
|
|||||||
control={props.form.control}
|
control={props.form.control}
|
||||||
name="output_modes"
|
name="output_modes"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem className="flex flex-col gap-2">
|
<FormItem className="flex flex-col gap-2 my-2">
|
||||||
<FormLabel>Restrict Output Modes</FormLabel>
|
<FormLabel>Restrict Output Modes</FormLabel>
|
||||||
<FormDescription>
|
<FormDescription>
|
||||||
Which output modes should this agent be limited to?
|
Which output modes should this agent be limited to?
|
||||||
@@ -1252,10 +1258,32 @@ export function AgentModificationForm(props: AgentModificationFormProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...props.form}>
|
<Form {...props.form}>
|
||||||
<form onSubmit={props.form.handleSubmit(handleSubmit)} className="space-y-6">
|
<form
|
||||||
<div className="space-y-6">{formGroups[currentStep].label}</div>
|
onSubmit={props.form.handleSubmit(handleSubmit)}
|
||||||
{currentStep < formGroups.length &&
|
className="space-y-6 h-full flex flex-col justify-between"
|
||||||
formGroups[currentStep].fields.map((field) => renderFormField(field.name))}
|
>
|
||||||
|
<Tabs defaultValue="basic" value={formGroups[currentStep].tabName}>
|
||||||
|
<TabsList className="grid grid-cols-2 md:grid-cols-4 gap-2 h-fit">
|
||||||
|
{formGroups.map((group) => (
|
||||||
|
<TabsTrigger
|
||||||
|
key={group.tabName}
|
||||||
|
value={group.tabName}
|
||||||
|
onClick={() =>
|
||||||
|
setCurrentStep(
|
||||||
|
formGroups.findIndex((g) => g.tabName === group.tabName),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{group.label}
|
||||||
|
</TabsTrigger>
|
||||||
|
))}
|
||||||
|
</TabsList>
|
||||||
|
{formGroups.map((group) => (
|
||||||
|
<TabsContent key={group.tabName} value={group.tabName}>
|
||||||
|
{group.fields.map((field) => renderFormField(field.name))}
|
||||||
|
</TabsContent>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
<div className="flex justify-between mt-4">
|
<div className="flex justify-between mt-4">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
55
src/interface/web/components/ui/tabs.tsx
Normal file
55
src/interface/web/components/ui/tabs.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const Tabs = TabsPrimitive.Root;
|
||||||
|
|
||||||
|
const TabsList = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.List>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<TabsPrimitive.List
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
||||||
|
|
||||||
|
const TabsTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<TabsPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
||||||
|
|
||||||
|
const TabsContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof TabsPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<TabsPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
"@radix-ui/react-select": "^2.1.1",
|
"@radix-ui/react-select": "^2.1.1",
|
||||||
"@radix-ui/react-separator": "^1.1.1",
|
"@radix-ui/react-separator": "^1.1.1",
|
||||||
"@radix-ui/react-slot": "^1.1.1",
|
"@radix-ui/react-slot": "^1.1.1",
|
||||||
|
"@radix-ui/react-tabs": "^1.1.2",
|
||||||
"@radix-ui/react-toast": "^1.2.1",
|
"@radix-ui/react-toast": "^1.2.1",
|
||||||
"@radix-ui/react-toggle": "^1.1.0",
|
"@radix-ui/react-toggle": "^1.1.0",
|
||||||
"@radix-ui/react-tooltip": "^1.1.6",
|
"@radix-ui/react-tooltip": "^1.1.6",
|
||||||
|
|||||||
@@ -914,7 +914,7 @@
|
|||||||
"@radix-ui/react-use-previous" "1.1.0"
|
"@radix-ui/react-use-previous" "1.1.0"
|
||||||
"@radix-ui/react-use-size" "1.1.0"
|
"@radix-ui/react-use-size" "1.1.0"
|
||||||
|
|
||||||
"@radix-ui/react-tabs@^1.1.1":
|
"@radix-ui/react-tabs@^1.1.1", "@radix-ui/react-tabs@^1.1.2":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz#a72da059593cba30fccb30a226d63af686b32854"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz#a72da059593cba30fccb30a226d63af686b32854"
|
||||||
integrity sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==
|
integrity sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==
|
||||||
|
|||||||
Reference in New Issue
Block a user