jules f81ad25fc8 DeepSeek: drop /v1 from default baseURL, refresh model list
Provider's published URL is now https://api.deepseek.com (no /v1).
Default model list updated to V4 family (flash + pro). Legacy aliases
deepseek-chat / deepseek-reasoner are still accepted upstream but
deprecate 2026-07-24, so they don't belong in the picker default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:33:18 +10:00
2026-05-01 22:50:59 +10:00

lib-llm-providers-ui

Multi-provider LLM picker + settings card for Crema apps. Sits on top of @crema/llm-ui and adds:

  • A named provider catalog (OpenAI, Anthropic, DeepSeek, Qwen, LM Studio) with sensible default base URLs and model lists.
  • An arcadia-proxy adapter that routes chat completions through POST /api/v1/ai/llm/chat, so API keys never leave the server.
  • A direct-mode adapter that resolves the API key from arcadia's Secrets Manager (GET /api/v1/secrets/:name) and calls the provider directly from the browser.
  • A settings card (LLMProvidersSettingsCard) that ties it all together — provider, model, base-URL override, arcadia-secret name, transport toggle, context/response budgets, system prompt.
  • A persistent settings store with useSettings() / saveSettings() / resetSettings() and a crema:llm-providers-change event for reactive updates across tabs.

Quick start

import {
  LLMProvidersSettingsCard,
  buildAdapter,
  useSettings,
} from "@crema/llm-providers-ui"
import { LLMProvider, useChat } from "@crema/llm-ui"
import { useArcadiaClient } from "@crema/arcadia-client"
import { useEffect, useState } from "react"

function App() {
  const arcadia = useArcadiaClient()
  const settings = useSettings()
  const [adapter, setAdapter] = useState(null)

  useEffect(() => {
    buildAdapter({
      settings,
      // Direct mode — fetch the API key from arcadia's vault.
      resolveSecret: async (name) => {
        const res = await arcadia.GET<{ data: { value: string } }>(`/api/v1/secrets/${name}`)
        return res.data.value
      },
      // Or proxy mode (when the backend endpoint exists):
      arcadiaBaseURL: import.meta.env.VITE_ARCADIA_URL,
      arcadiaAuthToken: sessionStorage.getItem("arcadia_access_token") ?? undefined,
      arcadiaTenantId: import.meta.env.VITE_ARCADIA_TENANT,
    }).then(setAdapter)
  }, [settings, arcadia])

  if (!adapter) return null
  return (
    <LLMProvider adapter={adapter} model={settings.model}>
      <Chat />
    </LLMProvider>
  )
}

For the settings page:

<LLMProvidersSettingsCard
  hideTransportToggle={!proxyAvailable}
  onTest={async (s) => {
    // Wire to a one-off completion through buildAdapter.
    // Return { ok: true, message: "Connected." } or { ok: false, message: "..." }.
  }}
/>

Direct vs proxy

Mode Where the key lives at call time When to use
direct Briefly in the browser (fetched from arcadia per-call) When the backend proxy isn't deployed yet, or for local development.
proxy Server-side only (read by arcadia, never sent to the client) Production. Requires POST /api/v1/ai/llm/chat on arcadia — see LLM_PROXY_CONTRACT.md in the consuming app.

The settings card lets the user toggle between them. buildAdapter() returns the right adapter automatically.

Provider catalog

Edit PROVIDERS in src/index.tsx to add more. Each entry is:

{
  id: "deepseek",
  label: "DeepSeek",
  baseURL: "https://api.deepseek.com/v1",
  transport: "openai-compatible", // or "anthropic"
  requiresKey: true,
  defaultModels: ["deepseek-chat", "deepseek-reasoner"],
  hint: "OpenAI-compatible. Create a key at platform.deepseek.com.",
}

Adding a provider with a different shape (e.g. Google AI) means picking the closest existing transport, or extending @crema/llm-ui with a new adapter and adding a transport string here.

Wiring into a Crema app

  1. Clone this lib as a sibling.
  2. Add @source "../../lib-llm-providers-ui/src"; under /* CREMA:SOURCES */ in app/app.css.
  3. Add the path alias under // CREMA:PATHS in tsconfig.json:
    "@crema/llm-providers-ui": ["../lib-llm-providers-ui/src/index.tsx"],
    "@crema/llm-providers-ui/*": ["../lib-llm-providers-ui/src/*"],
    
  4. crema add does this automatically once the manifest knows about the lib.
Description
Multi-provider LLM picker (OpenAI, Anthropic, DeepSeek, Qwen, LM Studio) on top of @crema/llm-ui, with arcadia-vault key resolution and a settings card.
Readme 59 KiB
Languages
TypeScript 100%