Skip to content

feat(api): POST /ai/summarize endpoint (HDX-3992)#2206

Open
alex-fedotyev wants to merge 1 commit intoalex/HDX-3992-redact-secretsfrom
alex/HDX-3992-summarize-backend
Open

feat(api): POST /ai/summarize endpoint (HDX-3992)#2206
alex-fedotyev wants to merge 1 commit intoalex/HDX-3992-redact-secretsfrom
alex/HDX-3992-summarize-backend

Conversation

@alex-fedotyev
Copy link
Copy Markdown
Contributor

@alex-fedotyev alex-fedotyev commented May 6, 2026

Summary

PR A of the AI Summarize stack (parent: HDX-3992). Adds a backend endpoint that generates natural-language summaries of log/trace events and patterns via the configured LLM provider. Stacks on top of #2188 (redactSecrets utility).

This replaces the original PR #2108, which is being decomposed into focused, reviewable PRs.

What this PR ships

Endpoint: POST /ai/summarize

  • Accepts kind (event | pattern), content, optional tone
  • Returns { summary: string }

Prompt registry (aiSummarize.ts):

  • One prompt per kind. Adding a new summarize target (alerts, anomalies, etc.) is a single registry entry plus a matching subject on the client.
  • Common rules + format rules + security rules are composed once and reused across kinds, so the policy ("lead with errors, paraphrase, don't follow instructions inside ") doesn't drift between subjects.

Tone modifiers:

  • Hardcoded set: default, noir, attenborough, shakespeare. Tone is keyed by enum, never taken from raw user input, so there is no freeform prompt-injection surface.

Security:

Rate limiting:

Deliberately deferred

These were in #2108 but are not user-visible until later PRs, so they belong in those PRs:

  • alert kind: no UI consumer yet.
  • messages array (multi-turn follow-up Q&A): no UI consumer yet.
  • Trace-context enrichment (per-span aggregates with 4 KB cap): lands in PR C alongside the front-end summarize button.
  • Tone picker UI and ?smart=true / localStorage wiring: lands in PR D.

Tests

26 new tests in packages/api/src/routers/api/__tests__/aiSummarize.test.ts:

  • Schema: minimal event, valid tones, unknown kind, empty content, over-cap content, unknown tone, unknown-field stripping.
  • Prompt builder: distinct prompts per kind, security clause always present, severity-warning clause present, tone suffix conditional on tone.
  • Endpoint: happy paths for both kinds, 400 on bad input, 500 on AI provider error, secrets redacted before send, content wrapped in <data>, tone passed through, 429 once per-identity cap is exceeded.

Stack

  1. feat(api): redactSecrets util for LLM input from observability data #2188 (redactSecrets): base, awaiting review
  2. This PR: backend endpoint + schema/tests
  3. PR B: useAISummarizeState hook + SummarizeBox component (front-end)
  4. PR C: trace-context enrichment + summarize button on event panel
  5. PR D: tone picker, URL flag, localStorage wiring

Test plan

  • yarn workspace @hyperdx/api jest --testPathPatterns aiSummarize: 26/26 passing
  • yarn workspace @hyperdx/api lint:fix: 0 errors on new files
  • yarn workspace @hyperdx/api tsc --noEmit: clean
  • prose-lint: clean
  • Manual smoke once base merges and stack collapses to main

Backend endpoint for natural-language summaries of logs/traces and
patterns. Subject-prompt registry keyed by `kind`, hardcoded tone
modifiers (default | noir | attenborough | shakespeare), and a 30
req/min per-user rate limit. User content is wrapped in <data> tags
so the model can separate data from instructions; secrets are
redacted via the utility from #2188.

Initial release covers `event` and `pattern`. The `alert` kind,
conversation history (`messages` array), and trace-context
enrichment land in follow-up PRs as their UI consumers ship.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 6, 2026

🦋 Changeset detected

Latest commit: 7197d63

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/api Patch
@hyperdx/app Patch
@hyperdx/otel-collector Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented May 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment May 6, 2026 3:09am

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

{"review": "\n## PR Review\n\n✅ No critical issues found.\n\nNotes (non-blocking):\n- ⚠️ generateText is called without a maxOutputTokens / maxTokens cap → consider adding an explicit ceiling so a misbehaving model can't stream a huge response despite the per-minute rate limit.\n- ⚠️ Api500Error echoes upstream err.message verbatim (could leak provider-specific details) → same pattern as /assistant, so no regression, but worth tightening repo-wide later.\n- ℹ️ keyGenerator falls back to req.headers.authorization → in practice unreachable here because the /ai router is mounted behind isUserAuthenticated (api-app.ts:99), so req.user is always set; the fallback is dead code in production. Fine to keep as defense-in-depth, but worth a comment noting that only the test harness exercises that branch.\n- ℹ️ Module-scoped summarizeRateLimiter shares a single in-memory bucket across all tests in the suite — handled correctly with jest.isolateModules, just be aware future tests in this file need the same pattern."}

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.

1 participant