Provider reconfig: agent-config sync, Hermes One auto-provisioning, provider UI redesign & chat stream fixes - #862
Merged
Merged
Conversation
Contributor
Greptile SummaryThis PR unifies provider behavior across the desktop, Hermes Agent, and Hermes One. The main changes are:
Confidence Score: 5/5The reviewed fixes appear safe to merge.
Important Files Changed
Reviews (3): Last reviewed commit: "Review Fixes" | Re-trigger Greptile |
Owner
Author
|
@greptile-apps review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This branch makes providers behave as one system across the desktop, the bundled hermes-agent, and the Hermes One backend — plus a light-based redesign of the provider surfaces and two chat-streaming correctness fixes the work surfaced along the way.
🔑 Provider routing fixes
Native provider keys were invisible in the model picker.
providerRouteForEnvKeyonly knew keys carried by aPROVIDERS.setupcard or a local preset; everything else fell to a deadcustom+ empty-base-URL route, which the active-model picker silently drops. A configured Nous Portal API key never appeared in the "Select default model" modal. A newNATIVE_ENV_KEY_ROUTEStable maps each orphaned key to its hermes-agent slug (NOUS_API_KEY → nous,GLM_API_KEY → zai,KIMI_API_KEY → kimi-coding,MINIMAX[_CN]_API_KEY → minimax[-cn],NVIDIA,OPENCODE_ZEN/GO,HF_TOKEN → huggingface,PERPLEXITY → custom + base URL), verified against the agent's ownplugins/model-providers/*registries. A test asserts no LLM-section key can ever land on the dead fallback again.Session switches to custom-endpoint models routed to the wrong provider.
/model <id> --provider customlets the agent bindcustomto the session's current base URL — so switching tohermesone-swiftwhile a session sat on Nous sent the request to the Nous proxy (HTTP 404 … OpenRouter catalog). Fixed at both ends:providers: hermesone:entry (base_url+key_env), so the gateway always has a slug that carries the right endpoint;resolveDashboardProviderForModelnow matches any gateway provider row by base URL (named user providers included, not justcustom:*rows) before ever falling back to barecustom.providers: {}is rewritten into block form on upsert — the line-based parser couldn't index it, which silently disabled the mirror on real configs (and appending would have produced a duplicate top-level key).🔄 Desktop ↔ hermes-agent provider sync
Named OpenAI-compatible providers now sync both ways with the agent's config.yaml via a new text-based bridge (
src/main/agent-config-providers.ts) that preserves comments and unrelated keys:providers:dict entries and legacycustom_providers:list entries added via the CLI are imported on every provider-list / model-library read — cards, picker entries, and model rows appear without reseeding. A terminal entry's customkey_envvalue is aliased additively to the desktop's derivedCUSTOM_PROVIDER_<NAME>_KEYso keys resolve everywhere. Previouslycustom_providers:was only honored once, at firstmodels.jsonseed.providers:entry (patching fields in place — a terminal user's extra fields liketransport:survive); removing a provider deletes it from both config.yaml shapes so it can't re-import.🪪 Hermes One account: auto-provisioned key + credits
Signing in should yield model access without hand-copying keys:
POST /api/credits/keyswith the bearer token and stores the one-timehs-live-…key asHERMESONE_API_KEY— which by itself makes the Hermes One card and picker entry appear. Idempotent (an existing key is never replaced), single-flight (concurrent calls can't double-issue), and local-mode only (a remote/SSH profile would strand orphan keys).$X.XX creditschip viaGET /api/credits/balance).🎨 Provider UI redesign (light-based, stroke-free)
hs-••••••••3k8d) with Show / Replace and a "Used by N models" meta line; models as compact chips with an inline "+ Add model ID" pill (autocomplete, Enter/blur commits) collapsing behind "+N more" past 10; hairline header/footer dividers, fills instead of strokes, 11–13px control type.overflow: hidden, so long provider lists actually scroll.💬 Chat streaming correctness
Both fixes key on the same insight: text assembled from dropped chunks is, by construction, a subsequence of the canonical text.
reasoning, the streamed bubble ends up a garbled subset of the final text, andmergeStreamedWithFinalconcatenated the two ("! What are we working on?\n\nHey! What are we working on today?"). A guarded subsequence branch (≥12 chars, ≥30% coverage) replaces the garbled stream with the final — the pre-tool-call + answer pair still stacks.🧪 Tests & docs
~60 new tests: env-key routing invariants, provider ordering, the config.yaml bridge (parse/upsert/remove/
{}-scaffold round-trips), import/mirror/delete sync, key provisioning (single-flight, failure paths), dashboard provider resolution (incl. the Nous-404 regression), and the two subsequence-based stream reconciliations. All 1795 pass;lat.md/updated throughout (provider-setup,hermes-account-login,chat-commands,sidebar-navigation) andlat checkis green.