Skip to content

fix(lmstudio): respect applied runtime context - #52188

Closed
lunarnexus wants to merge 1 commit into
NousResearch:mainfrom
lunarnexus:fix/lmstudio-context-runtime-combined
Closed

fix(lmstudio): respect applied runtime context#52188
lunarnexus wants to merge 1 commit into
NousResearch:mainfrom
lunarnexus:fix/lmstudio-context-runtime-combined

Conversation

@lunarnexus

@lunarnexus lunarnexus commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes LM Studio context handling so Hermes stops treating 64_000 as both a preload default and a runtime-state sentinel.

The replacement keeps LM Studio runtime state and allocation intent separate:

  • already-loaded LM Studio instances keep their reported loaded_instances[].config.context_length, including 64K;
  • unloaded explicit-mode loads omit context_length when Hermes has no explicit override;
  • explicit Hermes overrides are sent exactly and rejected if they exceed a known LM Studio maximum;
  • Hermes requests echo_load_config and only adopts a context length verified by LM Studio's response or a refreshed loaded-instance query;
  • lmstudio_load_mode: jit still skips the management preload endpoint.

Related Issue

Fixes #30178
Related to #25989

#25989 asks for JIT lifecycle behavior. This PR preserves existing JIT no-preload behavior but does not redesign post-JIT reconciliation, fallback lifecycle, or multiple-instance routing.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactor / cleanup
  • Test-only change

Changes Made

  • hermes_cli/models.py

    • Preserves active loaded-instance context exactly.
    • Omits context_length for unloaded/no-override explicit loads.
    • Sends exact explicit override values.
    • Rejects explicit overrides above known max_context_length before POST.
    • Uses echo_load_config or one refreshed catalog query before adopting runtime context.
  • run_agent.py

    • Removes the forced max(config_context_length or 0, 64_000) LM Studio preload target.
    • Preserves JIT preload bypass.
    • Prevents rejected or unverifiable management loads from falling back to guessed context budgets.
  • agent/agent_init.py

    • Passes verified LM Studio startup runtime into the context engine.
    • Limits sub-64K startup allowance to explicit LM Studio context configuration.
  • agent/agent_runtime_helpers.py

    • Uses the destination model's configured LM Studio context during direct model switching.
    • Passes verified runtime into the switched model's context engine.
  • tests/...

    • Adds focused regressions for loaded 64K authority, omitted cold-load context, exact overrides, above-max rejection, verification-only adoption, JIT no-preload, and direct switch context propagation.
  • website/docs/integrations/providers.md

    • Updates LM Studio context behavior docs.
  • contributors/emails/git@lunarnexus.com

    • Adds required contributor attribution mapping.

How to Test

Targeted local verification:

scripts/run_tests.sh --file-retries 0 \
  tests/hermes_cli/test_lmstudio_context_policy.py \
  tests/hermes_cli/test_urllib_security.py \
  tests/run_agent/test_lmstudio_load_mode.py \
  tests/run_agent/test_switch_model_context.py \
  -q

Result:

34 tests passed, 0 failed

Additional checks run:

ruff check hermes_cli/models.py run_agent.py agent/agent_init.py agent/agent_runtime_helpers.py tests/hermes_cli/test_lmstudio_context_policy.py tests/hermes_cli/test_urllib_security.py tests/run_agent/test_lmstudio_load_mode.py tests/run_agent/test_switch_model_context.py
python scripts/check-windows-footguns.py --all
uv lock --check
git diff --check HEAD^ --

Results:

Ruff: passed
Windows footguns: passed
uv lock --check: passed
git diff --check: passed

Manual smoke validation performed earlier on Linux with LM Studio: unloaded explicit-mode cold load no longer forced 64K when no Hermes context override was configured.

Checklist

  • I have read the contribution guide
  • My commit follows Conventional Commit format
  • I searched for related issues/PRs before submitting
  • This PR is focused and avoids unrelated changes
  • Tests pass locally
  • Bug-fix tests were added/updated
  • Tested on Linux
  • Documentation updated where applicable
  • No new dependencies
  • No secrets, credentials, or environment values added

Security impact

No new credential sources or auth behavior. Existing credential-safe urllib redirect handling remains covered by tests/hermes_cli/test_urllib_security.py.

Scope intentionally deferred

  • Post-JIT context reconciliation after inference-triggered loads
  • TTL / Auto-Evict lifecycle handling
  • Fallback provider activation transactions
  • Multiple loaded instances of the same LM Studio model with different contexts

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have labels Jun 24, 2026
@lunarnexus

Copy link
Copy Markdown
Contributor Author

Additional verification / process notes:

  • This PR intentionally consolidates fix: use LM Studio max_context_length when model is loaded at default 64K #45037 and fix(lmstudio): use detected context for runtime preload when no override is set #48884 into one reviewable LM Studio context fix.

  • The diff is limited to the two LM Studio context paths and their regression tests:

    • agent/model_metadata.py
    • run_agent.py
    • tests/agent/test_model_metadata_local_ctx.py
    • tests/agent/test_lmstudio_runtime_load.py
  • Targeted tests pass locally:

    python -m pytest tests/agent/test_lmstudio_runtime_load.py tests/agent/test_model_metadata_local_ctx.py -q -o 'addopts='
    # 26 passed
  • Syntax check passes locally:

    python -m py_compile run_agent.py agent/model_metadata.py tests/agent/test_lmstudio_runtime_load.py tests/agent/test_model_metadata_local_ctx.py
  • I also ran the preferred wrapper:

    scripts/run_tests.sh

    It timed out after 600s after running 14,333 tests. The observed failures were outside this PR's touched area; one reproduced on untouched origin/main:

    python -m pytest tests/agent/test_copilot_acp_client.py::test_run_prompt_preserves_real_home_when_profile_home_available -q -o 'addopts='

    Untouched origin/main fails with the same HOME assertion, so that failure is not introduced by this PR.

