Skip to content

feat(logs): add optional token-log pagination without breaking Go/Rust parity #455

Description

@LIghtJUNction

Upstream

Upstream behavior

GET /api/log/token currently returns only the most recent MaxRecentItems rows. #7523 adds opt-in pagination: when p, page_size, ps, or size is explicitly present, the response becomes {page,page_size,total,items}; without those parameters it keeps the existing array response and recent-row cap. The PR counts only in paginated mode, keeps token scoping/redaction/order, and caps one page at 1000.

api.lmm.best gap

Go main has the same limitation today:

  • apps/api-go/controller/log.go::GetLogByKey ignores paging parameters.
  • apps/api-go/model/log.go::GetLogByTokenId always applies Limit(common.MaxRecentItems) and has no offset/total path.
  • apps/api-go/common/page_info.go::GetPageQuery has a global 100-row cap, so adopting the upstream 1000-row token-log cap needs an explicit per-call limit rather than changing every endpoint.

LMM also has a Rust backend. apps/api-rust/src/routes/observability.rs intentionally codifies the current token-log contract: LogsByToken ignores query paging and executes ORDER BY ... LIMIT 1000, with tests asserting that behavior. Porting #7523 only to Go would create a backend contract split.

Upstream #7523 is still open. Its frontend CI is green and Go vet/build are green, but the backend CI currently fails in the root/relaykit test step. Because this is a new feature rather than a production bug, do not copy it before the upstream result stabilizes or the failing test is shown unrelated.

Suggested LMM-native implementation

  1. Keep the no-pagination request contract byte-compatible: success/data array, latest 1000 rows, same token-only authorization and redaction.
  2. Enable pagination only when one of p, page_size, ps, size is explicitly present.
  3. Let GetPageQuery accept an endpoint-specific maximum while preserving the existing default cap of 100 for all other callers.
  4. Count only in paginated mode; query and count must both be constrained to the authenticated token_id.
  5. Preserve LMM-specific formatUserLogs behavior, including removal of admin_info and audit_info, empty channel_name, and display IDs based on the page offset.
  6. Add the same contract to Rust LogsByToken in the same PR so Go and Rust stay behaviorally aligned.
  7. Reject/normalize non-positive values and guard page * page_size overflow before building offsets. Decide whether the page cap remains upstream-compatible at 1000 or is lower for LMM after measuring the exact-count/deep-offset cost.

Acceptance criteria

  • No paging parameters: Go and Rust return the existing legacy array and at most MaxRecentItems rows.
  • p, page_size, ps, and size each opt into the paginated envelope.
  • Paginated responses expose page, page_size, total, items; old clients remain unaffected.
  • A token can never count or read another token's rows, even if a query parameter attempts to supply another token id.
  • Deep pages return older history beyond the legacy 1000-row window.
  • Invalid/negative/zero/overflowing parameters cannot cause an unbounded query or integer overflow.
  • User-facing log redaction remains identical to current LMM behavior (admin_info/audit_info removed; no admin-only channel data leaks).
  • ClickHouse ordering remains deterministic in Go; PostgreSQL ordering remains equivalent in Rust.
  • Go and Rust contract tests cover legacy, paginated first/second/deep/empty pages, aliases, page cap, token isolation, redaction, DB/query failure, and overflow.
  • Existing pricing, groups, model price lock, /fast, OAuth restrictions, quota/billing, provider routing, and admin AI assistant behavior are unchanged.

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