feat(api): POST /ai/summarize endpoint (HDX-3992)#2206
feat(api): POST /ai/summarize endpoint (HDX-3992)#2206alex-fedotyev wants to merge 1 commit intoalex/HDX-3992-redact-secretsfrom
Conversation
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 detectedLatest commit: 7197d63 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
{"review": "\n## PR Review\n\n✅ No critical issues found.\n\nNotes (non-blocking):\n- |
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/summarizekind(event|pattern),content, optionaltone{ summary: string }Prompt registry (
aiSummarize.ts):kind. Adding a new summarize target (alerts, anomalies, etc.) is a single registry entry plus a matching subject on the client.Tone modifiers:
default,noir,attenborough,shakespeare. Tone is keyed by enum, never taken from raw user input, so there is no freeform prompt-injection surface.Security:
redactSecretsfrom feat(api): redactSecrets util for LLM input from observability data #2188 before being sent to the model.<data>...</data>delimiters and the system prompt explicitly tells the model to treat that block as data, not instructions.Rate limiting:
@/utils/rateLimiter(already in deps for feat(api): redactSecrets util for LLM input from observability data #2188), no new packages.Deliberately deferred
These were in #2108 but are not user-visible until later PRs, so they belong in those PRs:
alertkind: no UI consumer yet.messagesarray (multi-turn follow-up Q&A): no UI consumer yet.?smart=true/ localStorage wiring: lands in PR D.Tests
26 new tests in
packages/api/src/routers/api/__tests__/aiSummarize.test.ts:<data>, tone passed through, 429 once per-identity cap is exceeded.Stack
useAISummarizeStatehook +SummarizeBoxcomponent (front-end)Test plan
yarn workspace @hyperdx/api jest --testPathPatterns aiSummarize: 26/26 passingyarn workspace @hyperdx/api lint:fix: 0 errors on new filesyarn workspace @hyperdx/api tsc --noEmit: cleanprose-lint: clean