Maintainers can modify the branch if you'd prefer small wording/code adjustments before merge.

@lunarnexus
lunarnexus force-pushed the fix/lmstudio-context-runtime-combined branch 2 times, most recently from d0f8092 to 6b4cf87 Compare June 25, 2026 00:16
@lunarnexus

Copy link
Copy Markdown
Contributor Author

Update: the PR branch has now been rebased onto current origin/main and force-pushed cleanly after updating the fork PAT permissions.

Post-rebase local verification:

python -m pytest tests/agent/test_lmstudio_runtime_load.py tests/agent/test_model_metadata_local_ctx.py -q -o 'addopts='
# 26 passed

python -m py_compile run_agent.py agent/model_metadata.py tests/agent/test_lmstudio_runtime_load.py tests/agent/test_model_metadata_local_ctx.py
# passed

@lunarnexus

Copy link
Copy Markdown
Contributor Author

Quick maintainer check: should this be reviewed independently from #36852, or folded somehow? This PR covers the runtime preload + loaded-instance fallback path, not just config lookup: run_agent.py::_ensure_lmstudio_runtime_loaded(...) now uses detected context when no explicit override is set, and agent/model_metadata.py::_query_local_context_length(...) falls back to LM Studio max_context_length when the loaded instance is only at the default/minimum 64K.

Focused verification is already in the PR body (26 passed across the two LM Studio regression suites plus py_compile). If there’s a preferred way to reconcile this with #36852, I’m happy to rework it — I mainly want maintainer guidance on whether this should be evaluated as the runtime half of the fix or folded into a different path.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for consolidating the two LM Studio paths. The 64K preload behavior is still present on current main (run_agent.py:772), but the proposed runtime-detection heuristic needs rework.

Problems

  • Current main deliberately treats loaded_instances[].config.context_length as the actual runtime constraint (agent/model_metadata.py:1751-1757). Commit c030ac1d8520fec3088f10134a82b9560ea712af added that behavior, and tests/agent/test_model_metadata_local_ctx.py:407-442 protects it.
  • The PR changes any loaded value <= 64K to the advertised maximum. A loaded 64K instance with a larger max_context_length is therefore indistinguishable from the claimed default case and can be reloaded at the larger value through the new preload target.

Suggested changes

  • Keep every loaded-instance context authoritative; split unloaded-model capability discovery from active-runtime detection using an explicit server-state signal.
  • Add a regression case for loaded_instances.context_length == 64_000 plus a larger advertised maximum, preserving the active 64K limit.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
@lunarnexus
lunarnexus force-pushed the fix/lmstudio-context-runtime-combined branch from 6b4cf87 to 38598ba Compare July 20, 2026 15:33
@lunarnexus lunarnexus changed the title fix(lmstudio): use max context for detection and preload fix(lmstudio): respect applied runtime context Jul 20, 2026
@lunarnexus
lunarnexus force-pushed the fix/lmstudio-context-runtime-combined branch from 38598ba to 89bc5f0 Compare July 20, 2026 16:19
@lunarnexus

Copy link
Copy Markdown
Contributor Author

Correction: I narrowed this branch after the replacement grew beyond the reviewer request.

This revision removes the fallback lifecycle, cache invalidation, and broad transaction-snapshot work from the PR. Those are useful follow-ups, but not needed for the core LM Studio context bug.

Current scope is limited to:

  • preserving active loaded_instances[].config.context_length, including 64K;
  • removing the forced 64K explicit preload target;
  • omitting context_length on unloaded/no-override explicit loads;
  • sending exact explicit overrides and rejecting above-known-maximum values;
  • adopting only LM Studio-verified applied runtime;
  • preserving lmstudio_load_mode: jit no-preload behavior;
  • carrying the verified runtime through startup and direct /model switching.

The earlier broad rework comment is obsolete and should be ignored in favor of this narrower revision.

kshitijk4poor added a commit to kshitijk4poor/hermes-agent that referenced this pull request Jul 28, 2026
… Studio loads

Salvage of PR NousResearch#52188. The original PR raised RuntimeError when LM Studio
load was rejected or unverifiable, which would abort agent startup on
transient network failures. Replace with logger.warning + fallback to
configured context length, preserving the old graceful-degradation behavior.
kshitijk4poor added a commit that referenced this pull request Jul 28, 2026
… Studio loads

Salvage of PR #52188. The original PR raised RuntimeError when LM Studio
load was rejected or unverifiable, which would abort agent startup on
transient network failures. Replace with logger.warning + fallback to
configured context length, preserving the old graceful-degradation behavior.
@lunarnexus
lunarnexus deleted the fix/lmstudio-context-runtime-combined branch July 28, 2026 22:51
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
… Studio loads

Salvage of PR NousResearch#52188. The original PR raised RuntimeError when LM Studio
load was rejected or unverifiable, which would abort agent startup on
transient network failures. Replace with logger.warning + fallback to
configured context length, preserving the old graceful-degradation behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: LM Studio custom_providers per-model context_length broken in 0.14.0 — regressed to 64K

3 participants