anyllm_proxy 0.9.6

HTTP proxy translating Anthropic Messages API to OpenAI Chat Completions
Documentation
import { useMemo, useState } from 'react'
import {
  useManagedBackends,
  useDeleteManagedBackend,
  useCatalogProviders,
} from '../../api/queries'
import type { ManagedBackend } from '../../api/types'
import EmptyState from '../../components/shared/EmptyState'
import ConfirmDialog from '../../components/shared/ConfirmDialog'
import ProviderIcon from '../../components/shared/ProviderIcon'
import { BackendForm } from './BackendForm'

type PanelState =
  | { mode: 'none' }
  | { mode: 'create' }
  | { mode: 'edit'; backend: ManagedBackend }

export function ManagedBackendsSection() {
  const { data, isLoading, error } = useManagedBackends()
  const { data: providers = [] } = useCatalogProviders()
  const del = useDeleteManagedBackend()

  const [panel, setPanel] = useState<PanelState>({ mode: 'none' })
  const [pendingDelete, setPendingDelete] = useState<ManagedBackend | null>(null)

  const providerMap = useMemo(
    () => Object.fromEntries(providers.map(p => [p.id, p.display_name])),
    [providers],
  )

  function getProviderLabel(providerId: string): string {
    return providerMap[providerId] ?? providerId
  }

  function doDelete() {
    if (!pendingDelete) return Promise.resolve()
    return del.mutateAsync(pendingDelete.name).then(() => undefined)
  }

  return (
    <div style={{ marginBottom: 24 }}>
      <div className="section-header">
        <div className="section-label" style={{ margin: 0 }}>Managed Backends</div>
        <button
          className="btn btn-primary btn-sm"
          onClick={() => setPanel({ mode: 'create' })}
        >
          Add Backend
        </button>
      </div>
      <div style={{ fontSize: 12, color: 'var(--text-2)', marginBottom: 10 }}>
        Configure provider credentials and backend settings at runtime.
      </div>

      {/* Inline form — create or edit */}
      {panel.mode === 'create' && (
        <BackendForm
          onSuccess={() => setPanel({ mode: 'none' })}
          onCancel={() => setPanel({ mode: 'none' })}
        />
      )}
      {panel.mode === 'edit' && (
        <BackendForm
          initial={panel.backend}
          onSuccess={() => setPanel({ mode: 'none' })}
          onCancel={() => setPanel({ mode: 'none' })}
        />
      )}

      <EmptyState loading={isLoading} error={error?.message} />

      {data && data.backends.length === 0 && (
        <div style={{ padding: '20px 0', color: 'var(--text-2)', fontSize: 13 }}>
          No managed backends yet. Add one to configure provider credentials at runtime.
        </div>
      )}

      {data && data.backends.length > 0 && (
        <table className="route-table">
          <thead>
            <tr>
              <th>Name</th>
              <th>Provider</th>
              <th>Credentials</th>
              <th>Base URL</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {data.backends.map((b) => (
              <tr key={b.id}>
                <td className="mono">{b.name}</td>
                <td className="dim" style={{ whiteSpace: 'nowrap' }}>
                  <ProviderIcon id={b.provider_id} size={16} style={{ marginRight: 6, verticalAlign: 'middle', opacity: 0.8 }} />
                  {getProviderLabel(b.provider_id)}
                </td>
                <td>
                  {b.api_key_set && (
                    <span className="badge badge-active" style={{ marginRight: 4 }}>Key set</span>
                  )}
                  {!b.api_key_set && !b.aws_creds_set && (
                    <span className="badge badge-revoked">No key</span>
                  )}
                  {b.aws_creds_set && (
                    <span className="badge badge-active">AWS creds set</span>
                  )}
                </td>
                <td className="dim mono" style={{ fontSize: 11 }}>{b.api_base ?? '—'}</td>
                <td>
                  <div style={{ display: 'flex', gap: 6 }}>
                    <button
                      className="btn btn-secondary btn-sm"
                      onClick={() => {
                        if (panel.mode === 'edit' && panel.backend.id === b.id) {
                          setPanel({ mode: 'none' })
                        } else {
                          setPanel({ mode: 'edit', backend: b })
                        }
                      }}
                    >
                      Edit
                    </button>
                    <button
                      className="btn btn-danger btn-sm"
                      onClick={() => setPendingDelete(b)}
                      disabled={del.isPending && del.variables === b.name}
                    >
                      Delete
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      )}

      <ConfirmDialog
        open={pendingDelete !== null}
        onClose={() => setPendingDelete(null)}
        onConfirm={doDelete}
        title="Delete managed backend?"
        message={
          <>
            Delete backend <span className="mono">{pendingDelete?.name}</span>? Stored credentials will be
            removed. Routes still referencing it will fail until reconfigured.
          </>
        }
      />
    </div>
  )
}