Skip to content

fix(gateway): respect OPENAI_API_KEY env var to bypass OAuth - #47

Closed
mjshiggins wants to merge 1 commit into
NousResearch:mainfrom
mjshiggins:fix/gateway-oauth-env-check
Closed

fix(gateway): respect OPENAI_API_KEY env var to bypass OAuth#47
mjshiggins wants to merge 1 commit into
NousResearch:mainfrom
mjshiggins:fix/gateway-oauth-env-check

Conversation

@mjshiggins

Copy link
Copy Markdown

(generated by Hermes, haven’t reviewed myself)

The gateway was forcing OAuth authentication for all Nous Research URLs, overriding user-provided API keys from environment variables. This caused failures when Nous Portal credits were exhausted or when users wanted to use direct API keys.

Changes:

  • Check for OPENAI_API_KEY before triggering OAuth flow
  • Only mint agent keys when no explicit API key is provided
  • Allows direct API usage without portal authentication

The gateway was forcing OAuth authentication for all Nous Research URLs,
overriding user-provided API keys from environment variables. This caused
failures when Nous Portal credits were exhausted or when users wanted to
use direct API keys.

Changes:
- Check for OPENAI_API_KEY before triggering OAuth flow
- Only mint agent keys when no explicit API key is provided
- Allows direct API usage without portal authentication

Fixes issues where users couldn't use kimi-k2.5 or other models
due to OAuth credit exhaustion blocking all gateway requests.
@teknium1

Copy link
Copy Markdown
Contributor

Fixed earlier!

@teknium1 teknium1 closed this Feb 26, 2026
malaiwah pushed a commit to malaiwah/hermes-agent that referenced this pull request Apr 5, 2026
Previous commit had double-escaped backslashes (\\) which broke
the Dockerfile syntax. This fixes the RUN instructions to use
proper single backslashes for line continuation.

Fixes build failure in run NousResearch#47.
malaiwah pushed a commit to malaiwah/hermes-agent that referenced this pull request Apr 11, 2026
Previous commit had double-escaped backslashes (\\) which broke
the Dockerfile syntax. This fixes the RUN instructions to use
proper single backslashes for line continuation.

Fixes build failure in run NousResearch#47.
teknium1 added a commit that referenced this pull request May 29, 2026
…kew) (#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call #47/#48/#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
KKT-OPT pushed a commit to KKT-OPT/hermes-agent that referenced this pull request May 31, 2026
…kew) (NousResearch#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-NousResearch#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-NousResearch#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call NousResearch#47/NousResearch#48/NousResearch#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
alt-glitch pushed a commit that referenced this pull request Jun 14, 2026
…kew) (#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call #47/#48/#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
T02200059 pushed a commit to T02200059/hermes-agent that referenced this pull request Jun 18, 2026
…kew) (NousResearch#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-NousResearch#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-NousResearch#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call NousResearch#47/NousResearch#48/NousResearch#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
@mms358-create

Copy link
Copy Markdown

AFK-V2 commit 74c3924ac fixes the core routing bugs from the WhatsApp regression transcript.

Fixed:

  • Draft vs Send: 'draft an email to Bob' now routes to gmail.create_draft deterministically
  • Draft deletion misrouting: 'delete the draft' now routes to gmail.delete_drafts, not cron
  • Dangerous approval: cron state questions route to cron.list (zero shell commands, direct Python API)

7 new regression tests, all passing. Audit report at docs/reports/REAL_USER_REGRESSION_AUDIT.md.

Remaining: contact lookup without Google Workspace still returns a clean error rather than looping. /new consistency is expected behavior — no code change needed.

waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…kew) (NousResearch#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-NousResearch#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-NousResearch#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call NousResearch#47/NousResearch#48/NousResearch#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…kew) (NousResearch#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-NousResearch#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-NousResearch#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call NousResearch#47/NousResearch#48/NousResearch#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
donbowman pushed a commit to donbowman/hermes-agent that referenced this pull request Jul 13, 2026
…kew) (NousResearch#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-NousResearch#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-NousResearch#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call NousResearch#47/NousResearch#48/NousResearch#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…kew) (NousResearch#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-NousResearch#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-NousResearch#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call NousResearch#47/NousResearch#48/NousResearch#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
Soju06 added a commit to Soju06/hermes-agent that referenced this pull request Jul 28, 2026
Meraniya pushed a commit to Meraniya/hermes-agent that referenced this pull request Aug 6, 2026
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…kew) (NousResearch#34475)

A process running mismatched module versions — conversation_compression.py
re-imported with the post-NousResearch#34351 lock code while a long-lived
hermes_state.SessionDB stays bound to the pre-NousResearch#34351 class in memory — has
the try_acquire_compression_lock call site but not the method. The
AttributeError it raises is NOT a sqlite3.Error, so the method's own
fail-open guard never runs; the exception escapes to the outer agent loop,
which prints the error and retries. Compression never succeeds, the token
count never drops, and the loop re-triggers compaction forever (the
'API call NousResearch#47/NousResearch#48/NousResearch#49 ... has no attribute try_acquire_compression_lock'
spin a user hit after an update).

Wrap the lock acquire so any unexpected exception fails OPEN: skip locking
and proceed with compression. Skipping the lock risks a rare
concurrent-compression session fork; an infinite no-progress loop that never
compresses at all is strictly worse. The remediation hint in the log points
at the real fix (restart / hermes update to resync the stale module).

Also guards get_compression_lock_holder against the same skew.

Adds a regression test simulating the version skew (real SessionDB wrapped
so only the lock methods raise AttributeError) — asserts _compress_context
proceeds and rotates instead of raising.
blut-agent pushed a commit to blut-agent/hermes-agent-fork that referenced this pull request Aug 11, 2026
An opener is not always titleable — an image with no caption, a compaction
handoff, a bare slash command — and those sessions stayed unnamed for
life, because the guard that stops re-titling a named session also stopped
the nameless one from ever asking again. Let a later turn name a session
that still has no title.

The derived title also ran the collision dedupe inline on the turn.
It is a slice of the user's own words, so it collides constantly — people
open sessions with "hi" — and resolving "hi NousResearch#47" is a widening scan on the
critical path for a name the model replaces a second later. Decline it
there and let the background stage, which can afford the scan, pick it up.
@zapabob zapabob mentioned this pull request Aug 12, 2026
33hodl pushed a commit to 33hodl/hermes-agent that referenced this pull request Aug 12, 2026
An opener is not always titleable — an image with no caption, a compaction
handoff, a bare slash command — and those sessions stayed unnamed for
life, because the guard that stops re-titling a named session also stopped
the nameless one from ever asking again. Let a later turn name a session
that still has no title.

The derived title also ran the collision dedupe inline on the turn.
It is a slice of the user's own words, so it collides constantly — people
open sessions with "hi" — and resolving "hi NousResearch#47" is a widening scan on the
critical path for a name the model replaces a second later. Decline it
there and let the background stage, which can afford the scan, pick it up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants