mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-03 02:11:48 +00:00
chore: remove comments
This commit is contained in:
parent
0348a69c51
commit
e1027134cd
12 changed files with 721 additions and 378 deletions
|
|
@ -44,18 +44,16 @@ export function Backdrop() {
|
|||
// `assets.bg` — the <img> hides itself when a CSS bg is set
|
||||
// so the two don't double-darken. CSS var fallbacks keep the
|
||||
// default behaviour unchanged when no theme customises these.
|
||||
mixBlendMode: "var(--component-backdrop-filler-blend-mode, difference)",
|
||||
mixBlendMode:
|
||||
"var(--component-backdrop-filler-blend-mode, difference)",
|
||||
opacity: "var(--component-backdrop-filler-opacity, 0.033)",
|
||||
backgroundImage: "var(--theme-asset-bg)",
|
||||
backgroundSize: "var(--component-backdrop-background-size, cover)",
|
||||
backgroundPosition: "var(--component-backdrop-background-position, center)",
|
||||
backgroundPosition:
|
||||
"var(--component-backdrop-background-position, center)",
|
||||
} as unknown as React.CSSProperties
|
||||
}
|
||||
>
|
||||
{/* Default filler image only renders when no theme-asset-bg is
|
||||
set. Themes that provide their own `assets.bg` override the
|
||||
<div>'s backgroundImage above, so hiding the <img> in that
|
||||
case prevents the two from compositing incorrectly. */}
|
||||
<img
|
||||
alt=""
|
||||
className="h-[150dvh] w-auto min-w-[100dvw] object-cover object-top-left invert theme-default-filler"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ export function LanguageSwitcher() {
|
|||
title={t.language.switchTo}
|
||||
aria-label={t.language.switchTo}
|
||||
>
|
||||
{/* Show the *current* language's flag — tooltip advertises the click action */}
|
||||
<span className="text-base leading-none">
|
||||
{locale === "en" ? "🇬🇧" : "🇨🇳"}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
Brain,
|
||||
Eye,
|
||||
Gauge,
|
||||
Lightbulb,
|
||||
Wrench,
|
||||
Loader2,
|
||||
} from "lucide-react";
|
||||
import { Brain, Eye, Gauge, Lightbulb, Wrench, Loader2 } from "lucide-react";
|
||||
import { api } from "@/lib/api";
|
||||
import type { ModelInfoResponse } from "@/lib/api";
|
||||
import { formatTokenCount } from "@/lib/format";
|
||||
|
|
@ -18,7 +11,10 @@ interface ModelInfoCardProps {
|
|||
refreshKey?: number;
|
||||
}
|
||||
|
||||
export function ModelInfoCard({ currentModel, refreshKey = 0 }: ModelInfoCardProps) {
|
||||
export function ModelInfoCard({
|
||||
currentModel,
|
||||
refreshKey = 0,
|
||||
}: ModelInfoCardProps) {
|
||||
const [info, setInfo] = useState<ModelInfoResponse | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const lastFetchKeyRef = useRef("");
|
||||
|
|
@ -53,7 +49,6 @@ export function ModelInfoCard({ currentModel, refreshKey = 0 }: ModelInfoCardPro
|
|||
|
||||
return (
|
||||
<div className="border border-border/60 bg-muted/30 px-3 py-2.5 space-y-2">
|
||||
{/* Context window */}
|
||||
<div className="flex items-center gap-4 text-xs">
|
||||
<div className="flex items-center gap-1.5 text-muted-foreground">
|
||||
<Gauge className="h-3.5 w-3.5" />
|
||||
|
|
@ -68,12 +63,13 @@ export function ModelInfoCard({ currentModel, refreshKey = 0 }: ModelInfoCardPro
|
|||
(override — auto: {formatTokenCount(info.auto_context_length)})
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-muted-foreground/60 text-[10px]">auto-detected</span>
|
||||
<span className="text-muted-foreground/60 text-[10px]">
|
||||
auto-detected
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Max output */}
|
||||
{hasCaps && caps.max_output_tokens && caps.max_output_tokens > 0 && (
|
||||
<div className="flex items-center gap-4 text-xs">
|
||||
<div className="flex items-center gap-1.5 text-muted-foreground">
|
||||
|
|
@ -86,7 +82,6 @@ export function ModelInfoCard({ currentModel, refreshKey = 0 }: ModelInfoCardPro
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* Capability badges */}
|
||||
{hasCaps && (
|
||||
<div className="flex flex-wrap items-center gap-1.5 pt-0.5">
|
||||
{caps.supports_tools && (
|
||||
|
|
|
|||
|
|
@ -21,11 +21,7 @@ type Phase =
|
|||
| "approved"
|
||||
| "error";
|
||||
|
||||
export function OAuthLoginModal({
|
||||
provider,
|
||||
onClose,
|
||||
onSuccess,
|
||||
}: Props) {
|
||||
export function OAuthLoginModal({ provider, onClose, onSuccess }: Props) {
|
||||
const [phase, setPhase] = useState<Phase>("starting");
|
||||
const [start, setStart] = useState<OAuthStartResponse | null>(null);
|
||||
const [pkceCode, setPkceCode] = useState("");
|
||||
|
|
@ -202,7 +198,6 @@ export function OAuthLoginModal({
|
|||
)}
|
||||
</div>
|
||||
|
||||
{/* ── starting ───────────────────────────────────── */}
|
||||
{phase === "starting" && (
|
||||
<div className="flex items-center gap-3 py-6 text-sm text-muted-foreground">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
|
|
@ -210,7 +205,6 @@ export function OAuthLoginModal({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* ── PKCE: paste code ───────────────────────────── */}
|
||||
{start?.flow === "pkce" && phase === "awaiting_user" && (
|
||||
<>
|
||||
<ol className="text-sm space-y-2 list-decimal list-inside text-muted-foreground">
|
||||
|
|
@ -250,7 +244,6 @@ export function OAuthLoginModal({
|
|||
</>
|
||||
)}
|
||||
|
||||
{/* ── PKCE: submitting exchange ──────────────────── */}
|
||||
{phase === "submitting" && (
|
||||
<div className="flex items-center gap-3 py-6 text-sm text-muted-foreground">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
|
|
@ -258,7 +251,6 @@ export function OAuthLoginModal({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* ── Device code: show code + URL, polling ──────── */}
|
||||
{start?.flow === "device_code" && phase === "polling" && (
|
||||
<>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
|
|
@ -309,7 +301,6 @@ export function OAuthLoginModal({
|
|||
</>
|
||||
)}
|
||||
|
||||
{/* ── approved ───────────────────────────────────── */}
|
||||
{phase === "approved" && (
|
||||
<div className="flex items-center gap-3 py-6 text-sm text-success">
|
||||
<Check className="h-5 w-5" />
|
||||
|
|
@ -317,7 +308,6 @@ export function OAuthLoginModal({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* ── error ──────────────────────────────────────── */}
|
||||
{phase === "error" && (
|
||||
<>
|
||||
<div className="border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive">
|
||||
|
|
|
|||
|
|
@ -1,8 +1,22 @@
|
|||
import { useEffect, useState, useCallback, useRef } from "react";
|
||||
import { ShieldCheck, ShieldOff, ExternalLink, RefreshCw, LogOut, Terminal, LogIn } from "lucide-react";
|
||||
import {
|
||||
ShieldCheck,
|
||||
ShieldOff,
|
||||
ExternalLink,
|
||||
RefreshCw,
|
||||
LogOut,
|
||||
Terminal,
|
||||
LogIn,
|
||||
} from "lucide-react";
|
||||
import { api, type OAuthProvider } from "@/lib/api";
|
||||
import { Button, CopyButton } from "@nous-research/ui";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Badge } from "@nous-research/ui";
|
||||
import { OAuthLoginModal } from "@/components/OAuthLoginModal";
|
||||
import { useI18n } from "@/i18n";
|
||||
|
|
@ -12,7 +26,10 @@ interface Props {
|
|||
onSuccess?: (msg: string) => void;
|
||||
}
|
||||
|
||||
function formatExpiresAt(expiresAt: string | null | undefined, expiresInTemplate: string): string | null {
|
||||
function formatExpiresAt(
|
||||
expiresAt: string | null | undefined,
|
||||
expiresInTemplate: string,
|
||||
): string | null {
|
||||
if (!expiresAt) return null;
|
||||
try {
|
||||
const dt = new Date(expiresAt);
|
||||
|
|
@ -70,7 +87,8 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
}
|
||||
};
|
||||
|
||||
const connectedCount = providers?.filter((p) => p.status.logged_in).length ?? 0;
|
||||
const connectedCount =
|
||||
providers?.filter((p) => p.status.logged_in).length ?? 0;
|
||||
const totalCount = providers?.length ?? 0;
|
||||
|
||||
return (
|
||||
|
|
@ -79,19 +97,25 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<ShieldCheck className="h-5 w-5 text-muted-foreground" />
|
||||
<CardTitle className="text-base">{t.oauth.providerLogins}</CardTitle>
|
||||
<CardTitle className="text-base">
|
||||
{t.oauth.providerLogins}
|
||||
</CardTitle>
|
||||
</div>
|
||||
<Button
|
||||
outlined
|
||||
onClick={refresh}
|
||||
disabled={loading}
|
||||
prefix={<RefreshCw className={loading ? "animate-spin" : undefined} />}
|
||||
prefix={
|
||||
<RefreshCw className={loading ? "animate-spin" : undefined} />
|
||||
}
|
||||
>
|
||||
{t.common.refresh}
|
||||
</Button>
|
||||
</div>
|
||||
<CardDescription>
|
||||
{t.oauth.description.replace("{connected}", String(connectedCount)).replace("{total}", String(totalCount))}
|
||||
{t.oauth.description
|
||||
.replace("{connected}", String(connectedCount))
|
||||
.replace("{total}", String(totalCount))}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
|
@ -107,14 +131,16 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
)}
|
||||
<div className="flex flex-col divide-y divide-border">
|
||||
{providers?.map((p) => {
|
||||
const expiresLabel = formatExpiresAt(p.status.expires_at, t.oauth.expiresIn);
|
||||
const expiresLabel = formatExpiresAt(
|
||||
p.status.expires_at,
|
||||
t.oauth.expiresIn,
|
||||
);
|
||||
const isBusy = busyId === p.id;
|
||||
return (
|
||||
<div
|
||||
key={p.id}
|
||||
className="flex items-center justify-between gap-4 py-3"
|
||||
>
|
||||
{/* Left: status icon + name + source */}
|
||||
<div className="flex items-start gap-3 min-w-0 flex-1">
|
||||
{p.status.logged_in ? (
|
||||
<ShieldCheck className="h-5 w-5 text-success shrink-0 mt-0.5" />
|
||||
|
|
@ -124,7 +150,10 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
<div className="flex flex-col min-w-0 gap-0.5">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="font-medium text-sm">{p.name}</span>
|
||||
<Badge tone="outline" className="text-[11px] uppercase tracking-wide">
|
||||
<Badge
|
||||
tone="outline"
|
||||
className="text-[11px] uppercase tracking-wide"
|
||||
>
|
||||
{t.oauth.flowLabels[p.flow]}
|
||||
</Badge>
|
||||
{p.status.logged_in && (
|
||||
|
|
@ -145,11 +174,12 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
</div>
|
||||
{p.status.logged_in && p.status.token_preview && (
|
||||
<code className="text-xs font-mono-ui truncate">
|
||||
<span className="opacity-50">token{" "}</span>
|
||||
<span className="opacity-50">token </span>
|
||||
{p.status.token_preview}
|
||||
{p.status.source_label && (
|
||||
<span className="opacity-40">
|
||||
{" "}· {p.status.source_label}
|
||||
{" "}
|
||||
· {p.status.source_label}
|
||||
</span>
|
||||
)}
|
||||
</code>
|
||||
|
|
@ -170,7 +200,7 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* Right: action buttons */}
|
||||
|
||||
<div className="flex items-center gap-1.5 shrink-0">
|
||||
{p.docs_url && (
|
||||
<a
|
||||
|
|
@ -186,10 +216,7 @@ export function OAuthProvidersCard({ onError, onSuccess }: Props) {
|
|||
</a>
|
||||
)}
|
||||
{!p.status.logged_in && p.flow !== "external" && (
|
||||
<Button
|
||||
onClick={() => setLoginFor(p)}
|
||||
prefix={<LogIn />}
|
||||
>
|
||||
<Button onClick={() => setLoginFor(p)} prefix={<LogIn />}>
|
||||
{t.oauth.login}
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue