feat(cli): add first-class z.ai/GLM, Kimi, MiniMax direct API provider support#33
Conversation
|
@teknium1 I wanted to be able to freely try Hermes Agents and have a subscription to all of these open source model providers You don't need to merge but I made sure to do to a high quality - used only GPT 5.3 Codex Extra High and referenced the provider implementation from Pi Agent |
|
Follow-up (clean summary of commit
Validation run:
|
Will be reviewing soon - It's a bit of a complex PR so want to make sure its thoroughly looked over, will lyk in a day or so |
FYI consider using the PR as a prompt template Ie have your own preferred coding agent rebuild it in a way that works for you I rarely merge OSS PR because of conflict and vision management I will have Claude and Codex review it to create a meta prompt that I would apply whenever suits This does add a full provider layer which may not be exactly to the way you prefer So yeah, totally cool, do whatever you like |
|
Yea I probably will - Am trying to work out a way to let PR sources get contributor status though x] |
Personally not concerned about attribution For when you do want that process, you could add Co-authored-by: Your Name And ask everyone to start with an issue template Look forward to seeing whatever you come up with! |
Adds 4 new direct API-key providers (zai, kimi-coding, minimax, minimax-cn) to the inference provider system. All use standard OpenAI-compatible chat/completions endpoints with Bearer token auth. Core changes: - auth.py: Extended ProviderConfig with api_key_env_vars and base_url_env_var fields. Added providers to PROVIDER_REGISTRY. Added provider aliases (glm, z-ai, zhipu, kimi, moonshot). Added auto-detection of API-key providers in resolve_provider(). Added resolve_api_key_provider_credentials() and get_api_key_provider_status() helpers. - runtime_provider.py: Added generic API-key provider branch in resolve_runtime_provider() — any provider with auth_type='api_key' is automatically handled. - main.py: Added providers to hermes model menu with generic _model_flow_api_key_provider() flow. Updated _has_any_provider_configured() to check all provider env vars. Updated argparse --provider choices. - setup.py: Added providers to setup wizard with API key prompts and curated model lists. - config.py: Added env vars (GLM_API_KEY, KIMI_API_KEY, MINIMAX_API_KEY, etc.) to OPTIONAL_ENV_VARS. - status.py: Added API key display and provider status section. - doctor.py: Added connectivity checks for each provider endpoint. - cli.py: Updated provider docstrings. Docs: Updated README.md, .env.example, cli-config.yaml.example, cli-commands.md, environment-variables.md, configuration.md. Tests: 50 new tests covering registry, aliases, resolution, auto-detection, credential resolution, and runtime provider dispatch. Inspired by PR #33 (numman-ali) which proposed a provider registry approach. Credit to tars90percent (PR #473) and manuelschipper (PR #420) for related provider improvements merged earlier in this changeset.
|
We've implemented first-class z.ai/GLM, Kimi/Moonshot, MiniMax support in commit 388dd47, taking inspiration from this PR's provider registry approach. Due to 24 merge conflicts (the branch was very stale against main), we couldn't merge directly. Instead we implemented the provider support from scratch, following the same general concept but integrating with the current codebase architecture. Changes cover all 9 integration points: auth.py PROVIDER_REGISTRY, runtime_provider.py, hermes model command, setup wizard, config, status, doctor, CLI, and docs. 50 new tests. Thanks for the original design proposal, @numman-ali — credited in the commit message. |
|
Closing as superseded by the direct implementation in commits 388dd47 and 9742f11. The provider registry concept from this PR was implemented from scratch against the current codebase (the original branch had 24 merge conflicts). Thanks again @numman-ali for the design inspiration — credited in commit messages. |
…ree-preview Sprint 18: File preview auto-close, thinking display, workspace tree view
…ry/File Browser (NousResearch#33) * feat: Agent Hub restructure — 3-tab layout, pixel robot avatars, enterprise polish - Restructured Agent Hub from 5 tabs to 3 (Overview/Configure/Missions) - Overview: mission banner, stats cards, agent cards grid, live office toggle - Configure: agents (name/model/role/prompt/avatar), teams, API keys, approvals - Missions: launch form, active mission board, history - Pixel robot SVG avatars (10 unique chunky designs) - Trendy default agent names (Scout, Quill, Polish, Atlas, Forge, etc.) - Avatar picker in Configure with 10 robot options - Full light theme polish, removed all dark: classes - Extracted components: overview-tab, configure-tab, missions-tab, office-view, launch-wizard, agent-avatar - Sidebar logo visible when collapsed, hover-to-expand - Chat panel scroll fix - System metrics footer removed - Auth guards, memory APIs, costs page from sprint branch - Removed unused desktop roster/live-feed panels - Clean TypeScript build * fix: Agent Hub mission bugs — timeline view, output streaming, status counts, navigation * fix: Agent output panel — slide-out overlay, markdown rendering, status badges, light theme * feat: Mission deliverables, auto-reports, mission history persistence - Artifact extraction from agent outputs (code blocks with filenames, report/summary sections) - Deliverables section in Missions tab with artifact cards, type badges, preview - HTML artifacts open in new tab via blob URL - Markdown/code artifacts render in modal with proper formatting - Auto-generated mission reports on completion (goal, team, tasks, per-agent summary, cost estimate) - Mission history persisted to localStorage (max 10, newest first) - View Report modal with stats cards (duration, tasks, artifacts, cost) - Token counting during missions for cost estimates - stopMissionAndCleanup consolidated into reusable callback - Added ROADMAP.md * feat: Browser APIs rewired — multi-method fallback, navigate route, no demo mode, proper error states - All browser API routes (status/tabs/screenshot) now try multiple RPC method names (camelCase + snake_case) - New /api/browser/navigate route for URL navigation - Removed demo/mock tab data — shows real connection status or clear 'not connected' state - BrowserPanel: proper disconnected state with instructions, auto-refresh screenshots when connected - TypeScript clean build * fix: model discovery includes auth-free providers (ollama, local LLMs) from models.providers config * feat: Add 6 new model presets (GPT-5, o3, Gemini Pro, DeepSeek, MiniMax, Grok) * fix: clean model presets — 6 core models with minimax, removed dark: classes from badges * feat: Dynamic model dropdown + Add Provider form in Agent Hub - Model dropdown fetches from /api/models, shows presets + all gateway models - Add Provider form in Configure > API Keys writes to openclaw.json - Backend add-provider handler with validation and cache invalidation - Model badge/label fallbacks for arbitrary provider/model strings - Widened modelId type from ModelPresetId to string across all components * feat: Interactive model selector in Add Provider, default model persistence * feat: Overview redesign + dynamic model dropdowns from gateway - Overview: hero section, live office always visible, current/recent missions, team overview, compact stats - Model dropdowns show all gateway models (optgroup: Presets + Available Models) - Badge/label fallbacks for arbitrary provider/model strings - Removed Cards/Live toggle (office always shown) * feat: Isometric pixel office + Overview widget grid + specs for missions kanban * feat: approvals bell in header + gateway approval polling + distinct themes * feat: approvals bell in header + gateway approval polling + distinct ops/premium dark themes - ApprovalsBell popup component in header next to Live View - Shows badge count, auto-opens on first approval - Quick approve/deny + expand to read full context - Visual distinction: amber for agent approvals, violet for gateway approvals - Approve All / Deny All in footer - Click-outside to close, pulse animation on new arrivals - Gateway approval polling (every 8s) - Polls /api/gateway/approvals and merges into local state - Gateway approvals routed to resolveGatewayApproval API - Agent approvals still send APPROVED/DENIED messages to sessions - Degrades gracefully if endpoint not available - Approvals source field in store (agent | gateway) - Removed old amber badge button from tab bar (redundant) - Ops Dark: cold blue-steel (#080c14 bg, #1e3a5f border, #3b82f6 focus) - Premium Dark: deep zinc + violet glow (#05050a bg, #2a1f4a border, #7c6fdd focus) - Both themes apply globally via CSS variables with targeted overrides - EnterpriseThemePicker in settings now shows visual swatches for each theme * refactor: overview widget cleanup + TS fixes - Remove Quick Links footer bar (Cost Analytics, Memory Browser, etc.) - Replace 'Current Session' widget with 'System Health' (gateway status, active sessions, model count, providers, est. cost) - Replace 'Reports' widget with 'Recent Missions' (last 3 runs with task progress bar, duration, cost, agent count) - Fix TS6133 errors: remove _gatewayHeaderPillClass, _headerMetricCardClass, prefix _selectedAverageBudgetCost and _selectedSessionMember * refactor: configure page cleanup + system prompt overhaul - Remove Approvals tab from Configure (moved to header bell) - Remove theme switcher from Configure header (use main settings only) - Avatar: replace 10-icon grid with pencil edit button + popover picker (click-outside to dismiss, 5-col grid, scale-up on selected) - System prompt templates: 8 → 16 battle-tested templates organized by category (Engineering / Research / Content / Ops / General) New: Architect, DevOps/SRE, Security, Competitive Intel, Copywriter, Content Strategy, Product Manager, Planner (rewritten) - Template display now grouped by category with section labels - Clean up: remove ApprovalsPanel import, dead pendingApprovalCount var * redesign: avatar-focused agent cards with inline edit mode - Cards now show: large centered avatar (64px), name, model chip, role, prompt preview - Pencil button (top-right) toggles inline edit mode in place - Edit mode: card spans 2 cols, shows name/model/role inputs + system prompt + templates - Close via X button or Done button at bottom - Avatar swap button appears on avatar in edit mode → opens 5-col picker popover - System prompt: collapsed = 2-line preview; no prompt = '+Set system prompt' CTA - Grid: 2 cols → 3 cols → 4 cols responsive (vs previous 1→2) - Add Agent card matches new style with dashed border * feat: template toggle/deselect, card design on teams+API keys, expanded edit layout - Prompt templates now toggle: click active template = deselect (clear backstory) - Custom button: violet pill, highlights when prompt doesn't match any template - Clear button appears whenever backstory is non-empty - Expanded agent card: col-span-full (full row width) - Edit form: 3-col grid for Name/Model/Role, system prompt full-width below - Teams saved configs: same avatar-card design (centered icon, name, member chips, Load/Delete footer) - Empty state: save CTA card - Grid: 2→3→4 cols responsive - API Keys connected providers: centered identity cards (2-letter icon, provider name, active dot, model count) - Grid: 2→3→4→5 cols - Per-provider accent color * refactor: teams/api-keys enterprise overhaul + wizard Teams: - Remove 'Current Team' TeamPanel (redundant with Agents tab) - Quick-Start templates moved to collapsible <details> section at bottom - Saved teams at top with active badge, load/delete footer buttons - Matches agent card aesthetic throughout API Keys: - Remove gateway status row entirely - Add Provider → 2-step visual wizard - Step 1: provider tile grid (all known providers + Custom) with checkmark on already-added - Step 2: API key input + optional model select + Connect button - Back link to return to Step 1 - Connected Providers section header simplified (count + total models, Refresh icon button) - Gateway status removed from this page * feat: wizard popup modals for agents, teams, and providers Agents: - Pencil now opens AgentWizardModal (popup, not inline) - Modal: avatar w/ swap picker, name/model/role row, system prompt w/ template categories (toggle to deselect), textarea - Remove Agent button in modal footer - Cards simplified: clean identity cards only (avatar, name, model, role, prompt preview) Teams → My Teams: - Renamed 'Saved Teams' → 'My Teams' - Save button → + New Team button → opens AddTeamModal - Step 1: choose current config or quick-start template - Step 2: name the team → Create Team - Quick-start templates live inside this modal - Team cards: pencil in top-right → opens TeamWizardModal - Edit name, view agents, Load/Delete, Active indicator - Edit button in card footer as secondary path API Keys: - Provider cards: pencil in top-right → opens ProviderEditModal - Shows provider branding (emoji + name + description) - Lists active models - Update API key field (optional) - Default model picker - Provider cards now use PROVIDER_META for emoji icons + descriptions (Anthropic 🟠, OpenAI 🟢, DeepSeek 🐋, Ollama 🦙, etc.) New file: src/screens/gateway/components/config-wizards.tsx WizardModal, AgentWizardModal, TeamWizardModal, AddTeamModal, ProviderEditModal, PROVIDER_META * feat: real provider logos, team icon picker, backdrop click to close, cleaner teams/providers UX - Fix WizardModal: backdrop onClick closes modal, panel stopPropagation prevents bubble - Add ProviderLogo component (SimpleIcons CDN with branded hex colors + letter fallback) - Use ProviderLogo in connected provider cards and ProviderEditModal header - TeamWizardModal: full agent-wizard-style header (large icon, name, count) - Team icon picker: 40-emoji grid popup with pencil button on team avatar - SavedTeamConfig: add optional icon field, persisted to localStorage - onRename now properly updates teamConfigs state (was only setting teamConfigName) - onUpdateIcon wired to update teamConfigs per-config icon - Remove Quick-Start Templates <details> from main Teams page (now only inside + New Team wizard) - Team cards display saved icon instead of hardcoded 👥 - ProviderEditModal polished to match agent/team wizard style * feat: Add Provider popup modal, Add Agent button, Activate teams, logo fixes - Add Provider: move inline wizard into WizardModal popup (same design language as agent/team wizards) - Add Provider: orange '+ Add Provider' button in Connected Providers header - WizardModal: exported so it can be used directly in layout - Add Agent: orange '+ Add Agent' button added to top-right of Agents section header - Teams: rename 'Load' button to 'Activate' (clearer intent) - ProviderLogo: fix OpenAI hex to 000000 (black, current branding) - ProviderLogo: remove deepseek/fireworks/togetherai/minimax from SimpleIcons (not in slugs.md) - ProviderLogo: emoji fallback for providers without SimpleIcons (DeepSeek=whale, MiniMax=lightning, Fireworks=sparkle, Together=handshake) - ProviderLogo: fix Mistral hex to FF7000 (official orange) - Add Provider tiles: use PROVIDER_META branded colors instead of cycling random colors * feat: wizard-first add agent, provider model picker, dark mode logo fix - Add Agent: wizard-first flow — configure name/model/role/prompt BEFORE agent is added - handleAddAgent now opens wizard with a draft (not yet in team) - 'Done' renamed to '+ Add Agent', 'Remove Agent' renamed to 'Cancel' in addMode - On confirm: draft is added to team with final name; on cancel: discarded - Avatar picker fully functional for draft agents - ProviderLogo: remove hex from CDN URL to avoid black-on-dark rendering issue - ProviderLogo: dark:invert for logos with very dark brand colors (OpenAI, Ollama, xAI) - PROVIDER_COMMON_MODELS: curated model lists for all major providers (Anthropic, OpenAI, Google, DeepSeek, Mistral, Groq, Cohere, etc.) - ProviderEditModal: shows curated models when gateway hasn't loaded models yet - Add Provider step 2: shows curated model picker for all known providers - PROVIDER_COMMON_MODELS exported so it can be used in layout and elsewhere * fix: unique team icons, dual-src logos for dark mode, remove Refresh btn - AddTeamModal: auto-picks a unique icon on open (pickUniqueTeamIcon picks randomly from icons NOT already used by existing teams; falls back to full pool if all icons are taken) - AddTeamModal: receives existingIcons[] from layout so it knows which icons are already in use - ProviderLogo: dual-src approach for dark mode — dark brand logos (openai, ollama, xai) get a white /ffffff variant shown only in dark mode via 'hidden dark:block'; the brand-color version has 'block dark:hidden' Works reliably without CSS filter tricks - Connected Providers header: removed Refresh button (keep only + Add Provider) - Add Agent: wizard-first flow already in place from previous commit * feat: wizard flow optimization + overview cards (team, missions, cost) * feat: overview — virtual office hero + 3 info cards below * fix: overview layout — office contained full-width, cards below with proper spacing * fix: overview — office expanded to 420px focal point, cards below * fix: overview — office flex-fills available height, cards row anchored below * fix: critical QA — conditional tabs, duplicate SSE, pause button, team edit agent management * fix: team edit — wire availableAgents from team state so add/remove agents works * feat: team edit — star active toggle, +/× agent UX, specialty description field * feat: team edit — star active toggle, +/× agent UX, specialty description field * fix: agent wizard auto-resize textarea on template select; team wizard add-agents divider + scroll hint * feat: overview widgets — wire active team, mission history, usage data to live agent hub state - Card 1 (Active Team): Already properly wired with live data from team state - Shows team name, icon, agent count - Lists all agents with model badges and status dots - Switch Team button navigates to Configure → Teams tab - Card 2 (Recent Missions): Now merges data from TWO sources - missionReports (stored mission reports from completed missions) - missionHistory (local checkpoints from mission-checkpoint.ts) - Unified data structure with name, goal, agent count, duration, success rate - Shows last 4 missions sorted by completion time - View All → navigates to Missions tab - + New Mission → navigates to Missions tab - Live mission indicator when mission is running - Card 3 (Usage & Cost): Already properly wired with live data - Shows today's sessions, tokens, estimated cost - Live mission cost indicator when mission is running - Provider breakdown from active team models - Today filter aggregates from completed reports + live mission tokens All data now flows from live Agent Hub state with no empty states when data exists. * feat: theme consistency — add bg-surface and text-ink overrides for all 3 enterprise themes - Paper Light, Ops Dark, Premium Dark now override bg-surface → --theme-bg - Paper Light, Ops Dark, Premium Dark now override text-ink → --theme-text - Ensures components using bg-surface/text-ink respect the active theme - Completes theme system consistency across sidebar, nav, layout, pages * fix: remove all TS6133 unused locals — dead code cleanup in agent-hub-layout * feat: agent click → editor, unique agent names, 3-step team wizard * fix: preserve live output history on close; add steer agent modal + retry spawn button * feat: mission maximize panel — full detail view, steer/pause from modal, office click wires to maximize * fix: live feed history persists on hide/show; mission auto-completes when all agents done * fix: restore checkpoint restores team + opens mission wizard instead of silently disappearing * fix: restore checkpoint TS error; agents tab shows all agents across all team configs * fix: task auto-completion on agent done + checkpoint save; agents grid shows global pool * fix: custom provider baseUrl/apiType sent to gateway; provider edit saves; re-run button on completed missions * feat: add AgentHubErrorBoundary — crash protection for render exceptions * fix: mission pause/resume propagates to all agent sessions via handleMissionPause * fix: restore checkpoint opens new mission modal at launch step instead of legacy wizard * feat: kill agent button; remove provider with confirmation * feat: desktop agent output panel — slides in from right when agent selected * feat: archive button on review missions; auto-complete safety net via terminal state detection * fix: mission state sync, task progress, agent spawn reliability, token display Bug 1 (State desync): Mission cards stayed in Running column after completion - Added setMissionActive(false) in running→stopped transition useEffect - Ensures card moves to Review column when mission completes Bug 2 (Task progress stuck at 0%): Progress never updated after mission completed - Added buildMissionCompletionSnapshotRef to capture fresh snapshot - SSE auto-complete and safety net now capture snapshot BEFORE state change - Prevents stale closure from missing completed task statuses Bug 3 (Agent spawn failures): Only first agent spawned, others rejected - Changed friendlyId from 'hub-{name}-{suffix}' to pure UUID - Gateway was parsing agent name from key and rejecting unknown agents - Added systemPrompt with agent role/goal/backstory to session creation - Sessions endpoint now accepts and forwards systemPrompt to gateway Bug 4 (Negative token count display): Showed -178,993 tok - Added Math.max(0, tokenCount) guard when reading session.tokenCount - Gateway returns negative values for cache accounting, now clamped to 0 * fix: agent spawn model resolution, isolate sessions from Discord channel, task progress Issue A (model): Sessions.ts now does model patching as a separate sessions.patch call (matching openclaw sessions_spawn pattern) to decouple session creation from model assignment. Model errors no longer silently cause the whole spawn to use gateway defaults without notice. Issue B (Discord channel association): The root cause was using a bare UUID as the session key when calling sessions.patch. The gateway was resolving bare UUIDs against the current operator session context (discord:g-...), linking spawned sessions to the Discord channel. Fix: use 'agent:main:subagent:<uuid>' key format which creates a truly isolated subagent session. Also added a guard in spawnAgentSession to never reuse channel/discord sessions by label match. Issue C (task progress stuck at 0%): Two fixes: 1. After successful spawn, immediately set agent status to 'active' (not waiting for the 5s poll) so SSE streams open before the agent starts processing. 2. When dispatchToAgent throws (e.g. bad session), mark tasks as done + agent status as error + add to sessionsDone set so mission can auto-complete rather than hanging at 0/N progress forever. * revert: restore hub-{name} session key format, remove broken agent:main:subagent prefix * docs: session handoff, state files, screenshots for visual upgrade sprint * feat: timeline mission view, sunset-brand theme, visual upgrade * feat: wire MissionTimeline into Active Mission tab, fix Overview stat cards * fix: reactive agent output lines — MissionTimeline live output now updates in real time * fix: wire MissionTimeline live output to AgentOutputPanel SSE — same stream as right panel * fix: Agent Hub overview sizing — rounded-2xl, p-4, max-w-7xl responsive grid, gradient bg, progress bar wired * fix: office card gutter matches widget cards — same max-w-7xl px-3 sm:px-4 wrapper * fix: office card explicit h-[520px] so PixelOfficeView renders — compact mode needs concrete height * fix: office fills viewport with flex-1, widgets shrink-0 at bottom * fix: increase spacing between office and widget cards (mt-4 → mt-8) * feat: missions tab 1:1 design match — colors, typography, cards, timeline, live feed * feat: missions tab matches Configure design — rounded-2xl cards, orange accent bars, Tailwind colors, shared tab style * feat: missions v2 — segmented tabs, history cards with status borders, live feed card, checkpoint card, spacious empty states * fix: P0+P2 logic bugs — stale space key, dispatch false-success, optimistic state, event types, history failed * fix: dark mode coverage, timeline labels, SSE retry, theme-color meta, splash theme init * fix: dark mode coverage in agent-hub mission area, steer modal, kill button * fix: auto-navigate to Active Mission tab on launch, guard missionActive reset * feat: mission completion modal, remove auto-open output panel and live feed * feat: active mission pause/steer/stop controls, fix completion report content and timing * polish: align header buttons, mission sub-tab segmented control, stat cards, recent missions list * feat: soft pause — steer-based pause/resume, replaces broken gateway RPC * polish: fix text bleed in recent missions, global card/label/spacing consistency pass * feat: active mission layout overhaul — progress header, bounded timeline, streaming overflow fix * feat: rich completion report modal — markdown rendering, artifacts, download button * feat: history tab overhaul — filters, redesigned cards, View Report wired to rich modal * fix: live output retention 8→200 lines, auto-expand active agent, keep overview on agent click * feat: wizard team descriptions, Switch Team popup modal, history list view * feat: replace processType badge in office view with New Mission button * fix: revert switch-team modal, remove agent guard, active mission viewport fit, live output always visible * fix: office agent click navigates to active mission, checkpoint restore opens wizard, embed AgentOutputPanel for live output * fix: checkpoint restore passes goal directly to openNewMissionModal (bypasses React batching) * fix: keep active mission visible after completion, show Complete badge, hide controls when done * fix: agentSessionMap type allows null values in MissionTimeline * fix: compact agent cards in active mission (one-screen fit), wire SSE output for reports * fix: add onLine callback to AgentOutputPanel, hidden capture panels for report content * remove: live feed panel from active mission tab (accessible via header button) * fix: FeedEventType 'agent'→'system' for completion toast * fix: fetch real session history at completion for report content — actual agent findings now captured * polish: unify agent status labels — Ready→Idle, Stopped→Idle, Spawning→Starting across components * feat: kanban task board — drag-and-drop columns, list/kanban toggle, task detail panel * feat: memory editor — inline edit mode, write API, unsaved changes guard * feat: agent @mentions in mission wizard — cursor-tracked autocomplete, ↑↓/Enter/Esc, smart placement * feat: office visualization templates — Grid/Roundtable/War Room layouts, animated transitions, localStorage persistence * fix: memory browser light mode — replace hardcoded dark colors with light/dark: variants throughout * fix: light mode — tasks-widget, costs-screen, metrics-widget dark: prefix audit * fix: dashboard light mode + layout cleanup — all widgets dark: prefixed, remove TokenUsageHero+QuickActions from desktop, slim default widgets * fix: dark mode toggle syncs data-theme attribute — prevents paper-light !important vars overriding dark: classes * feat: restore TokenUsageHero on desktop, remove metric cards row, agent hub header matches dashboard style * polish: agent hub header — inline title+subtitle, md:px-5 md:py-3 responsive padding, match dashboard spacing exactly * polish: agent hub header icon-only controls — remove Approvals/Live View text labels, group into single pill (📡+🌙+?), match dashboard compact style * polish: SystemGlance — merge duplicate HEALTHY badges, bordered stat cards, move +Widget/Reset controls inside card footer * polish: agent hub header margins match dashboard — mx-4 md:mx-6 md:mb-5 (was mx-3) * fix: GlanceCard remove backdrop-blur (bleed fix), widget controls button parity — both ghost style * feat: normalize all page containers — min-h-full bg-surface px-4 md:px-6 pt-5 md:pt-8, max-w-[1200px] mx-auto * fix: logo gradient ID collision (useId per-instance), tab nav px-4 md:px-6 matches header margins, tabs fill full width evenly * fix: page container audit — activity/providers/debug max-w-[1200px], agent hub header no shadow/mb, tab nav solid bg + mt-2 gap * feat: full design QA — unified max-w-[1600px] container on agent hub, dashboard-style header cards on all 9 sub-pages, consistent max-w-[1200px] inner content * feat: accent color routing (orange→accent-* across 13 files), settings dialog 2-panel layout, remove Editor section, trimmed Advanced/Chat sections, data-accent persistence fix * feat: chat streaming — Telegram-style bouncing dots, pulsing cursor, smooth text transition, user bubble accent color * fix: complete accent-* routing on agent hub (orange→accent everywhere except brand bars), token usage bar contrast track, TS LoadingIndicator cleanup * fix: missions tab dark mode — outer bg dark:bg-neutral-950 gradient, checkpoint banner dark:accent-900/15, sub-tab bar dark border, 9x card-top gradients orange→accent-* * feat: agent hub — remove Overview tab, Active Mission+History+Configure tabs, office layout selector behind pencil icon * feat: chat streaming blank fix, live tool call UI, exec approval banner in chat * fix: restore Office tab as Overview, remove cramped 340px header, proper full-height tab layout * fix: restore Overview tab labels (Overview/Missions) and h-full height to match last working state * feat: smooth streaming text animation + thinking phase indicator (Telegram-style) * fix(agent-hub): codex provider map, nav history cleanup, overview new mission wizard * fix(agent-hub): agent dispatch route + mission launch preflight * fix(agent-hub): dispatch hardening, overview wizard defaults, status stability * feat(agent-hub): streamlined mission flow + enterprise report quality * feat(agent-hub): overview launchpad, 3-step wizard, active command center, history viewer * fix(agent-hub): restore overview office+widgets and keep mission-only changes * fix(agent-hub): missions default active, correct report binding, live output polish * fix(agent-hub): sanitize mission report synthesis and remove meta-output noise * feat(agent-hub): overview polish, streamlined controls, agent quick-edit popup, strict report scoping * fix(agent-hub): stabilize output panel height and tighten mission report quality * fix(agent-output): persist session output across panel close and enforce scrollable compact view * fix(chat): auto-compress image attachments + deduplicate messages * fix(chat): show live tool call pills and streaming text during multi-step responses * feat(agent-hub): show external chat sub-agents in office view * fix(chat): show live tool activity during thinking via activity stream * fix(agent-sidebar): compact cards, clean expanded state, maximized view polish * fix(agent-sidebar): refine compact card density and prevent sidebar clipping * fix(agent-card): restore name/avatar/role in compact card view * fix(dashboard): improve widget card contrast and accent colors * feat(chat): inline session name editing on click * feat(chat): support .md/text file attachments + improve image error messaging * feat(sidebar): hide/show toggle for History and Browser sections * fix(chat): proper nonce-based dedup — replace optimistic on SSE match * fix(chat): grace period on thinking indicator prevents blank gap * fix(sidebar): eyeball hides section content completely, no 'hidden' text * revert(sidebar): remove eyeball hide toggle — not working as intended * remove(sidebar): drop History section + clean up unused import * fix(chat): open activity EventSource on mount — eliminates tool pill connection latency gap * feat(agent-hub): add PC1 distilled model presets and loop team template * feat(chat): sync dot, auto-rename, copy code blocks, mobile context bar, scroll fix, ⌘⇧M shortcut * feat(sidebar): move usage meter to sidebar — compact mini bars * feat(sidebar): enhance compact usage meter — all stats, provider picker, set default * fix(agent-card): add title tooltip so full name shows on hover when truncated * feat(sidebar): merge orchestrator card + usage into one seamless card * fix(sidebar): streamline usage meter — 2 bars, fix truncation, inline provider * feat(sidebar): usage provider rotation, reset hints, agent card expand polish * feat(sidebar): usage provider rotation, reset hints, agent card expand polish * fix(sidebar): agent name, reset hint right-aligned, usage padding * feat(chat): hover actions, empty state, tool result collapse, system msg style, sub-agent card polish * feat(chat): remove delete message button — unnecessary * fix(chat): remove duplicate hover copy button and retry button — keep inline MessageActionsBar only * fix(chat): streaming ID, attachment type rendering, auto-rename dedup, failsafe timer, tool calls always visible * fix(dispatch+dashboard+sidebar): correct agent RPC, real health probes, metrics footer, theme toggle, session refresh, model default * fix(chat): base64-encode text file attachments before send — fixes .md/.txt not sending * fix(chat): inject text file content into message body — guarantees .md/.txt reaches the model * feat(chat): immediate processing indicator, elapsed timer, connection status — eliminate dead air * fix(chat): fill thinking→text gap with bouncing dots — no more blank space mid-stream * fix(chat): remove 'Connected' status bar from chat header * feat(approvals): global exec approval toast overlay — shows on all screens * fix(ui): dashboard card contrast + dark mode hover states sweep * fix(p0): gateway approvals API routes + server-side event store - src/server/exec-approval-store.ts: singleton subscribes to gateway exec.approval.requested/resolved events, maintains in-memory pending list - GET /api/gateway/approvals: returns {ok, pending, approvals} - POST /api/gateway/approvals/:approvalId/:action: proxies to exec.approval.resolve RPC (approve=allow-once, deny=deny) Fixes P0-1 from QA-REPORT-agent-hub.md — exec approval toast and approvals bell/count now have working server-side backing. * fix(p1): enter-to-send, invalid tailwind classes, costs chart theme - chat-composer: Enter sends (Shift+Enter = newline), Cmd+Enter still works Updated placeholder hint text accordingly - Fix 6x invalid dark:hover:bg-white/10/10 → dark:hover:bg-white/10 (chat-composer, quick-actions-row, squad-status-widget, glance-card) - costs-screen: chart colors now theme-aware (light vs dark mode) CartesianGrid, axes, Tooltip all respect current theme * fix(p0/p1): terminal SSE event name, cron auth guards, cron form schedule+payload types * fix(p1): settings theme persistence, enterprise picker mobile, rename dialog ref, sidebar hover dedup * fix(chat): double-send bug — add type=button to send button, prevents form onSubmit + onClick double-fire * feat: system metrics footer hidden by default w/ settings toggle; fix chart bar contrast (white candles → neutral-300/700) * fix(p0): auth guards on /api/ping and /api/sessions POST/PATCH/DELETE * fix: terminal SSE event names P0, cron auth P0, settings theme persist, enterprise picker on settings page, rename dialog controlled state, wizard step guard, agent last-seen timestamp * fix: P0 auth guards on 8 routes, dashboard error boundaries, toast spam; P1 CPU init, services dedup, usage-analytics route, KpiCard light mode, stop button during stream * fix(chat): prevent duplicate sends — submittingRef guard + form preventDefault * fix(theme): dark mode sweep — theme tokens, mission labels, dispatch error state, splash theme variants * fix(chat): remove duplicate keyboard send triggers * fix(browser): remove dead code and null stubs * feat(cron): schedule type + payload type selectors * fix(nav): Gateway → Agents routes to registry view, not Agent Hub * fix(chat): match input box border/bg to theme, remove gradient bleed * Revert "fix(chat): match input box border/bg to theme, remove gradient bleed" This reverts commit 2557f78ce31b8b5cceed1ad33dab6ee2f9458b4f. * fix(mission): restore agent-hub-layout to pre-Codex state — revert broken missionStateRef + dispatch error changes * fix(dispatch): remove sessions.patch no-op that was blocking sessions.send * fix(mission): restore mission control logic from v0.visual-sprint-complete (62f775e) + pc1 type fixes * fix(mission): restore 66ef2f3 UI (full sizing+submenus) — pre-dates all broken logic changes * fix(mission): hard-revert to 62f775e working mission logic + pc1 type fixes * fix(mission-ui): dark mode, accent tokens, segmented tabs, warden controls * feat(chat): compaction in-progress amber banner * fix(gateway): agents no sidebar, sidebar collapsible, nodes RPC, consistent headers * feat(mission-control): UI cleanup - quick launch bar, example missions, button fixes - Added quick-launch input bar on Overview tab for fast mission creation - Missions overview empty state now shows example mission chips for one-click launch - Fixed 'View Active Mission' button color from red to accent (not destructive) - Reduced margin between office view and cards for tighter layout - All new elements support dark mode * fix(mission-control): remove duplicate selectedReport modal, keep polished version Removed the older, less-styled selectedReport modal that lacked dark mode support, proper accent gradient headers, agents list, and artifact links. The new modal added in the previous commit now serves as the single report viewer with full dark mode, stat cards, agent badges, artifact preview links, and consistent styling. * feat(mission-control): make recent missions clickable to view reports - Overview tab recent missions cards now open the report modal on click - Missions overview sub-tab recent missions also clickable - Added hover states and cursor pointer on clickable items - Dark mode badge colors fixed for status indicators * fix(mission-control): prevent premature mission completion on agent questions The SSE 'done' event fires when an LLM finishes generating ANY response, including clarifying questions. Previously this was treated as 'agent completed its work', causing missions to auto-close when agents asked questions like 'let me know if you meant...' Changes: - Add classifyAgentTurnEnd() heuristic to distinguish completed work from questions/waiting-for-input (checks for completion markers, question endings, and message length) - Add 'waiting_for_input' status to AgentWorkingStatus and AgentSessionStatusEntry types - SSE done handler now classifies the final message: if agent is asking a question, set status to waiting_for_input instead of marking done - Safety net auto-completion skips when any agent is waiting_for_input - Session poller preserves waiting_for_input status (doesn't override) - Steer/approve handlers clear waiting_for_input when user provides input - Add extractTextFromMessage() helper for parsing chat message objects * feat(mission-control): redesign missions tab as unified list/log view Replace the three-sub-tab layout (Overview/Active/History) with a single unified mission list with filter bar: - Filter tabs: All | Running | Needs Input | Complete | Failed - Each mission = one row with: status badge (color-coded), title, agents (avatar stack), duration, time ago, action button - Running/needs_input missions show inline expansion with: - Progress bar - Agent status rows with last output - Warden controls (Resume/Pause/Stop) - Quick links to Agent Output and Event Log panels - 'Needs Input' entries have amber ring highlight + pulsing badge - Clicking completed missions opens the report modal - Clicking running missions opens the agent output panel - Empty states with contextual messaging per filter Status badge colors: blue = running, amber = needs_input, green = complete, red = failed * fix(mission-control): wire agent output into report + fix duplicate SSE Bug 1 - Report shows 'No output captured': - Main SSE chunk handler now calls captureAgentOutput() so streaming text populates agentOutputLinesRef (previously only message events did, which may not fire or may lack assistant role) - Added line-level dedup in captureAgentOutput to prevent duplicate lines when both chunk and message events deliver the same content Bug 2 - Live feed output duplicated 3x: - Desktop AgentOutputPanel now only renders when !isMobileHub, preventing two simultaneous panel instances opening separate SSE connections for the same session - Mobile AgentOutputPanel uses conditional rendering (unmounts when hidden) instead of display:none, properly closing SSE on hide - Added content-based dedup in appendAssistantMessage (checks last 10 messages) and appendBoundedMessage to guard against SSE replay on reconnect producing duplicate entries * enterprise polish: remove Live Feed, deduplicate controls, fix report timing, clean list layout - Remove Live Feed panel entirely — right panel is now Live Output only - Remove Live View toggle from header - Remove Stop Mission button from Missions tab header (controls only on expanded card) - Remove Start/Pause/Stop/Budget from sidebar dock (controls consolidated to expanded card) - Expanded card now has Resume/Pause/Stop + Live Output button - Right panel: wider (w-96), terminal-style dark bg, agent selector tabs, model+token count in header - Auto-open Live Output panel when mission starts (instead of Live Feed) - Fix report timing: increase done→report delay from 2s to 5s, safety net from 4s to 6s - Capture 20 output lines per agent in report (was 4) - Mission list: add #shortID hash to each entry for disambiguation - Mission list: dedup entries with same ID (history+reports overlap fix) - Active mission card: blue ring highlight for running state - Empty states: contextual messages per filter tab - Agent count shown in mission row - Mission row action: Live Output button (not Stop) for running missions - Status badge colors standardized: blue=running, amber=needs_input, emerald=complete, red=failed * clean up dead Live Feed state, refs, and effects * terminal-style Live Output panel: dark bg, monospace, timestamps, agent tabs - AgentOutputPanel: dark terminal theme (neutral-950 bg, monospace font) - Timestamps on every message line (HH:MM:SS format) - Tool calls: dark border, muted colors - User messages: blue-tinted for contrast - Streaming cursor: emerald-400 - Disconnected banner: dark theme amber colors - Outer panel: wider (w-96), dark header with agent name + model + token count + status - Agent selector tabs for multi-agent missions - Compact mode passed from parent (no duplicate inner header) - Empty states use dark theme colors * standardize agent status colors: paused=blue to match enterprise color scheme * dark terminal task list in compact mode, status-colored dots * fix(mission-control): text colors + report content quality - Fix text-neutral-700 in agent output panel header (unreadable on dark bg) → replaced with text-neutral-400 for modelId badge and idle status - Fix duplicate 'Mission Mission' in report header → strip leading 'Mission' from goal text in report generation - Strip metadata lines (Session ended, Mission complete, etc.) from per-agent summaries — keep only actual content - Increase agent output buffer from 8 to 200 lines for richer report capture - Smart truncation for long output (keep intro + conclusion, ... in middle) - Auto-detect artifacts from agent output: - Fenced code blocks → code artifacts - URLs → link artifacts - Markdown tables → table artifacts - Merge auto-detected artifacts into stored report + report text - Format per-agent summary as markdown (preserve tables, bullets, code blocks) * fix(mission-control): terminal colors + completion flow + card preview 1. Dark mode text colors: comprehensive audit and fix of all hardcoded light-theme colors (text-neutral-700/800/900, bg-white, bg-neutral-50) that lacked dark: variants. Added dark mode counterparts throughout OfficeView, HistoryView, wizard forms, and mission detail overlays. 2. Mission completion flow regression: session status poller was overriding SSE 'done' handler's idle status with 'active' (within 30s window), preventing the safety-net auto-complete from detecting terminal state. Fix: poller now checks agentSessionsDoneRef and preserves 'idle' for agents that have sent their done event. Also added proper cleanup in the missionState transition effect (clear tasks, session maps, refs) so Stop button disappears and checkpoint is archived on auto-completion. 3. Card preview text: added extractPreviewLine() that filters out raw command flags, code snippets, and noise lines, returning the last meaningful prose line for human-readable preview. Falls back to 'Agent working...' when no prose is found. * fix(mission-control): native theme output panel + auto tab switching - Agent output panel: replaced all forced dark terminal classes (bg-neutral-950, bg-neutral-900, text-neutral-300, etc.) with --theme-* CSS variables that respect light/dark mode. Panel now matches the rest of the UI. - Right-side output panel wrapper: same treatment — removed hardcoded dark backgrounds and replaced with theme-aware classes. - Auto tab switching: mission filter tab now auto-switches on state changes: - Mission starts → 'Running' tab - Agent needs input → 'Needs Input' tab - Mission completes → 'Complete' tab (+ report modal, already existed) - Mission aborted/failed → 'Failed' tab * fix(mission-control): align header with page container * fix(mission-control): output pipeline + pause + steer button + overview new mission Issue 1: Output panel now gets sessionKey immediately as each agent spawns (incremental setAgentSessionMap in ensureAgentSessions), and always picks first agent + opens panel on mission start, including fallback to first team member. Issue 2: Pause handler now gracefully handles 404/not-implemented errors from gateway — shows warning toast instead of crashing. handleMissionPause wrapped in extra try/catch safety. Issue 3: Added Steer button (✦) to mission warden controls bar and per-agent status rows. Shows when mission is running or agent needs input. Opens existing steer modal targeting the active/waiting agent. Issue 4: Overview 'New Mission' button and Quick Launch bar now open the mission wizard modal on the Missions tab (openNewMissionModal lifted to component scope). On wizard submit, auto-switches to Missions → Running. * fix(mission-control): SSE stream filter + dedup guard + header cleanup + compaction banner Issue 1 — SSE stream never opens: - Changed activeAgentIds filter from requiring agentSessionStatus === 'active' to only requiring agentSessionMap[id] != null. Streams now open as soon as a sessionKey is known, regardless of status (spawning/ready/active/idle). - Removed agentSessionStatus from useEffect dependency array since it no longer gates stream creation. SSE dedup — triple-subscribe regression: - Added content-tail dedup guard in captureAgentOutput: if the buffer tail already ends with the incoming text, skip the append entirely. - Added externalStream prop to AgentOutputPanel — when true, the panel skips opening its own EventSource. Both AgentOutputPanel instances in AgentHub now pass externalStream, preventing duplicate SSE connections per sessionKey. The parent useEffect is the single source of truth for SSE. Issue 2 — Header card misaligned: - Removed card styling (border, bg, shadow, rounded) from the Mission Control header. Now a plain flex row with px-1 py-2 matching other screen headers. Issue 3 — Compaction notification: - Added compactionBanner state with auto-dismiss after 8s. - Detects compaction keywords in SSE stream text via handleUpdate. - Shows amber banner (matching chat screen pattern from 31b3628) between the header and filter bar with dismiss button. * fix(agent-hub): align header + tab bar to max-w-[1200px] matching content width * feat(mission-control): optimize report generation - summary + findings + outcome - Add Executive Summary section extracted from primary agent prose output - Add Key Findings section (top 5 bullets from structured content) - Add Mission Outcome label (Complete/Partial/No output/Aborted) - Improve smartTruncate: keep first 15 + summary sections + last 5 lines - Enhance artifact detection: numbered lists, commands, reference sections * fix(agent-hub): max-w-7xl header + wire New Mission button on overview * fix(agent-hub): uniform max-w-[1600px] matching dashboard width * fix(mission-control): live output panel shows agent data from parent state Option A: pass agentOutputLines[agentId] directly as outputLines prop to AgentOutputPanel. When outputLines is provided and non-empty, the panel renders those lines directly instead of its internal empty messages state. The panel was showing 'Waiting for response...' because externalStream=true correctly skipped opening a 2nd SSE connection, but nothing ever fed data into the panel's own messages state. The parent already has all the output in agentOutputLines (proven by the mission card preview working). Passing it down as a prop is the simplest, most reliable fix. - Added outputLines?: string[] prop to AgentOutputPanelProps - Render outputLines path takes priority over internal messages state - Falls back gracefully to internal SSE messages when outputLines absent - Applied to both desktop sidebar and mobile bottom sheet instances - 0 TypeScript errors * fix(agent-hub): match header padding px-3 sm:px-4 to card content edges * fix(agent-hub): mission wizard modal fixed-position so it opens from Overview tab * fix: agent hub header width + wire New Mission button on Overview * fix: align agent hub header width + wire overview new mission button * fix: constrain orange accent bar width + always-open New Mission wizard * security: auth guards on 10 API routes + fix wildcard CORS on browser proxy/stream * draft: v3.0.0 README — app install, Tailscale, desktop/cloud sections, star history, ETH donate [DO NOT PUSH - awaiting Eric review] * chore: remove raw screenshot staging folders * docs: comprehensive v3.0.0 CHANGELOG + updated SECURITY.md * docs: expand v3.0.0 CHANGELOG — chat streaming, sidebar, exec approval, kanban, settings, @mentions, theme routing, UI polish * fix: hoist mission launch/draft/budget fns to outer scope (crash fix) + dashboard-style header card * fix: dedup chat messages on paste/attach (BUG-4) + mission pause state sync (BUG-5) * fix: restore sessions.send→chat.send fallback in agent-dispatch (mission no-output crash) * fix: mobile batch — nav glass, chat padding, office card view, sub-header, quick actions, icons (MOB-1-7) * fix: wire agent dispatch to /api/agent-dispatch (BUG-1) BUG-1 is confirmed fixed: - dispatchToAgent() in agent-hub-layout.tsx calls /api/agent-dispatch (not /api/sessions/send) - /api/agent-dispatch endpoint exists at src/routes/api/agent-dispatch.ts - Gateway RPC called with lane: 'subagent', deliver: false - sessions.send→chat.send fallback for gateway compatibility (commit 4bf8760) - Request body shape matched: { sessionKey, message, agentId, idempotencyKey } - npx tsc --noEmit: 0 errors * feat: exec approval modal — SSE-driven, approve/deny, auto-timeout, stacked queue (BUG-3) * feat: cost tracking analytics page — real SQLite data, per-agent breakdown, daily trend (BUG-2) - Enhanced /api/usage-analytics to include per-agent cost breakdowns derived from session keys (agent:main:subagent:xxx → 'subagent') - Added CostAgentRow type and normalizeAgents() for agent aggregation - Hero KPI cards: MTD Total, Projected EOM, Budget Used %, Top Agent - Per-agent horizontal bar chart (recharts) showing spend by agent - Daily cost trend as line chart (30 days) replacing bar chart - Per-model usage table with token input/output mix bars - Session cost breakdown table with agent column and sort controls - Added Line/LineChart to recharts type declarations - 0 TypeScript errors (npx tsc --noEmit) * fix: agent hub — pause steer fix, header cleanup, live output layout, office sizing (opus review) * fix: match agent hub to dashboard style (headers/cards/bg) + fix office fill * fix: mobile UI — glass nav, chat safe area, office cards, widget grid, icons (verified pass) MOB-3/7: Remove isolate + simplify backdrop-blur on mobile nav - Removed 'isolate' class from nav (breaks backdrop-filter in Safari) - Removed 'supports-[backdrop-filter]:' conditional — just apply backdrop-blur-xl directly - Removed 'backdrop-blur-sm' from inner pill div (fighting parent blur) - Result: true frosted glass, bg-white/80 + backdrop-blur-xl MOB-2: Agent hub mobile office → agent cards (verified already correct in 928d975) - 'hidden sm:flex' for desktop office, 'flex sm:hidden' for mobile cards ✓ MOB-4: Chat input safe area (verified correct in 928d975) - translateY lifts composer above nav, pb accounts for safe-area ✓ MOB-5: Dashboard widget 2×2→4-up grid (verified correct in 928d975) - QuickActionsRow removed, grid grid-cols-2 sm:grid-cols-4 widget cards ✓ MOB-6: BotIcon on Agent Hub tab (verified correct in 928d975) ✓ Fix: agent-hub-layout.tsx hero card div left unclosed from a prior uncommitted change — caused TS errors at build time. Added missing </div>. * fix: restore agent hub overview layout from e1b24c8 (office hero, correct widget layout) * fix: session status endpoint — wire real gateway lookup instead of hardcoded active (FEAT-7) * feat: persistent system metrics footer — CPU/RAM/disk/gateway/uptime (FEAT-1) * fix: system metrics footer off by default, toggle in settings (FEAT-1) * feat: provider add/remove gateway restart UX — confirm dialog, restart overlay, auto-reconnect (FEAT-4) * feat: in-app memory browser — list/read/edit memory files, full-text search (FEAT-2) * fix: QA sweep — browser/terminal/cron/files/skills wire-up gaps (FEAT-5) Browser tab: - Fully wired via gateway RPC (status/tabs/screenshot/navigate) - Shows graceful 'not connected' state when gateway lacks browser RPC - No functional gaps — behavior is correct by design Terminal tab: - Fully wired: SSE streaming via Python PTY helper verified working - /api/terminal-stream, /api/terminal-input, /api/terminal-resize, /api/terminal-close all functional - Real PTY with xterm.js confirmed live Cron tab: - Fully wired: list/create/run/delete/toggle all verified live against gateway - Added nextRunAt field to CronJob type (was computed in API, missing from type) - Wired nextRunAt display into CronJobCard component File Manager tab: - Fully wired: list/read/write/mkdir/rename/delete/upload all functional - Auth guards already in place (SEC-1 confirmed) - Removed unused requireJsonContentType import from files.ts Skills tab: - FIXED: GET /api/skills had no auth check (POST had one, GET did not) - Added isAuthenticated guard to GET handler - Added requireJsonContentType CSRF guard to POST handler - install/uninstall/toggle all verified functional TypeScript: 0 errors (noEmit, strict mode) * feat: dashboard revamp B/C/D — dark mode polish, WebSocket origin fix, widget edit placement (FEAT-6) B4: Remove hardcoded localhost:3000 WebSocket origin — derive from gateway URL (gateway.ts + gateway-stream.ts) C2/C3: Enterprise visual polish - Page bg: dark:bg-[var(--theme-bg)] for consistent themed dark backgrounds - All cards: dark:border-neutral-800 dark:bg-[var(--theme-panel)] pattern - Updated: header, widget-shell, glance-card, system-glance, now-card, token-usage-hero, collapsible-widget - Consistent rounded-xl + border treatment across all dashboard surfaces D1: Widget edit controls moved from mobile header to inline row above widget grid — keeps the top bar clean Also: added missing requireJsonContentType() to rate-limit.ts (fixes 4 tsc errors), fixed unused variable in provider-wizard.tsx * security: full audit pass — auth gaps, input validation, rate limiting, info leak, CSRF (SEC-3) Pass 1 - Auth gaps fixed: - /api/agent-activity — added isAuthenticated guard - /api/cli-agents — added isAuthenticated guard (exposes ps aux output) - /api/context-usage — added isAuthenticated guard (exposes session model/token data) - /api/models — added isAuthenticated guard (exposes configured providers) - /api/provider-usage — added isAuthenticated guard (exposes API usage/costs) - /api/workspace — added isAuthenticated guard (exposes filesystem paths) (events/recent, send, sessions, agent-kill/pause/steer, chat-abort, memory/write, debug/reconnect, cron/*, browser/navigate, session-title, skills, gateway/approvals, tasks/*, gateway-config, gateway-discover, validate-provider — already in HEAD) Pass 3 - Rate limiting on high-RCE endpoints: - /api/update-check POST — 3/min per IP (git pull + npm install) - /api/openclaw-update POST — 3/min per IP (gateway update + restart) - /api/gateway-restart POST — 5/min per IP (service disruption risk) Pass 4 - Info leak audit: - /api/paths, /api/config-get, /api/debug-analyze, /api/context-usage — all confirmed auth-gated Pass 5 - CSRF protection: - requireJsonContentType() helper added to rate-limit.ts - Added Content-Type: application/json check to gateway-restart POST - Other mutating routes already have CSRF checks in HEAD npx tsc --noEmit: 0 errors * feat: workspace file browser — tree nav, preview, edit, markdown render (FEAT-3) * security: Codex SEC-3 pass — rate limiting, auth gaps, CSRF on terminal/browser/update routes * docs: final v3.0.0 CHANGELOG — all features, bugs, security, mobile * ci: fix pnpm→npm, exclude false-positive patterns from secret scan --------- Co-authored-by: Aurora <aurora@MacBookPro.lan> Co-authored-by: outsourc-e <eric@outsourc.e>
…search#33) The scripts/qa/test-redaction.ts file was referenced in CI but never created. The step was added in 31a7062, removed in 051d136, then accidentally reintroduced in 4f848a4. pnpm test (vitest) is the actual test command and is sufficient. Co-authored-by: dontcallmejames <dontcallmejames@users.noreply.github.com>
…ity with NousResearch#33) Ports the standalone plugin's Issue NousResearch#33 race-fix to this legacy in-fork variant so both deployment paths share the same lifecycle hygiene. Same three layered guarantees: 1. cancel_background_tasks() override — mirrors base's clear() behaviour for the parallel TTL state. Reuses base's drain ordering so in-flight handlers' finally blocks see _pending_messages empty and pop their own timestamps via the existing guard. 2. disconnect() — defense-in-depth clear at end of teardown for the direct-disconnect call sites that bypass cancel_background_tasks (gateway/run.py:_safe_adapter_disconnect, error-recovery in connect()). 3. handle_message() — wraps super() in try/finally so any unexpected exception (most relevantly CancelledError propagating up from base.handle_message itself) doesn't skip the post-super cleanup and leak a stamped timestamp into a future invocation. Plus a belt-and-braces clear() at the top of connect() for any path that reuses the adapter without a clean disconnect first. Memory-hygiene fix, not correctness — the existing TTL guard already keys off _pending_messages.get() first, so a phantom _pending_enqueued_at entry can't evict a real later message. The leak matters for long-running deployments that reconnect repeatedly over weeks. Tests: 158 passed (154 prior + 4 new regression in PendingEnqueuedAtCleanupTests). Cross-ref: linxule/hermes-kimi-plugin@268daf1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 4 new direct API-key providers (zai, kimi-coding, minimax, minimax-cn) to the inference provider system. All use standard OpenAI-compatible chat/completions endpoints with Bearer token auth. Core changes: - auth.py: Extended ProviderConfig with api_key_env_vars and base_url_env_var fields. Added providers to PROVIDER_REGISTRY. Added provider aliases (glm, z-ai, zhipu, kimi, moonshot). Added auto-detection of API-key providers in resolve_provider(). Added resolve_api_key_provider_credentials() and get_api_key_provider_status() helpers. - runtime_provider.py: Added generic API-key provider branch in resolve_runtime_provider() — any provider with auth_type='api_key' is automatically handled. - main.py: Added providers to hermes model menu with generic _model_flow_api_key_provider() flow. Updated _has_any_provider_configured() to check all provider env vars. Updated argparse --provider choices. - setup.py: Added providers to setup wizard with API key prompts and curated model lists. - config.py: Added env vars (GLM_API_KEY, KIMI_API_KEY, MINIMAX_API_KEY, etc.) to OPTIONAL_ENV_VARS. - status.py: Added API key display and provider status section. - doctor.py: Added connectivity checks for each provider endpoint. - cli.py: Updated provider docstrings. Docs: Updated README.md, .env.example, cli-config.yaml.example, cli-commands.md, environment-variables.md, configuration.md. Tests: 50 new tests covering registry, aliases, resolution, auto-detection, credential resolution, and runtime provider dispatch. Inspired by PR NousResearch#33 (numman-ali) which proposed a provider registry approach. Credit to tars90percent (PR NousResearch#473) and manuelschipper (PR NousResearch#420) for related provider improvements merged earlier in this changeset.
Adds 4 new direct API-key providers (zai, kimi-coding, minimax, minimax-cn) to the inference provider system. All use standard OpenAI-compatible chat/completions endpoints with Bearer token auth. Core changes: - auth.py: Extended ProviderConfig with api_key_env_vars and base_url_env_var fields. Added providers to PROVIDER_REGISTRY. Added provider aliases (glm, z-ai, zhipu, kimi, moonshot). Added auto-detection of API-key providers in resolve_provider(). Added resolve_api_key_provider_credentials() and get_api_key_provider_status() helpers. - runtime_provider.py: Added generic API-key provider branch in resolve_runtime_provider() — any provider with auth_type='api_key' is automatically handled. - main.py: Added providers to hermes model menu with generic _model_flow_api_key_provider() flow. Updated _has_any_provider_configured() to check all provider env vars. Updated argparse --provider choices. - setup.py: Added providers to setup wizard with API key prompts and curated model lists. - config.py: Added env vars (GLM_API_KEY, KIMI_API_KEY, MINIMAX_API_KEY, etc.) to OPTIONAL_ENV_VARS. - status.py: Added API key display and provider status section. - doctor.py: Added connectivity checks for each provider endpoint. - cli.py: Updated provider docstrings. Docs: Updated README.md, .env.example, cli-config.yaml.example, cli-commands.md, environment-variables.md, configuration.md. Tests: 50 new tests covering registry, aliases, resolution, auto-detection, credential resolution, and runtime provider dispatch. Inspired by PR NousResearch#33 (numman-ali) which proposed a provider registry approach. Credit to tars90percent (PR NousResearch#473) and manuelschipper (PR NousResearch#420) for related provider improvements merged earlier in this changeset.
Adds 4 new direct API-key providers (zai, kimi-coding, minimax, minimax-cn) to the inference provider system. All use standard OpenAI-compatible chat/completions endpoints with Bearer token auth. Core changes: - auth.py: Extended ProviderConfig with api_key_env_vars and base_url_env_var fields. Added providers to PROVIDER_REGISTRY. Added provider aliases (glm, z-ai, zhipu, kimi, moonshot). Added auto-detection of API-key providers in resolve_provider(). Added resolve_api_key_provider_credentials() and get_api_key_provider_status() helpers. - runtime_provider.py: Added generic API-key provider branch in resolve_runtime_provider() — any provider with auth_type='api_key' is automatically handled. - main.py: Added providers to hermes model menu with generic _model_flow_api_key_provider() flow. Updated _has_any_provider_configured() to check all provider env vars. Updated argparse --provider choices. - setup.py: Added providers to setup wizard with API key prompts and curated model lists. - config.py: Added env vars (GLM_API_KEY, KIMI_API_KEY, MINIMAX_API_KEY, etc.) to OPTIONAL_ENV_VARS. - status.py: Added API key display and provider status section. - doctor.py: Added connectivity checks for each provider endpoint. - cli.py: Updated provider docstrings. Docs: Updated README.md, .env.example, cli-config.yaml.example, cli-commands.md, environment-variables.md, configuration.md. Tests: 50 new tests covering registry, aliases, resolution, auto-detection, credential resolution, and runtime provider dispatch. Inspired by PR NousResearch#33 (numman-ali) which proposed a provider registry approach. Credit to tars90percent (PR NousResearch#473) and manuelschipper (PR NousResearch#420) for related provider improvements merged earlier in this changeset.
) When the WebUI's model picker sets the active provider to "venice" (or "crof", "bankr", "cometapi"), the agent's resolve_provider_client() looked up the slug in PROVIDER_REGISTRY, failed to find it, and raised: "Provider 'venice' is set in config.yaml but no API key was found. Set the VENICE_API_KEY environment variable..." VENICE_API_KEY WAS set in env — the failure was because the agent had no idea which env var or base URL to use for "venice" as a slug. PROVIDER_REGISTRY entries for the other OpenAI-compatible aggregators (Z.AI, MiniMax, Mistral, etc.) already existed; Venice/CrofAI/Bankr/CometAPI just hadn't been added in the upstream code. Adds four api_key-auth entries mirroring the existing OpenAI-compat ones: - venice → https://api.venice.ai/api/v1 + VENICE_API_KEY - crof → https://crof.ai/v1 + CROF_API_KEY - bankr → https://gateway.bankr.bot/v1 + BANKR_API_KEY - cometapi → https://api.cometapi.com/v1 + COMETAPI_API_KEY Companion to the WebUI side (PRs #26/#27/#29/#30/#32/#33) which made these providers discoverable in the model picker with their live /v1/models catalogs. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…ning + profile dir perms (0o700/0o600) - Dockerfile: OCI security labels, HEALTHCHECK, non-root safe - docker-compose: no-new-privileges, healthcheck mirroring - entrypoint.sh: chmod 700 on cron/sessions/memories/home/logs/plans - gateway/session.py: enforce 0o700 sessions dir, 0o600 sessions.json - hermes_cli/profiles.py: _ensure_profile_permissions() helper wired into create_profile Resolves security audit findings P1 NousResearch#33 (image hardening) and P1 NousResearch#59 (profile isolation)
- path-to-regexp: 0.1.12 → 0.1.13 (CVE-2026-4867, GHSA-37ch-88jc-xwx2) - picomatch: 2.3.1 → 2.3.2 (CVE-2026-33671, GHSA-c2c7-rcm5-vvqj) - undici: 7.23.0 → 7.27.1 (CVE-2026-1526/CVE-2026-2229/CVE-2026-1528) - serialize-javascript: 6.0.2 → 7.0.3 (GHSA-5c6j-r48x-rmvq, via overrides) Fixes Dependabot alerts NousResearch#37, NousResearch#34, NousResearch#33, NousResearch#32, NousResearch#29, NousResearch#27
Adds 4 new direct API-key providers (zai, kimi-coding, minimax, minimax-cn) to the inference provider system. All use standard OpenAI-compatible chat/completions endpoints with Bearer token auth. Core changes: - auth.py: Extended ProviderConfig with api_key_env_vars and base_url_env_var fields. Added providers to PROVIDER_REGISTRY. Added provider aliases (glm, z-ai, zhipu, kimi, moonshot). Added auto-detection of API-key providers in resolve_provider(). Added resolve_api_key_provider_credentials() and get_api_key_provider_status() helpers. - runtime_provider.py: Added generic API-key provider branch in resolve_runtime_provider() — any provider with auth_type='api_key' is automatically handled. - main.py: Added providers to hermes model menu with generic _model_flow_api_key_provider() flow. Updated _has_any_provider_configured() to check all provider env vars. Updated argparse --provider choices. - setup.py: Added providers to setup wizard with API key prompts and curated model lists. - config.py: Added env vars (GLM_API_KEY, KIMI_API_KEY, MINIMAX_API_KEY, etc.) to OPTIONAL_ENV_VARS. - status.py: Added API key display and provider status section. - doctor.py: Added connectivity checks for each provider endpoint. - cli.py: Updated provider docstrings. Docs: Updated README.md, .env.example, cli-config.yaml.example, cli-commands.md, environment-variables.md, configuration.md. Tests: 50 new tests covering registry, aliases, resolution, auto-detection, credential resolution, and runtime provider dispatch. Inspired by PR NousResearch#33 (numman-ali) which proposed a provider registry approach. Credit to tars90percent (PR NousResearch#473) and manuelschipper (PR NousResearch#420) for related provider improvements merged earlier in this changeset.
Deploy NousResearch#33 deferred the flip with WIRED_FAIL runtime-resolved-unknown-key: prod's config.yaml already carried a pre-tenant-auth placeholder api_key on the proxy provider block, the bootstrap correctly refused to clobber it, and the gateway therefore resolved a key unknown to keys.json — which would 401 Hermes after the flip. The bootstrap is the cutover tool, so make it authoritative: a :11435 block whose api_key isn't a keys.json-known tenant key is replaced with the hermes key (key_env/api_key_env indirection on the block is dropped too), with a one-time config.yaml.pre-proxy-lock.bak backup for rollback (the yaml round-trip drops comments). Known-key blocks are untouched; re-runs are no-ops. Failure messages now include the resolution source (e.g. a credential-pool hit) for one-glance diagnosis if verification still defers. Simulated the exact run-NousResearch#33 scenario locally: placeholder replaced, backup written, WIRED_OK, idempotent re-run, gateway-path resolution returns the hermes key. https://claude.ai/code/session_018vp1LDdpoaRLCNZQRsnAp8
…arch#34, NousResearch#65) - NousResearch#33 GH_TOKEN propagation: _inject_gh_token_into_env runs `gh auth token` before each worker subprocess.Popen and injects into env if the worker doesn't have GH_TOKEN/GITHUB_TOKEN. - NousResearch#34 respawn_guarded active_pr exempts review roles (tony/tchalla/ vision/reviewer). Bounded: exemption only applies while consecutive_failures < max_retries; once exhausted the guard fires. - NousResearch#65 fabricated github-auth block claims rejected: FabricatedAuthClaimError raised when kanban_block reason matches auth-claim pattern AND dispatcher's `gh auth status` succeeds. Strict leading-position regex with cause:/blocker:/reason:/infra: prefix exemption. Context: hermes-jarvis#61. 33 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
This PR adds Pi-aligned multi-provider support to Hermes CLI with first-class support for:
zai(GLM)kimi-codingminimaxminimax-cnIt also introduces a centralized provider abstraction and multi-profile model configuration flow so users can configure and switch across providers/models more ergonomically in setup + model picker + CLI overrides.
What Changed
1) Provider abstraction (Pi-aligned)
hermes_cli/provider_registry.pyGLM_API_KEY(preferred)ZAI_API_KEYZ_AI_API_KEY2) Multi-provider model profiles (backward compatible)
hermes_cli/model_profiles.pymodel.profilesmodel.active_profilemodel.scoped_profilesmodel.defaultmodel.providermodel.base_url3) Runtime/provider resolution updates
4) Setup/model picker/status/doctor parity
status,doctor, andconfigoutputs include new providers and profile state5) Documentation/examples
Updated:
README.mddocs/cli.mdcli-config.yaml.example.env.exampleDocs now include provider IDs, env vars, profile schema, model selection examples, and provider override behavior.
Tests
Added new tests:
tests/test_provider_registry.pytests/test_model_profiles.pytests/test_cli_first_run.pyExecuted locally:
Result:
27 passedAlso smoke-tested CLI startup:
Notes