mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
feat: dashboard OAuth provider management
Add OAuth provider management to the Hermes dashboard with full
lifecycle support for Anthropic (PKCE), Nous and OpenAI Codex
(device-code) flows.
## Backend (hermes_cli/web_server.py)
- 6 new API endpoints:
GET /api/providers/oauth — list providers with connection status
POST /api/providers/oauth/{id}/start — initiate PKCE or device-code
POST /api/providers/oauth/{id}/submit — exchange PKCE auth code
GET /api/providers/oauth/{id}/poll/{session} — poll device-code
DELETE /api/providers/oauth/{id} — disconnect provider
DELETE /api/providers/oauth/sessions/{id} — cancel pending session
- OAuth constants imported from anthropic_adapter (no duplication)
- Blocking I/O wrapped in run_in_executor for async safety
- In-memory session store with 15-minute TTL and automatic GC
- Auth token required on all mutating endpoints
## Frontend
- OAuthLoginModal — PKCE (paste auth code) and device-code (poll) flows
- OAuthProvidersCard — status, token preview, connect/disconnect actions
- Toast fix: createPortal to document.body for correct z-index
- App.tsx: skip animation key bump on initial mount (prevent double-mount)
- Integrated into the Env/Keys page
This commit is contained in:
parent
2773b18b56
commit
247929b0dd
11 changed files with 1789 additions and 96 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { Activity, BarChart3, Clock, FileText, KeyRound, MessageSquare, Package, Settings } from "lucide-react";
|
||||
import StatusPage from "@/pages/StatusPage";
|
||||
import ConfigPage from "@/pages/ConfigPage";
|
||||
|
|
@ -36,8 +36,15 @@ const PAGE_COMPONENTS: Record<PageId, React.FC> = {
|
|||
export default function App() {
|
||||
const [page, setPage] = useState<PageId>("status");
|
||||
const [animKey, setAnimKey] = useState(0);
|
||||
const initialRef = useRef(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Skip the animation key bump on initial mount to avoid re-mounting
|
||||
// the default page component (which causes duplicate API requests).
|
||||
if (initialRef.current) {
|
||||
initialRef.current = false;
|
||||
return;
|
||||
}
|
||||
setAnimKey((k) => k + 1);
|
||||
}, [page]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue