-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
136 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { | ||
Dialog, | ||
DialogContent, | ||
DialogHeader, | ||
DialogTitle, | ||
DialogDescription, | ||
DialogFooter, | ||
} from '@/components/ui/dialog'; | ||
import OnBoarding from './onboarding'; | ||
import { Button } from '@/components/ui/button'; | ||
import { useMustOnboard } from './use-must-onboard'; | ||
import { useEffect, useState } from 'react'; | ||
|
||
export function OnBoardingModal() { | ||
const { value: mustOnboard } = useMustOnboard(); | ||
const [openOnboarding, setOpenOnboarding] = useState(false); | ||
|
||
useEffect(() => { | ||
if (mustOnboard) { | ||
setOpenOnboarding(mustOnboard); | ||
} | ||
}, [mustOnboard]); | ||
|
||
const onOpenChange = (open: boolean) => { | ||
setOpenOnboarding(open); | ||
}; | ||
|
||
return ( | ||
<Dialog open={openOnboarding}> | ||
<DialogContent> | ||
<DialogHeader> | ||
<DialogTitle>Onboarding</DialogTitle> | ||
<DialogDescription> | ||
At least one API Key of one of the providers must be set. | ||
</DialogDescription> | ||
</DialogHeader> | ||
<div className='max-w-full'> | ||
<OnBoarding /> | ||
</div> | ||
<DialogFooter> | ||
<Button type="submit" disabled={mustOnboard} onClick={() => onOpenChange(false)}>Done</Button> | ||
</DialogFooter> | ||
</DialogContent> | ||
</Dialog> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import ApiKeysSection from '../settings/_components/api-keys.section'; | ||
|
||
export default function OnBoarding() { | ||
return ( | ||
<div> | ||
<ApiKeysSection /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { isAtLeastOneLlmApiKeySet } from '@/lib/api/llm'; | ||
import { useAsyncRetry, useInterval } from 'react-use'; | ||
|
||
interface Props { | ||
refreshInterval?: number; | ||
} | ||
|
||
export function useMustOnboard({ refreshInterval = 1000 }: Props = {}) { | ||
|
||
const state = useAsyncRetry(async () => { | ||
const response = await isAtLeastOneLlmApiKeySet(); | ||
return !response; | ||
}, []); | ||
|
||
useInterval( | ||
() => { | ||
state.retry(); | ||
}, | ||
state.value === true ? refreshInterval : null | ||
); | ||
|
||
return state; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,14 @@ | ||
import NewThreadPrompt from './_components/new-thread-prompt'; | ||
import RecentThreads from './_components/recent-threads'; | ||
import { OnBoardingModal } from './_onboarding/modal'; | ||
|
||
|
||
export default function Home() { | ||
return ( | ||
<main className="h-full flex flex-col"> | ||
<RecentThreads /> | ||
<NewThreadPrompt /> | ||
<OnBoardingModal /> | ||
</main> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,12 @@ | ||
import { Section } from '@/components/section'; | ||
import { ConfigurationKvEditor } from './configuration-kv-editor'; | ||
import { LLM_API_KEYS_KEYS } from '@/app.config'; | ||
|
||
|
||
export default function ApiKeysSection() { | ||
return ( | ||
<Section id='api-keys' title="API Keys"> | ||
<ConfigurationKvEditor kv_key="OPENAI_API_KEY" isSecret /> | ||
<ConfigurationKvEditor kv_key="ANTHROPIC_API_KEY" isSecret /> | ||
<ConfigurationKvEditor kv_key="SERPER_API_KEY" isSecret /> | ||
{ LLM_API_KEYS_KEYS.map((key) => <ConfigurationKvEditor key={key} kv_key={key} isSecret />) } | ||
</Section> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { when } from 'jest-when'; | ||
import { isAtLeastOneLlmApiKeySet } from './llm'; | ||
import { findConfiguration } from './tauri'; | ||
import { LLM_API_KEYS_KEYS } from '@/app.config'; | ||
|
||
vi.mock('./tauri'); | ||
describe('isAtLeastOneLlmApiKeySet', () => { | ||
|
||
it('should return false when each api key value is empty', async () => { | ||
LLM_API_KEYS_KEYS.forEach((key) => { | ||
when(findConfiguration).mockResolvedValue({ | ||
key: key, | ||
value: '', | ||
}); | ||
}); | ||
|
||
const result = await isAtLeastOneLlmApiKeySet(); | ||
|
||
expect(result).toBe(false); | ||
}); | ||
|
||
it('should return true when one of api key value is not empty', async () => { | ||
when(findConfiguration).mockResolvedValue({ | ||
key: '', | ||
value: '', | ||
}); | ||
|
||
when(findConfiguration).calledWith(LLM_API_KEYS_KEYS[0]).mockResolvedValue({ | ||
key: '', | ||
value: 'some', | ||
}); | ||
|
||
const result = await isAtLeastOneLlmApiKeySet(); | ||
|
||
expect(result).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { LLM_API_KEYS_KEYS } from '@/app.config'; | ||
import { findConfiguration } from './tauri'; | ||
|
||
export async function isAtLeastOneLlmApiKeySet(): Promise<boolean> { | ||
for (const key of LLM_API_KEYS_KEYS) { | ||
const config = await findConfiguration(key); | ||
if (config?.value) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters