mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-30 01:41:43 +00:00
* Port from Kilo-Org/kilocode#9448: roll up subagent costs into parent session total Child subagents built by delegate_task() each track their own session_estimated_cost_usd, but the parent agent's total never folded those numbers in. On runs where the parent mostly delegates and the children do the expensive work, the footer/UI was reporting a fraction of the actual spend — sometimes $0.00 when the parent itself made no billed calls. Fix: - Capture each child's session_estimated_cost_usd into _child_cost_usd on the result entry (before child.close() drops the counter). - After the existing subagent_stop hook loop, sum the children's costs and add the total to parent.session_estimated_cost_usd. - Promote session_cost_source from 'none' -> 'subagent' when the parent had no direct spend but children did, so the UI doesn't label the total as having unknown provenance. Real sources (openrouter, anthropic, etc.) are preserved. Nested orchestrator -> worker trees roll up naturally: each layer's own delegate_task() folds its direct children in, and when the orchestrator itself returns, its parent folds the orchestrator's now-inflated total on top. Internal fields (_child_cost_usd, _child_role) are stripped from the results dict before it's serialised back to the model — same contract as _child_role already followed. Tests: TestSubagentCostRollup (5 cases) covers single-child, batch, zero-cost-children, preserved-source, and legacy-fixture paths. Source: https://github.com/Kilo-Org/kilocode/pull/9448 * fix(web): scope dashboard config Reset button to the current tab Reported by @ykmfb001 via X: clicking 'Restore Defaults' (恢复默认值) on the Auxiliary page wiped the entire config.yaml to defaults, not just the auxiliary section. The button sits next to the category tabs and users reasonably assumed 'reset this tab', not 'reset everything'. Changes: - handleReset now scopes to the fields in the current view: active category's fields (form mode) or search-matched fields (search mode). Only those keys are copied from defaults; the rest of the config is left alone. - Added a window.confirm() with the scope name before applying. - Button is hidden in YAML mode (scoping doesn't apply there). - Tooltip/aria-label now name the scope, e.g. 'Reset Auxiliary to defaults'. - i18n: new resetScopeTooltip / confirmResetScope / resetScopeToast strings in en + zh; resetDefaults key preserved for compat. |
||
|---|---|---|
| .. | ||
| public | ||
| src | ||
| eslint.config.js | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.app.json | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| vite.config.ts | ||
Hermes Agent — Web UI
Browser-based dashboard for managing Hermes Agent configuration, API keys, and monitoring active sessions.
Stack
- Vite + React 19 + TypeScript
- Tailwind CSS v4 with custom dark theme
- shadcn/ui-style components (hand-rolled, no CLI dependency)
Development
# Start the backend API server
cd ../
python -m hermes_cli.main web --no-open
# In another terminal, start the Vite dev server (with HMR + API proxy)
cd web/
npm run dev
The Vite dev server proxies /api requests to http://127.0.0.1:9119 (the FastAPI backend).
Build
npm run build
This outputs to ../hermes_cli/web_dist/, which the FastAPI server serves as a static SPA. The built assets are included in the Python package via pyproject.toml package-data.
Structure
src/
├── components/ui/ # Reusable UI primitives (Card, Badge, Button, Input, etc.)
├── lib/
│ ├── api.ts # API client — typed fetch wrappers for all backend endpoints
│ └── utils.ts # cn() helper for Tailwind class merging
├── pages/
│ ├── StatusPage # Agent status, active/recent sessions
│ ├── ConfigPage # Dynamic config editor (reads schema from backend)
│ └── EnvPage # API key management with save/clear
├── App.tsx # Main layout and navigation
├── main.tsx # React entry point
└── index.css # Tailwind imports and theme variables