Skip to content

feat(channels): extend Advanced Custom balance queries for bounded POST/custom responses #411

Description

@LIghtJUNction

Upstream source

The upstream proposal adds per-channel JavaScript hooks so operators can query provider balances from custom GET/POST APIs and parse provider-specific response shapes.

Current LMM state / gap

LMM already has an architecture-specific alternative: Advanced Custom routes can define a balance management endpoint (/v1/dashboard/billing/credit_grants) with custom upstream path and auth, and fetchAdvancedCustomBalance performs a bounded response read.

Current limitations are narrower than upstream's motivation:

  • balance management requests are hard-coded to GET in apps/api-go/controller/channel-billing.go;
  • AdvancedCustomRoute has path/converter/models/auth, but no management-request method/body fields;
  • automatic balance extraction only recognizes the OpenAI-style credit_summary.total_available shape; other valid JSON is returned as raw response and does not update stored balance.

So importing the upstream JS runtime wholesale would duplicate LMM's existing Advanced Custom abstraction and add a new executable-script/security surface.

Why not implement upstream #7480 directly yet

Upstream #7480 is currently a draft and explicitly lists unresolved work:

  • backend tests were not completed;
  • security review is still pending;
  • each JS hook needs an independent timeout (the current implementation reuses one 5-second context across the HTTP request);
  • non-2xx and sanitization semantics are not finalized.

LMM also currently has no pkg/jsplugin host, so a direct port would be a much larger architectural change than the actual compatibility gap requires.

Suggested LMM-native design

Prefer extending the existing declarative Advanced Custom management route first:

  1. Add an optional method for management routes, restricted to an allowlist (GET, POST initially), with the existing behavior remaining GET by default.
  2. If POST is enabled, support a bounded request body/template designed for balance lookup; do not permit arbitrary network access or arbitrary code execution.
  3. Add a declarative balance extractor for a JSON response (for example a validated JSON path/pointer plus optional numeric scale) rather than executing JavaScript.
  4. Continue enforcing the current configured upstream/base URL boundary, existing proxy transport policy, bounded response size, finite/non-negative balance validation, and sanitized errors.
  5. Only consider a sandboxed script host later if real providers cannot be represented safely with the declarative contract and after upstream #7480 resolves its timeout/security TODOs.

Acceptance criteria

  • Existing Advanced Custom balance routes continue to behave identically with no new fields configured.
  • A configured POST balance endpoint can be queried without changing the channel's inference type.
  • Request method/body are bounded and cannot redirect credentials to another origin.
  • A configured JSON extraction rule can update a finite, non-negative balance from a non-OpenAI response shape.
  • Invalid paths, non-numeric values, NaN/Inf, negative values, oversized bodies/responses and disallowed methods fail closed without overwriting the previous balance.
  • API keys/body/response data are not leaked through errors or logs.
  • Tests cover GET backward compatibility, POST, custom extraction, origin/redirect restrictions, size limits and invalid balance values.
  • No changes to pricing, groups, model price lock, /fast, OAuth restrictions or the administrator AI assistant.

This issue tracks the useful provider-compatibility capability from upstream #7480 without committing LMM to its still-unsettled JavaScript execution design.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions