Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/aula-id_koma.json
T

1 line
12 KiB
JSON

{"repo": "aula-id/koma", "files": {"src-webgui/src/components/panels/connector/ProviderForm.tsx": {"3ea22924c1ad420c5a70bd887398726870103575": {"t": 1785674600.4391553, "n": 5798, "h": "49c90c625cb23cc7", "c": "import { useState } from 'react'\nimport { ChevronRight, Server, SlidersHorizontal } from 'lucide-react'\nimport { Field, TextInput } from '../form'\nimport { FormActions } from '../helpers'\nimport type { Provider } from '../../../types/config'\n\n// The daemon never sends the plaintext key back (see `Provider.hasKey`), so\n// the form can't prefill it. The save payload carries only the TYPED value —\n// empty means \"leave unchanged\" (daemon-side blank-keeps-existing).\nexport type ProviderSavePayload = { id: string; name: string; endpoint: string; apiKey: string }\n\n// Predefined marketplaces — a name + verified OpenAI-compatible base URL that\n// pre-fills the form so the user only pastes a key. Base URLs are WEB-VERIFIED\n// canonical endpoints (note the non-obvious ones: Groq `/openai/v1`, Fireworks\n// `/inference/v1`, DeepInfra `/v1/openai`, Mimo token-plan host). \"Custom\" is\n// handled separately (blank manual form).\nexport const PREDEFINED: { name: string; endpoint: string }[] = [\n { name: 'Koma', endpoint: 'https://koma.run/api/v1/koma-gateway' },\n { name: 'OpenRouter', endpoint: 'https://openrouter.ai/api/v1' },\n { name: 'DeepSeek', endpoint: 'https://api.deepseek.com' },\n { name: 'Mimo (token plan)', endpoint: 'https://token-plan-sgp.xiaomimimo.com/v1' },\n { name: 'OpenAI', endpoint: 'https://api.openai.com/v1' },\n { name: 'Groq', endpoint: 'https://api.groq.com/openai/v1' },\n { name: 'Together', endpoint: 'https://api.together.xyz/v1' },\n { name: 'Fireworks', endpoint: 'https://api.fireworks.ai/inference/v1' },\n { name: 'Mistral', endpoint: 'https://api.mistral.ai/v1' },\n { name: 'DeepInfra', endpoint: 'https://api.deepinfra.com/v1/openai' },\n]\n\nexport function ProviderForm({\n draft,\n onSave,\n onCancel,\n preset,\n}: {\n draft: Provider\n onSave: (d: ProviderSavePayload) => void\n onCancel: () => void\n // Onboarding pre-selects a preset (or an explicit \"custom\") on its own pick\n // screen and hands it in here — when supplied, skip the internal 'pick'\n // step entirely and pre-fill name/endpoint from the preset (undefined for\n // \"custom\", leaving the draft's blank name/endpoint as-is).\n preset?: { name: string; endpoint: string } | 'custom'\n}) {\n const [d, setD] = useState<Provider>(() =>\n preset && preset !== 'custom' ? { ...draft, name: preset.name, endpoint: preset.endpoint } : draft,\n )\n // Always starts empty — the real key is never available to prefill.\n const [apiKey, setApiKey] = useState('')\n // A brand-new provider (empty name + endpoint) leads with the marketplace\n // picker; editing an existing one jumps straight to the manual form. A\n // caller-supplied `preset` (onboarding) always skips straight to the form.\n const isNewDraft = draft.name.trim() === '' && draft.endpoint.trim() === ''\n const [step, setStep] = useState<'pick' | 'form'>(preset !== undefined ? 'form' : isNewDraft ? 'pick' : 'form')\n const patch = (p: Partial<Provider>) => setD((x) => ({ ...x, ...p }))\n const keyPlaceholder = d.hasKey ? '•••••••• (unchanged — leave blank to keep)' : 'sk-…'\n\n const pickPreset = (name: string, endpoint: string) => {\n patch({ name, endpoint })\n setStep('form')\n }\n\n if (step === 'pick') {\n return (\n <div className=\"flex-1 overflow-auto py-1\">\n <div className=\"px-3 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wider text-koma-fg opacity-50\">\n Choose a provider\n </div>\n <div className=\"flex flex-col gap-0.5 px-2\">\n {PREDEFINED.map((p) => (\n <button\n key={p.name}\n type=\"button\"\n onClick={() => pickPreset(p.name, p.endpoint)}\n className=\"flex items-center gap-2 rounded px-2 py-1.5 text-left transition-colors hover:bg-koma-hover\"\n >\n <Server size={14} className=\"flex-none text-koma-accent\" />\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-[12.5px] text-koma-fg\">{p.name}</span>\n <span className=\"truncate text-[10.5px] text-koma-fg opacity-40\">{p.endpoint}</span>\n </span>\n <ChevronRight size={13} className=\"flex-none text-koma-fg opacity-30\" />\n </button>\n ))}\n <button\n type=\"button\"\n onClick={() => setStep('form')}\n className=\"mt-1 flex items-center gap-2 rounded border border-dashed border-koma-border px-2 py-1.5 text-left transition-colors hover:bg-koma-hover\"\n >\n <SlidersHorizontal size={14} className=\"flex-none text-koma-fg opacity-60\" />\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-[12.5px] text-koma-fg\">Custom</span>\n <span className=\"text-[10.5px] text-koma-fg opacity-40\">Enter name + endpoint manually</span>\n </span>\n <ChevronRight size={13} className=\"flex-none text-koma-fg opacity-30\" />\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <>\n <div className=\"flex-1 overflow-auto py-1\">\n <Field label=\"Name\">\n <TextInput value={d.name} autoFocus placeholder=\"e.g. OpenRouter\" onChange={(e) => patch({ name: e.target.value })} />\n </Field>\n <Field label=\"Endpoint (base URL)\">\n <TextInput value={d.endpoint} placeholder=\"https://…/v1\" onChange={(e) => patch({ endpoint: e.target.value })} />\n </Field>\n <Field label=\"API key\">\n <TextInput value={apiKey} type=\"password\" placeholder={keyPlaceholder} onChange={(e) => setApiKey(e.target.value)} />\n </Field>\n </div>\n <FormActions\n onCancel={onCancel}\n onSave={() => onSave({ id: d.id, name: d.name, endpoint: d.endpoint, apiKey })}\n saveDisabled={!d.name.trim()}\n />\n </>\n )\n}\n"}, "a14d029250efb9a566fba4dafaa74d802462a6bf": {"t": 1785846899.227603, "n": 5798, "h": "49c90c625cb23cc7", "c": "import { useState } from 'react'\nimport { ChevronRight, Server, SlidersHorizontal } from 'lucide-react'\nimport { Field, TextInput } from '../form'\nimport { FormActions } from '../helpers'\nimport type { Provider } from '../../../types/config'\n\n// The daemon never sends the plaintext key back (see `Provider.hasKey`), so\n// the form can't prefill it. The save payload carries only the TYPED value —\n// empty means \"leave unchanged\" (daemon-side blank-keeps-existing).\nexport type ProviderSavePayload = { id: string; name: string; endpoint: string; apiKey: string }\n\n// Predefined marketplaces — a name + verified OpenAI-compatible base URL that\n// pre-fills the form so the user only pastes a key. Base URLs are WEB-VERIFIED\n// canonical endpoints (note the non-obvious ones: Groq `/openai/v1`, Fireworks\n// `/inference/v1`, DeepInfra `/v1/openai`, Mimo token-plan host). \"Custom\" is\n// handled separately (blank manual form).\nexport const PREDEFINED: { name: string; endpoint: string }[] = [\n { name: 'Koma', endpoint: 'https://koma.run/api/v1/koma-gateway' },\n { name: 'OpenRouter', endpoint: 'https://openrouter.ai/api/v1' },\n { name: 'DeepSeek', endpoint: 'https://api.deepseek.com' },\n { name: 'Mimo (token plan)', endpoint: 'https://token-plan-sgp.xiaomimimo.com/v1' },\n { name: 'OpenAI', endpoint: 'https://api.openai.com/v1' },\n { name: 'Groq', endpoint: 'https://api.groq.com/openai/v1' },\n { name: 'Together', endpoint: 'https://api.together.xyz/v1' },\n { name: 'Fireworks', endpoint: 'https://api.fireworks.ai/inference/v1' },\n { name: 'Mistral', endpoint: 'https://api.mistral.ai/v1' },\n { name: 'DeepInfra', endpoint: 'https://api.deepinfra.com/v1/openai' },\n]\n\nexport function ProviderForm({\n draft,\n onSave,\n onCancel,\n preset,\n}: {\n draft: Provider\n onSave: (d: ProviderSavePayload) => void\n onCancel: () => void\n // Onboarding pre-selects a preset (or an explicit \"custom\") on its own pick\n // screen and hands it in here — when supplied, skip the internal 'pick'\n // step entirely and pre-fill name/endpoint from the preset (undefined for\n // \"custom\", leaving the draft's blank name/endpoint as-is).\n preset?: { name: string; endpoint: string } | 'custom'\n}) {\n const [d, setD] = useState<Provider>(() =>\n preset && preset !== 'custom' ? { ...draft, name: preset.name, endpoint: preset.endpoint } : draft,\n )\n // Always starts empty — the real key is never available to prefill.\n const [apiKey, setApiKey] = useState('')\n // A brand-new provider (empty name + endpoint) leads with the marketplace\n // picker; editing an existing one jumps straight to the manual form. A\n // caller-supplied `preset` (onboarding) always skips straight to the form.\n const isNewDraft = draft.name.trim() === '' && draft.endpoint.trim() === ''\n const [step, setStep] = useState<'pick' | 'form'>(preset !== undefined ? 'form' : isNewDraft ? 'pick' : 'form')\n const patch = (p: Partial<Provider>) => setD((x) => ({ ...x, ...p }))\n const keyPlaceholder = d.hasKey ? '•••••••• (unchanged — leave blank to keep)' : 'sk-…'\n\n const pickPreset = (name: string, endpoint: string) => {\n patch({ name, endpoint })\n setStep('form')\n }\n\n if (step === 'pick') {\n return (\n <div className=\"flex-1 overflow-auto py-1\">\n <div className=\"px-3 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wider text-koma-fg opacity-50\">\n Choose a provider\n </div>\n <div className=\"flex flex-col gap-0.5 px-2\">\n {PREDEFINED.map((p) => (\n <button\n key={p.name}\n type=\"button\"\n onClick={() => pickPreset(p.name, p.endpoint)}\n className=\"flex items-center gap-2 rounded px-2 py-1.5 text-left transition-colors hover:bg-koma-hover\"\n >\n <Server size={14} className=\"flex-none text-koma-accent\" />\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-[12.5px] text-koma-fg\">{p.name}</span>\n <span className=\"truncate text-[10.5px] text-koma-fg opacity-40\">{p.endpoint}</span>\n </span>\n <ChevronRight size={13} className=\"flex-none text-koma-fg opacity-30\" />\n </button>\n ))}\n <button\n type=\"button\"\n onClick={() => setStep('form')}\n className=\"mt-1 flex items-center gap-2 rounded border border-dashed border-koma-border px-2 py-1.5 text-left transition-colors hover:bg-koma-hover\"\n >\n <SlidersHorizontal size={14} className=\"flex-none text-koma-fg opacity-60\" />\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-[12.5px] text-koma-fg\">Custom</span>\n <span className=\"text-[10.5px] text-koma-fg opacity-40\">Enter name + endpoint manually</span>\n </span>\n <ChevronRight size={13} className=\"flex-none text-koma-fg opacity-30\" />\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <>\n <div className=\"flex-1 overflow-auto py-1\">\n <Field label=\"Name\">\n <TextInput value={d.name} autoFocus placeholder=\"e.g. OpenRouter\" onChange={(e) => patch({ name: e.target.value })} />\n </Field>\n <Field label=\"Endpoint (base URL)\">\n <TextInput value={d.endpoint} placeholder=\"https://…/v1\" onChange={(e) => patch({ endpoint: e.target.value })} />\n </Field>\n <Field label=\"API key\">\n <TextInput value={apiKey} type=\"password\" placeholder={keyPlaceholder} onChange={(e) => setApiKey(e.target.value)} />\n </Field>\n </div>\n <FormActions\n onCancel={onCancel}\n onSave={() => onSave({ id: d.id, name: d.name, endpoint: d.endpoint, apiKey })}\n saveDisabled={!d.name.trim()}\n />\n </>\n )\n}\n"}}}}