import { Button } from "@opencode-ai/ui/button" import { useDialog } from "@opencode-ai/ui/context/dialog" import { ProviderIcon } from "@opencode-ai/ui/provider-icon" import { Tag } from "@opencode-ai/ui/tag" import { showToast } from "@opencode-ai/ui/toast" import type { IconName } from "@opencode-ai/ui/icons/provider" import { popularProviders, useProviders } from "@/hooks/use-providers" import { createMemo, type Component, For, Show } from "solid-js" import { useLanguage } from "@/context/language" import { useGlobalSDK } from "@/context/global-sdk" import { DialogConnectProvider } from "./dialog-connect-provider" import { DialogSelectProvider } from "./dialog-select-provider" type ProviderSource = "env" | "api" | "config" | "custom" type ProviderMeta = { source?: ProviderSource } export const SettingsProviders: Component = () => { const dialog = useDialog() const language = useLanguage() const globalSDK = useGlobalSDK() const providers = useProviders() const connected = createMemo(() => { return providers .connected() .filter((p) => p.id !== "opencode" || Object.values(p.models).find((m) => m.cost?.input)) }) const popular = createMemo(() => { const connectedIDs = new Set(connected().map((p) => p.id)) const items = providers .popular() .filter((p) => !connectedIDs.has(p.id)) .slice() items.sort((a, b) => popularProviders.indexOf(a.id) - popularProviders.indexOf(b.id)) return items }) const source = (item: unknown) => (item as ProviderMeta).source const type = (item: unknown) => { const current = source(item) if (current === "env") return language.t("settings.providers.tag.environment") if (current === "api") return language.t("provider.connect.method.apiKey") if (current === "config") return language.t("settings.providers.tag.config") if (current === "custom") return language.t("settings.providers.tag.custom") return language.t("settings.providers.tag.other") } const canDisconnect = (item: unknown) => source(item) !== "env" const disconnect = async (providerID: string, name: string) => { await globalSDK.client.auth .remove({ providerID }) .then(async () => { await globalSDK.client.global.dispose() showToast({ variant: "success", icon: "circle-check", title: language.t("provider.disconnect.toast.disconnected.title", { provider: name }), description: language.t("provider.disconnect.toast.disconnected.description", { provider: name }), }) }) .catch((err: unknown) => { const message = err instanceof Error ? err.message : String(err) showToast({ title: language.t("common.requestFailed"), description: message }) }) } return (
) }