Merge branch 'master' of github.com:khoj-ai/khoj into features/add-a-knowledge-base-page

This commit is contained in:
sabaimran
2025-01-13 15:07:59 -08:00
5 changed files with 104 additions and 92 deletions

View File

@@ -1,4 +1,4 @@
name: build and deploy github pages for documentation name: deploy documentation
on: on:
push: push:
branches: branches:

View File

@@ -14,14 +14,14 @@ LM Studio can expose an [OpenAI API compatible server](https://lmstudio.ai/docs/
## Setup ## Setup
1. Install [LM Studio](https://lmstudio.ai/) and download your preferred Chat Model 1. Install [LM Studio](https://lmstudio.ai/) and download your preferred Chat Model
2. Go to the Server Tab on LM Studio, Select your preferred Chat Model and Click the green Start Server button 2. Go to the Server Tab on LM Studio, Select your preferred Chat Model and Click the green Start Server button
3. Create a new [OpenAI Processor Conversation Config](http://localhost:42110/server/admin/database/openaiprocessorconversationconfig/add) on your Khoj admin panel 3. Create a new [Add ai model api](http://localhost:42110/server/admin/database/aimodelapi/add/) on your Khoj admin panel
- Name: `proxy-name` - Name: `proxy-name`
- Api Key: `any string` - Api Key: `any string`
- Api Base Url: `http://localhost:1234/v1/` (default for LMStudio) - Api Base Url: `http://localhost:1234/v1/` (default for LMStudio)
4. Create a new [Chat Model](http://localhost:42110/server/admin/database/chatmodel/add) on your Khoj admin panel. 4. Create a new [Chat Model](http://localhost:42110/server/admin/database/chatmodel/add) on your Khoj admin panel.
- Name: `llama3.1` (replace with the name of your local model) - Name: `llama3.1` (replace with the name of your local model)
- Model Type: `Openai` - Model Type: `Openai`
- Openai Config: `<the proxy config you created in step 3>` - Ai model api: `<the Ai model api you created in step 3>`
- Max prompt size: `20000` (replace with the max prompt size of your model) - Max prompt size: `20000` (replace with the max prompt size of your model)
- Tokenizer: *Do not set for OpenAI, mistral, llama3 based models* - Tokenizer: *Do not set for OpenAI, mistral, llama3 based models*
5. Go to [your config](http://localhost:42110/settings) and select the model you just created in the chat model dropdown. 5. Go to [your config](http://localhost:42110/settings) and select the model you just created in the chat model dropdown.

View File

@@ -52,6 +52,8 @@ import {
Waveform, Waveform,
MagnifyingGlass, MagnifyingGlass,
Brain, Brain,
EyeSlash,
Eye,
} from "@phosphor-icons/react"; } from "@phosphor-icons/react";
import Loading from "../components/loading/loading"; import Loading from "../components/loading/loading";
@@ -182,6 +184,101 @@ const useApiKeys = () => {
}; };
}; };
function ApiKeyCard() {
const { apiKeys, generateAPIKey, copyAPIKey, deleteAPIKey } = useApiKeys();
const [visibleApiKeys, setVisibleApiKeys] = useState<Set<string>>(new Set());
const { toast } = useToast();
return (
<Card className="grid grid-flow-column border border-gray-300 shadow-md rounded-lg dark:bg-muted dark:border-none border-opacity-50 lg:w-2/3">
<CardHeader className="text-xl grid grid-flow-col grid-cols-[1fr_auto] pb-0">
<span className="flex flex-wrap">
<Key className="h-7 w-7 mr-2" />
API Keys
</span>
<Button variant="secondary" className="!mt-0" onClick={generateAPIKey}>
<Plus weight="bold" className="h-5 w-5 mr-2" />
Generate Key
</Button>
</CardHeader>
<CardContent className="overflow-hidden grid gap-6">
<p className="text-md text-gray-400">
Access Khoj from the{" "}
<a href="https://docs.khoj.dev/clients/desktop" target="_blank">
Desktop
</a>
, <a href="https://docs.khoj.dev/clients/obsidian">Obsidian</a>,{" "}
<a href="https://docs.khoj.dev/clients/emacs">Emacs</a> apps and more.
</p>
<Table>
<TableBody>
{apiKeys.map((key) => (
<TableRow key={key.token}>
<TableCell className="pl-0 py-3">{key.name}</TableCell>
<TableCell className="grid grid-flow-col grid-cols-[1fr_auto] bg-secondary dark:bg-background rounded-xl p-3 m-1">
<span className="font-mono text-left w-[50px] md:w-[400px]">
{visibleApiKeys.has(key.token)
? key.token
: `${key.token.slice(0, 6)}...${key.token.slice(-4)}`}
</span>
<div className="grid grid-flow-col">
{visibleApiKeys.has(key.token) ? (
<EyeSlash
weight="bold"
className="h-4 w-4 mr-2 hover:bg-primary/40"
onClick={() =>
setVisibleApiKeys((prev) => {
const next = new Set(prev);
next.delete(key.token);
return next;
})
}
/>
) : (
<Eye
weight="bold"
className="h-4 w-4 mr-2 hover:bg-primary/40"
onClick={() =>
setVisibleApiKeys(
new Set([...visibleApiKeys, key.token]),
)
}
/>
)}
<Copy
weight="bold"
className="h-4 w-4 mr-2 hover:bg-primary/40"
onClick={() => {
toast({
title: `🔑 Copied API Key: ${key.name}`,
description: `Set this API key in the Khoj apps you want to connect to this Khoj account`,
});
copyAPIKey(key.token);
}}
/>
<Trash
weight="bold"
className="h-4 w-4 mr-2 md:ml-4 text-red-400 hover:bg-primary/40"
onClick={() => {
toast({
title: `🔑 Deleted API Key: ${key.name}`,
description: `Apps using this API key will no longer connect to this Khoj account`,
});
deleteAPIKey(key.token);
}}
/>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
<CardFooter className="flex flex-wrap gap-4" />
</Card>
);
}
enum PhoneNumberValidationState { enum PhoneNumberValidationState {
Setup = "setup", Setup = "setup",
SendOTP = "otp", SendOTP = "otp",
@@ -190,7 +287,6 @@ enum PhoneNumberValidationState {
} }
export default function SettingsView() { export default function SettingsView() {
const { apiKeys, generateAPIKey, copyAPIKey, deleteAPIKey } = useApiKeys();
const { userConfig: initialUserConfig } = useUserConfig(true); const { userConfig: initialUserConfig } = useUserConfig(true);
const [userConfig, setUserConfig] = useState<UserConfig | null>(null); const [userConfig, setUserConfig] = useState<UserConfig | null>(null);
const [name, setName] = useState<string | undefined>(undefined); const [name, setName] = useState<string | undefined>(undefined);
@@ -206,7 +302,7 @@ export default function SettingsView() {
const title = "Settings"; const title = "Settings";
const cardClassName = const cardClassName =
"w-full lg:w-5/12 grid grid-flow-column border border-gray-300 shadow-md rounded-lg border dark:border-none dark:bg-muted border-opacity-50"; "w-full lg:w-5/12 grid grid-flow-column border border-gray-300 shadow-md rounded-lg border dark:border-none border-opacity-50 dark:bg-muted";
useEffect(() => { useEffect(() => {
setUserConfig(initialUserConfig); setUserConfig(initialUserConfig);
@@ -1018,92 +1114,7 @@ export default function SettingsView() {
Clients Clients
</div> </div>
<div className="cards flex flex-col flex-wrap gap-8"> <div className="cards flex flex-col flex-wrap gap-8">
{!userConfig.anonymous_mode && ( {!userConfig.anonymous_mode && <ApiKeyCard />}
<Card className="grid grid-flow-column border border-gray-300 shadow-md rounded-lg dark:bg-muted dark:border-none border-opacity-50 lg:w-2/3">
<CardHeader className="text-xl grid grid-flow-col grid-cols-[1fr_auto] pb-0">
<span className="flex flex-wrap">
<Key className="h-7 w-7 mr-2" />
API Keys
</span>
<Button
variant="secondary"
className="!mt-0"
onClick={generateAPIKey}
>
<Plus
weight="bold"
className="h-5 w-5 mr-2"
/>
Generate Key
</Button>
</CardHeader>
<CardContent className="overflow-hidden grid gap-6">
<p className="text-md text-gray-400">
Access Khoj from the{" "}
<a
href="https://docs.khoj.dev/clients/Desktop"
target="_blank"
>
Desktop
</a>
,{" "}
<a href="https://docs.khoj.dev/clients/Obsidian">
Obsidian
</a>
,{" "}
<a href="https://docs.khoj.dev/clients/Emacs">
Emacs
</a>{" "}
apps and more.
</p>
<Table>
<TableBody>
{apiKeys.map((key) => (
<TableRow key={key.token}>
<TableCell className="pl-0 py-3">
{key.name}
</TableCell>
<TableCell className="grid grid-flow-col grid-cols-[1fr_auto] bg-secondary rounded-xl p-3 m-1">
<span>
{`${key.token.slice(0, 6)}...${key.token.slice(-4)}`}
</span>
<div className="grid grid-flow-col">
<Copy
weight="bold"
className="h-4 w-4 mr-2 hover:bg-primary/40"
onClick={() => {
toast({
title: `🔑 Copied API Key: ${key.name}`,
description: `Set this API key in the Khoj apps you want to connect to this Khoj account`,
});
copyAPIKey(
key.token,
);
}}
/>
<Trash
weight="bold"
className="h-4 w-4 mr-2 md:ml-4 text-red-400 hover:bg-primary/40"
onClick={() => {
toast({
title: `🔑 Deleted API Key: ${key.name}`,
description: `Apps using this API key will no longer connect to this Khoj account`,
});
deleteAPIKey(
key.token,
);
}}
/>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
<CardFooter className="flex flex-wrap gap-4"></CardFooter>
</Card>
)}
<Card className={`${cardClassName} lg:w-2/3`}> <Card className={`${cardClassName} lg:w-2/3`}>
<CardHeader className="text-xl flex flex-row"> <CardHeader className="text-xl flex flex-row">
<WhatsappLogo className="h-7 w-7 mr-2" /> <WhatsappLogo className="h-7 w-7 mr-2" />

View File

@@ -23,6 +23,7 @@ div.phoneInput input {
width: 100%; width: 100%;
padding: 0.5rem; padding: 0.5rem;
border: 1px solid hsla(var(--border)); border: 1px solid hsla(var(--border));
background-color: hsla(var(--background));
border-radius: 0.25rem; border-radius: 0.25rem;
} }

View File

@@ -267,7 +267,7 @@ def initialization(interactive: bool = True):
) )
# Remove models that are no longer available # Remove models that are no longer available
existing_models.exclude(chat_model__in=available_models).delete() existing_models.exclude(name__in=available_models).delete()
except Exception as e: except Exception as e:
logger.warning(f"Failed to update models for {config.name}: {str(e)}") logger.warning(f"Failed to update models for {config.name}: {str(e)}")