Skip to content

feat(cli): add first-class z.ai/GLM, Kimi, MiniMax direct API provider support#33

Closed
numman-ali wants to merge 4 commits into
NousResearch:mainfrom
numman-ali:feat/pi-aligned-multi-provider-support
Closed

feat(cli): add first-class z.ai/GLM, Kimi, MiniMax direct API provider support#33
numman-ali wants to merge 4 commits into
NousResearch:mainfrom
numman-ali:feat/pi-aligned-multi-provider-support

Conversation

@numman-ali

Copy link
Copy Markdown

Summary

This PR adds Pi-aligned multi-provider support to Hermes CLI with first-class support for:

  • zai (GLM)
  • kimi-coding
  • minimax
  • minimax-cn

It 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)

  • Added central provider registry: hermes_cli/provider_registry.py
  • Canonical provider IDs and aliases
  • Per-provider metadata:
    • default base URL
    • env var resolution order
    • optional base URL env override
    • curated model list
  • Added support for zAI key aliases:
    • GLM_API_KEY (preferred)
    • ZAI_API_KEY
    • Z_AI_API_KEY

2) Multi-provider model profiles (backward compatible)

  • Added profile helpers: hermes_cli/model_profiles.py
  • Extended config behavior to support:
    • model.profiles
    • model.active_profile
    • model.scoped_profiles
  • Legacy fields remain supported and synchronized:
    • model.default
    • model.provider
    • model.base_url

3) Runtime/provider resolution updates

  • Refactored provider resolution in CLI/auth/main flows to use registry helpers
  • Unified precedence across CLI args, config, env vars, and provider defaults
  • Preserved Nous OAuth path
  • Added provider choices to CLI/provider detection paths

4) Setup/model picker/status/doctor parity

  • Setup wizard now supports all providers and provider-aware key/base URL prompts
  • Model picker supports multi-provider/profile workflows and active profile updates
  • status, doctor, and config outputs include new providers and profile state

5) Documentation/examples

Updated:

  • README.md
  • docs/cli.md
  • cli-config.yaml.example
  • .env.example

Docs now include provider IDs, env vars, profile schema, model selection examples, and provider override behavior.

Tests

Added new tests:

  • tests/test_provider_registry.py
  • tests/test_model_profiles.py
  • tests/test_cli_first_run.py

Executed locally:

.venv/bin/python -m pytest tests/test_provider_registry.py tests/test_model_profiles.py tests/test_cli_first_run.py -q

Result: 27 passed

Also smoke-tested CLI startup:

.venv/bin/python cli.py --list-tools

Notes

  • Provider naming and abstraction follow Pi-style canonical IDs and registry-based resolution.
  • OpenRouter behavior remains unchanged for features that independently rely on OpenRouter tooling.

@numman-ali

Copy link
Copy Markdown
Author

@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

@numman-ali

Copy link
Copy Markdown
Author

Follow-up (clean summary of commit 20eb942):

  • Fixed runtime base URL precedence so active profile/model URLs are honored before provider defaults (resolve_effective_base_url).
  • Fixed /model persistence by syncing active profile model when writing model.default (interactive CLI path and hermes config set model.default).
  • Restored non-OAuth provider deactivation behavior for stale OAuth active_provider state in both hermes model and setup flows.
  • Removed OpenRouter runtime fallback to OPENAI_API_KEY (runtime now matches docs).
  • Prevented custom profiles without base URL from silently inheriting OpenRouter URL.
  • Added regression tests for all above, plus coverage for provider visibility lists and enabled-only profile filtering.

Validation run:

  • .venv/bin/python -m pytest tests/test_provider_registry.py tests/test_model_profiles.py tests/test_cli_first_run.py tests/test_cli_model_save.py -q -> 35 passed
  • .venv/bin/python cli.py --list-tools smoke test passes

@teknium1

Copy link
Copy Markdown
Contributor

@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

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

@numman-ali

Copy link
Copy Markdown
Author

@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

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

@teknium1

Copy link
Copy Markdown
Contributor

Yea I probably will - Am trying to work out a way to let PR sources get contributor status though x]

@numman-ali

Copy link
Copy Markdown
Author

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!

teknium1 added a commit that referenced this pull request Mar 7, 2026
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.
@teknium1

teknium1 commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

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.

@teknium1

teknium1 commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

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.

@teknium1 teknium1 closed this Mar 7, 2026
@teknium1 teknium1 changed the title feat(cli): add pi-aligned multi-provider support (zai/kimi/minimax) feat(cli): add first-class z.ai/GLM, Kimi, MiniMax direct API provider support Mar 7, 2026
sudo-yf pushed a commit to sudo-yf/hermes-agent that referenced this pull request Apr 5, 2026
…ree-preview

Sprint 18: File preview auto-close, thinking display, workspace tree view
h4x3rotab pushed a commit to Clawdi-AI/hermes-agent that referenced this pull request Apr 10, 2026
…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>
h4x3rotab pushed a commit to Clawdi-AI/hermes-agent that referenced this pull request Apr 10, 2026
…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>
linxule added a commit to linxule/hermes-agent that referenced this pull request Apr 27, 2026
…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>
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
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.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
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.
olympus-terminal pushed a commit to olympus-terminal/hermes-agent that referenced this pull request May 16, 2026
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.
ashneil12 referenced this pull request in ashneil12/vanilla-hermes-agent May 18, 2026
)

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>
shanewas added a commit to shanewas/hermes-agent that referenced this pull request Jun 2, 2026
…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)
dizhaky added a commit to dizhaky/hermes-agent that referenced this pull request Jun 4, 2026
- 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
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
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.
adrozdenko pushed a commit to adrozdenko/hermes-agent that referenced this pull request Jun 10, 2026
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
jarvis-stark-ops added a commit to 1Team-Engineering/hermes-agent that referenced this pull request Jun 10, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants