feat(agent): add Upstage Solar as a model provider (internal review)#1
Open
minchang wants to merge 1 commit into
Open
feat(agent): add Upstage Solar as a model provider (internal review)#1minchang wants to merge 1 commit into
minchang wants to merge 1 commit into
Conversation
118a925 to
cf599d5
Compare
Adds Upstage Solar as a bundled model-provider plugin. Solar exposes an OpenAI-compatible chat-completions endpoint at https://api.upstage.ai/v1, so the generic chat_completions transport handles request/response/streaming/tool calls — the profile is the core integration. Provider registration (Upstage isn't in models.dev, so each registry that does not auto-wire from the plugin layer needs an explicit entry — same pattern as nvidia/gmi): - plugins/model-providers/upstage/: UpstageProfile + plugin.yaml. Picker default and offline catalog list only the agentic Solar Pro models, led by `solar-pro` (rolling alias for the latest Pro). default_aux_model empty so aux tasks use the main model. `solar` alias. UPSTAGE_BASE_URL overrides the host. - hermes_cli/providers.py: HERMES_OVERLAYS + label + `solar` alias, so resolve_provider_full('upstage') resolves (without this, an explicit `provider: upstage` in config was dropped and fell through to auto-detect). - hermes_cli/auth.py: PROVIDER_REGISTRY entry + `solar` alias, so `hermes doctor` / resolve_provider recognise upstage (the static-registry path the lazy profile-extension doesn't reliably cover at validation time). - hermes_cli/models.py: CANONICAL_PROVIDERS entry places Upstage Solar in the curated picker order (above the auto-appended `custom`). - agent/model_metadata.py: context-window fallbacks (/v1/models omits context_length); `solar-pro` carries the 128K Pro context as the catch-all. Reasoning: UpstageProfile.build_api_kwargs_extras wires Solar's top-level `reasoning_effort` (low|medium|high; xhigh/max→high). Reasoning-capable families are solar-pro* and solar-open*; solar-mini/syn-pro never receive it. Defaults ON at medium when unset (matches the /reasoning "medium (default)" label); `/reasoning none` disables; explicit/saved settings are honored. No reasoning_content echo handling needed (unlike DeepSeek/Kimi). Web dashboard: - web/src/pages/EnvPage.tsx: add an "Upstage Solar" provider group so UPSTAGE_API_KEY / UPSTAGE_BASE_URL appear under LLM Providers (not "Other"). Docs/tests: - .env.example: documents UPSTAGE_API_KEY / UPSTAGE_BASE_URL. - tests: profile wiring, reasoning_effort mapping (pro/open/mini, efforts, disabled, default-on), provider-resolver regression (resolve_provider_full / get_provider / solar alias / overlay), `solar-pro` default. Testing: pytest tests/providers tests/plugins/model_providers tests/hermes_cli/test_upstage_provider.py tests/run_agent/test_provider_parity.py tests/hermes_cli/test_api_key_providers.py; ruff clean. Verified end-to-end: `hermes doctor` shows "Upstage Solar", and live chat works via both `--provider upstage` and `--provider solar`. Reasoning wire format per https://console.upstage.ai/api/docs/for-agents/raw. Platforms tested: macOS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cf599d5 to
4317c2d
Compare
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.
Internal review before upstream
Internal review PR within
UpstageAI/hermes-agentbefore we submit tonousresearch/hermes-agent. (Upstream PR NousResearch#41697 was opened then closed to revise here first.)What
Adds Upstage Solar as a model provider so it appears in the
hermes model/hermes setupprovider picker. Solar exposes an OpenAI-compatible chat-completions endpoint (https://api.upstage.ai/v1), so this uses Hermes' documented fast path — a self-registeringProviderProfileplugin. No transport changes.solar-pro(rolling alias for the latest Solar Pro).fallback_models): only the agentic Solar Pro models (solar-pro,solar-pro3). When a key is set, the live/v1/modelscatalog lists everything available.Changes
plugins/model-providers/upstage/—ProviderProfile+plugin.yaml. Nameupstage, aliassolar,UPSTAGE_API_KEY(+ optionalUPSTAGE_BASE_URL).default_aux_modelleft empty so auxiliary side tasks (compression, vision, memory) fall back to the user's main model. Every downstream layer auto-wires from the registry.agent/model_metadata.py— context-window fallbacks (/v1/modelsomitscontext_length). Versioned ids resolve exactly;solar-procarries the 128K Pro context as the rolling-alias catch-all for futuresolar-pro*releases..env.example— documentsUPSTAGE_API_KEY/UPSTAGE_BASE_URL.solar-prodefault.Review feedback applied
solar-pro(= latest Solar Pro), led infallback_models[0].solar-miniremoved from the default/fallback model list. It's also not pinned as the aux model —default_aux_modelis left empty so background tasks use the main model, avoiding a silent 404 when Mini is deprecated (no committed replacement).solar-pro2dropped from promotion; descriptions no longer enumerate a fixed model list, so better models surface automatically via the live catalog.solar-pro(128K) instead of a baresolar(32K) entry — futuresolar-pro4inherits the Pro context.Still to confirm before upstreaming
solar-pro/solar-pro3are the exact native slugs returned byhttps://api.upstage.ai/v1/models(vs OpenRouter's dashedsolar-pro-3).fallback_modelsonly matters offline — the live catalog overrides it when a key is set.— resolved: aux model left empty (falls back to mainsolar-minias aux modelsolar-pro), so no dependency on Mini.reasoning_effortwiring). Confirm Solar Pro doesn't require echoingreasoning_contentback on later turns (the DeepSeek/Kimi trap); if it does, we'll add abuild_api_kwargs_extrasoverride.https://console.upstage.ai/api-keys.feat(agent).Testing
594+ passed across provider/plugin/runtime/CLI/parity/api-key suites;
ruffclean. Verified the picker shows"Upstage Solar", the default resolves tosolar-pro, and a futuresolar-pro4inherits the Pro context window.Platforms tested: macOS.
🤖 Generated with Claude Code