Merge pull request #329 from abi/add-anthropic-key
Add field for Anthropic API key in settings
This commit is contained in:
commit
22e45cc566
@ -120,6 +120,17 @@ async def stream_code(websocket: WebSocket):
|
||||
)
|
||||
return
|
||||
|
||||
# Get the Anthropic API key from the request. Fall back to environment variable if not provided.
|
||||
# If neither is provided, we throw an error later only if Claude is used.
|
||||
anthropic_api_key = None
|
||||
if "anthropicApiKey" in params and params["anthropicApiKey"]:
|
||||
anthropic_api_key = params["anthropicApiKey"]
|
||||
print("Using Anthropic API key from client-side settings dialog")
|
||||
else:
|
||||
anthropic_api_key = ANTHROPIC_API_KEY
|
||||
if anthropic_api_key:
|
||||
print("Using Anthropic API key from environment variable")
|
||||
|
||||
# Get the OpenAI Base URL from the request. Fall back to environment variable if not provided.
|
||||
openai_base_url = None
|
||||
# Disable user-specified OpenAI Base URL in prod
|
||||
@ -219,31 +230,31 @@ async def stream_code(websocket: WebSocket):
|
||||
else:
|
||||
try:
|
||||
if validated_input_mode == "video":
|
||||
if not ANTHROPIC_API_KEY:
|
||||
if not anthropic_api_key:
|
||||
await throw_error(
|
||||
"Video only works with Anthropic models. No Anthropic API key found. Please add the environment variable ANTHROPIC_API_KEY to backend/.env"
|
||||
"Video only works with Anthropic models. No Anthropic API key found. Please add the environment variable ANTHROPIC_API_KEY to backend/.env or in the settings dialog"
|
||||
)
|
||||
raise Exception("No Anthropic key")
|
||||
|
||||
completion = await stream_claude_response_native(
|
||||
system_prompt=VIDEO_PROMPT,
|
||||
messages=prompt_messages, # type: ignore
|
||||
api_key=ANTHROPIC_API_KEY,
|
||||
api_key=anthropic_api_key,
|
||||
callback=lambda x: process_chunk(x),
|
||||
model=Llm.CLAUDE_3_OPUS,
|
||||
include_thinking=True,
|
||||
)
|
||||
exact_llm_version = Llm.CLAUDE_3_OPUS
|
||||
elif code_generation_model == Llm.CLAUDE_3_SONNET:
|
||||
if not ANTHROPIC_API_KEY:
|
||||
if not anthropic_api_key:
|
||||
await throw_error(
|
||||
"No Anthropic API key found. Please add the environment variable ANTHROPIC_API_KEY to backend/.env"
|
||||
"No Anthropic API key found. Please add the environment variable ANTHROPIC_API_KEY to backend/.env or in the settings dialog"
|
||||
)
|
||||
raise Exception("No Anthropic key")
|
||||
|
||||
completion = await stream_claude_response(
|
||||
prompt_messages, # type: ignore
|
||||
api_key=ANTHROPIC_API_KEY,
|
||||
api_key=anthropic_api_key,
|
||||
callback=lambda x: process_chunk(x),
|
||||
)
|
||||
exact_llm_version = code_generation_model
|
||||
|
||||
@ -46,7 +46,8 @@
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"thememirror": "^2.0.1",
|
||||
"vite-plugin-checker": "^0.6.2",
|
||||
"webm-duration-fix": "^1.0.4"
|
||||
"webm-duration-fix": "^1.0.4",
|
||||
"zustand": "^4.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.12",
|
||||
|
||||
@ -59,6 +59,7 @@ function App() {
|
||||
{
|
||||
openAiApiKey: null,
|
||||
openAiBaseURL: null,
|
||||
anthropicApiKey: null,
|
||||
screenshotOneApiKey: null,
|
||||
isImageGenerationEnabled: true,
|
||||
editorTheme: EditorTheme.COBALT,
|
||||
@ -378,7 +379,10 @@ function App() {
|
||||
/>
|
||||
)}
|
||||
<div className="lg:fixed lg:inset-y-0 lg:z-40 lg:flex lg:w-96 lg:flex-col">
|
||||
<div className="flex grow flex-col gap-y-2 overflow-y-auto border-r border-gray-200 bg-white px-6 dark:bg-zinc-950 dark:text-white">
|
||||
<div
|
||||
className="flex grow flex-col gap-y-2 overflow-y-auto border-r
|
||||
border-gray-200 bg-white px-6 dark:bg-zinc-950 dark:text-white"
|
||||
>
|
||||
<div className="flex items-center justify-between mt-10 mb-2">
|
||||
<h1 className="text-2xl ">Screenshot to Code</h1>
|
||||
<SettingsDialog settings={settings} setSettings={setSettings} />
|
||||
|
||||
@ -49,7 +49,7 @@ function SettingsDialog({ settings, setSettings }: Props) {
|
||||
<div className="flex items-center space-x-2">
|
||||
<Label htmlFor="image-generation">
|
||||
<div>DALL-E Placeholder Image Generation</div>
|
||||
<div className="font-light mt-2">
|
||||
<div className="font-light mt-2 text-xs">
|
||||
More fun with it but if you want to save money, turn it off.
|
||||
</div>
|
||||
</Label>
|
||||
@ -64,10 +64,11 @@ function SettingsDialog({ settings, setSettings }: Props) {
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-4">
|
||||
<div className="flex flex-col space-y-6">
|
||||
<div>
|
||||
<Label htmlFor="openai-api-key">
|
||||
<div>OpenAI API key</div>
|
||||
<div className="font-light mt-2 leading-relaxed">
|
||||
<div className="font-light mt-1 mb-2 text-xs leading-relaxed">
|
||||
Only stored in your browser. Never stored on servers. Overrides
|
||||
your .env config.
|
||||
</div>
|
||||
@ -84,9 +85,10 @@ function SettingsDialog({ settings, setSettings }: Props) {
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{!IS_RUNNING_ON_CLOUD && (
|
||||
<>
|
||||
<div>
|
||||
<Label htmlFor="openai-api-key">
|
||||
<div>OpenAI Base URL (optional)</div>
|
||||
<div className="font-light mt-2 leading-relaxed">
|
||||
@ -105,9 +107,31 @@ function SettingsDialog({ settings, setSettings }: Props) {
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<Label htmlFor="anthropic-api-key">
|
||||
<div>Anthropic API key</div>
|
||||
<div className="font-light mt-1 text-xs leading-relaxed">
|
||||
Only stored in your browser. Never stored on servers. Overrides
|
||||
your .env config.
|
||||
</div>
|
||||
</Label>
|
||||
|
||||
<Input
|
||||
id="anthropic-api-key"
|
||||
placeholder="Anthropic API key"
|
||||
value={settings.anthropicApiKey || ""}
|
||||
onChange={(e) =>
|
||||
setSettings((s) => ({
|
||||
...s,
|
||||
anthropicApiKey: e.target.value,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Accordion type="single" collapsible className="w-full">
|
||||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>Screenshot by URL Config</AccordionTrigger>
|
||||
|
||||
10
frontend/src/store/app-store.ts
Normal file
10
frontend/src/store/app-store.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { create } from "zustand";
|
||||
|
||||
// Store for app-wide state
|
||||
interface AppStore {
|
||||
inputMode: "image" | "video";
|
||||
}
|
||||
|
||||
export const useStore = create<AppStore>(() => ({
|
||||
inputMode: "image",
|
||||
}));
|
||||
@ -16,6 +16,7 @@ export interface Settings {
|
||||
codeGenerationModel: CodeGenerationModel;
|
||||
// Only relevant for hosted version
|
||||
isTermOfServiceAccepted: boolean;
|
||||
anthropicApiKey: string | null; // Added property for anthropic API key
|
||||
}
|
||||
|
||||
export enum AppState {
|
||||
|
||||
@ -5642,6 +5642,11 @@ use-sidecar@^1.1.2:
|
||||
detect-node-es "^1.1.0"
|
||||
tslib "^2.0.0"
|
||||
|
||||
use-sync-external-store@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
|
||||
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
|
||||
|
||||
util-deprecate@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
||||
@ -5937,3 +5942,10 @@ zod@3.22.4:
|
||||
version "3.22.4"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
|
||||
integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==
|
||||
|
||||
zustand@^4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.2.tgz#fddbe7cac1e71d45413b3682cdb47b48034c3848"
|
||||
integrity sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==
|
||||
dependencies:
|
||||
use-sync-external-store "1.2.0"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user