Skip to content

fix(gateway): proxy mode returns correct history_offset (filtered agent_history length) - #59538

Closed
Elshayib wants to merge 2 commits into
NousResearch:mainfrom
Elshayib:fix/proxy-mode-history-offset
Closed

Elshayib wants to merge 2 commits into
NousResearch:mainfrom
Elshayib:fix/proxy-mode-history-offset

Conversation

@Elshayib

@Elshayib Elshayib commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a bug in proxy mode where _run_agent_via_proxy() returned history_offset=len(history) (raw history length including session_meta entries) instead of the filtered agent_history length. This caused transcript persistence to skip valid new messages when the gateway transcript contained session_meta entries.

Changes

gateway/run.py

  • Build agent_history in proxy mode using the same filtering logic as _build_gateway_agent_history() (skips session_meta, system, strips timestamp/observed from tool messages)
  • All return paths in _run_agent_via_proxy() now use len(agent_history) for history_offset
  • api_messages sent to remote still contains compact user/assistant turns (unchanged behavior)

tests/gateway/test_proxy_mode.py

  • Added test_history_offset_uses_filtered_length — verifies history_offset == 2 when raw history has 1 session_meta + 2 conversation messages
  • Added test_history_offset_with_system_and_tool_messages — verifies session_meta, system, and tool messages are all filtered correctly (raw 6 → filtered 4)

Testing

  • All 24 proxy mode tests pass
  • All 8 transcript offset tests pass
  • The fix mirrors the non-proxy path's behavior (see _run_agent return at line 18516 which uses _effective_history_offset based on len(agent_history))

Root Cause

The proxy path was returning the raw len(history) as history_offset, but the transcript persistence code (line 11665) slices agent_messages[history_offset:] assuming the offset matches the filtered history the agent actually received. When session_meta entries exist in the transcript, the raw length is larger than the filtered length, causing valid new messages to be skipped during persistence.

islam666 added 2 commits July 6, 2026 08:28
…ejection

- Raise silent-rejection cap from 64 → 256 chars so Home Assistant
  Supervisor ingress prefixes (e.g. /api/hassio_ingress/<token>/dashboard,
  up to ~73+ chars) and other deep path-prefix gateways pass validation.
- Add _warn_malformed_prefix() mirroring the existing dedup pattern in
  _warn_if_malformed_public_url() — a misconfigured proxy no longer
  silently discards the prefix and leaves the SPA loading a blank white
  page with zero logs.
- Kept all other validation (path traversal, control chars, double slash)
  unchanged.

Closes #59476
…l bindings

_handle_message_with_agent()'s auto-skill block (Telegram DM Topics,
Discord channel_skill_bindings) loads bound skills via _load_skill_payload()
with a raw identifier, bypassing get_skill_commands()'s scan-time disabled
filter. Result: a skill an operator disables for a platform (or globally,
via skills.disabled) still gets its full content injected into every new
session bound to that channel/topic.

The stacked-skill (#58888) and bundle (#59156) invocation paths already
re-check get_disabled_skill_names() for exactly this reason — the auto-skill
block was the one path in gateway/run.py still missing it.

Fix: check each resolved skill's name against get_disabled_skill_names(platform=...)
before injecting it, skip and log disabled ones. Mirrors the existing
stacked/bundle gates exactly (same helper, same platform scoping, same log style).
No behavior change for any binding that references an enabled skill.

- gateway/run.py: re-check get_disabled_skill_names() in the auto-skill loading
  loop, skipping disabled skills (+14 lines)
- tests/gateway/test_auto_skill_platform_disabled.py: new regression test
  verifying the fix via source-code inspection (mirrors
  test_10710_auto_reset_evicts_cached_agent.py approach; verified: fails
  without the fix, passes with it)
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery tool/skills Skills system (list, view, manage) duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists labels Jul 6, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Duplicate of #59478. Heads up: this PR's description (proxy-mode history_offset) does not match its actual diff. The real change gates auto-skill channel bindings on get_disabled_skill_names(platform=...) in _handle_message_with_agent (gateway/run.py ~L10677) plus a new tests/gateway/test_auto_skill_platform_disabled.py — the same site, mechanism, and test as the earlier open #59478. It also bundles an unrelated hermes_cli/dashboard_auth/prefix.py X-Forwarded-Prefix warning + 64→256 length bump. Recommend consolidating on #59478 (or resubmitting the prefix-warning change separately with an accurate description).

@Elshayib

Elshayib commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Closing: PR body describes proxy history_offset filtering, but the branch diff only contains the #59478 auto-skill gate (+ unrelated prefix.py). The proxy history_offset fix and tests (test_history_offset_uses_filtered_length) are already on main in gateway/run.py / test_proxy_mode.py. No unique change left on this branch after rebase.

@Elshayib

Elshayib commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Stale/mismatched PR — proxy fix already on main; remainder duplicates #59478.

@Elshayib Elshayib closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists tool/skills Skills system (list, view, manage) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants