Skip to content

WIP: Use Nous JWTs for inference entitlements - #21894

Draft
rewbs wants to merge 1 commit into
NousResearch:mainfrom
rewbs:rewbs/jwt-for-inference-and-better-free-paid-info
Draft

rewbs wants to merge 1 commit into
NousResearch:mainfrom
rewbs:rewbs/jwt-for-inference-and-better-free-paid-info

Conversation

@rewbs

@rewbs rewbs commented May 8, 2026 •

Copy link
Copy Markdown
Contributor

Do not merge: this is dependent on an Inference API change that is not in prod yet.

Summary

  • Use the NAS OAuth access JWT directly as the Nous inference bearer token and mirror it into the existing agent_key compatibility fields.
  • Add live NAS account entitlement parsing so free/paid decisions use paid_service_access and usable credits instead of subscription price alone.
  • Improve Nous 402/payment-required guidance, /usage, status/setup/tool messaging, and built-in prompts to recommend subscription vs credit top-up based on account state.

Validation

  • python -m py_compile ... for changed Python modules
  • git diff --check
  • ./scripts/run_tests.sh tests/hermes_cli/test_nous_account.py tests/hermes_cli/test_models.py tests/tools/test_tool_backend_helpers.py tests/test_account_usage.py tests/agent/test_prompt_builder.py tests/hermes_cli/test_auth_nous_provider.py tests/hermes_cli/test_auth_commands.py tests/agent/test_credential_pool.py tests/hermes_cli/test_runtime_provider_resolution.py tests/hermes_cli/test_nous_subscription.py tests/hermes_cli/test_status.py tests/hermes_cli/test_status_model_provider.py tests/tools/test_managed_media_gateways.py tests/tools/test_managed_browserbase_and_modal.py tests/tools/test_terminal_requirements.py tests/run_agent/test_run_agent.py

Result: 841 passed, 1 skipped.


Full agent plan

Summary

Update Hermes to use the NAS OAuth access JWT directly as the Nous inference bearer token, matching the RS256 JWT entitlement design. Hermes will stop minting opaque inference tokens, persist the JWT through the existing agent_key compatibility paths, and make free/paid decisions from live NAS account entitlement data.

Source contracts checked:

  • NAS account endpoint: /Users/rewbs/code/nous-account-service/src/app/api/oauth/account/route.ts
  • NAS paid-access rule: paid_access = total_usable_credits > 0
  • Inference JWT auth: /Users/rewbs/code/api/src/middleware/nas_jwt_auth.ts

Key Changes

  • Replace /api/oauth/agent-key minting in hermes_cli/auth.py with JWT aliasing:
    • refresh the NAS OAuth access token as needed;
    • return access_token as the runtime api_key;
    • persist the same JWT into existing agent_key, agent_key_expires_at, agent_key_obtained_at, and credential-pool fields so existing key readers keep working.
  • Keep public helper signatures compatible:
    • resolve_nous_runtime_credentials(..., force_mint=True) becomes a compatibility path that forces a JWT refresh rather than minting an opaque key.
    • Shared auth state continues to omit agent_key; the JWT is already present there as access_token, and opaque keys were not shared previously.
  • Update runtime provider resolution and credential-pool freshness checks to use JWT access-token expiry/skew, not the old opaque-key minimum TTL.
  • Rename user-facing diagnostics from “agent key” to “JWT”, “OAuth token”, or “Nous inference token” where appropriate.

Entitlement And Menus

  • Add a small shared NAS account-status helper that fetches GET {portal}/api/oauth/account using the NAS access JWT and parses:
    • paid_service_access.paid_access / allowed
    • has_active_subscription
    • active_subscription_is_paid
    • subscription_tier
    • total_usable_credits
    • subscription and purchased credit balances.
  • Change all free/paid branching to use live NAS entitlement status:
    • free_tier = not paid_access
    • paid subscription alone is not enough if usable credits are zero.
  • Update model selection, setup flows, /model nous, status output, managed-tool gating, and recommended auxiliary model selection to use this entitlement helper.
  • Default behavior:
    • model menus: if NAS account fetch fails, do not hide paid models, but mark account status unknown;
    • managed paid services: if NAS account fetch fails, do not claim the service is available.

402 And Prompt Guidance

  • Add Nous-specific billing guidance for 402 and relevant SUBSCRIPTION_REQUIRED/credit errors:
    • no active subscription: recommend subscribing;
    • active subscription with no usable credits: recommend top-up;
    • unknown account status: recommend checking Nous billing/credits.
  • Wire this into:
    • main agent provider error handling in run_agent.py;
    • managed Tool Gateway error translation;
    • auxiliary Nous model fallback paths when a Nous 402 exhausts fallbacks.
  • Add Nous support to /usage via agent/account_usage.py, rendering live subscription tier, paid-access state, and usable credit balances from NAS.
  • Update the built-in Nous prompt context so Hermes knows paid access means positive usable credits, and that 402s should trigger live account inspection before suggesting subscription or top-up.

Tests

  • Auth/runtime tests:
    • no POST to /api/oauth/agent-key;
    • runtime api_key equals the access JWT;
    • JWT is persisted through existing agent_key provider and credential-pool fields;
    • forced mint paths now force JWT refresh.
  • Entitlement tests:
    • active paid subscription with zero usable credits is treated as no paid access;
    • purchased credits without subscription grant paid access;
    • unavailable NAS status follows the planned menu and managed-tool defaults.
  • Error-message tests:
    • Nous 402 with no subscription recommends subscription;
    • Nous 402 with active subscription and zero credits recommends top-up.
  • Prompt and usage tests:
    • prompt contains the live account/credits workflow;
    • /usage renders Nous subscription and credit state.
  • Run targeted suites through scripts/run_tests.sh for auth, runtime provider resolution, models, setup/status menus, account usage, prompt builder, managed tools, and run-agent billing handling.

Assumptions

  • Hermes keeps the existing OAuth scope unless NAS requires a new one; the inference API already accepts RS256 NAS JWTs directly.
  • Existing config/file compatibility is preserved by aliasing the JWT into agent_key fields, not by introducing a new required storage key.
  • Entitlement truth comes from NAS /api/oauth/account; JWT claims are only a fallback for runtime authentication, not for fresh menu decisions.

@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard area/auth Authentication, OAuth, credential pools labels May 11, 2026
@alt-glitch alt-glitch added the comp/dashboard Web dashboard / control panel UI (dashboard/, landing) label Jun 27, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/dashboard Web dashboard / control panel UI (dashboard/, landing) P2 Medium — degraded but workaround exists type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants