Skip to content

feat(seer): Add lightweight RCA clustering endpoint integration#112229

Open
yuvmen wants to merge 6 commits intomasterfrom
yuvmen/feat/lightweight-rca-cluster
Open

feat(seer): Add lightweight RCA clustering endpoint integration#112229
yuvmen wants to merge 6 commits intomasterfrom
yuvmen/feat/lightweight-rca-cluster

Conversation

@yuvmen
Copy link
Copy Markdown
Member

@yuvmen yuvmen commented Apr 3, 2026

Integrate Seer's new /v0/issues/supergroups/cluster-lightweight endpoint for lightweight root cause analysis and supergroup clustering.

When a new error issue is created, if the org is in the supergroups.lightweight-enabled-orgs sentry-option, we send the issue's event data to Seer. Seer generates a lightweight RCA via a single LLM call and clusters the issue into supergroups based on embedding similarity. This is separate from the existing Explorer-based agentic RCA flow.

Changes:

  • Register supergroups.active-rca-source and supergroups.lightweight-enabled-orgs sentry-options
  • Add LightweightRCAClusterRequest type and make_lightweight_rca_cluster_request() API function
  • Add trigger_lightweight_rca_cluster() core function and Celery task
  • Add kick_off_lightweight_rca_cluster pipeline step in post_process for new error issues
  • Rename existing lightweight_rca.pyexplorer_lightweight_rca.py to clarify it's the Explorer-based flow

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 3, 2026
Call Seer's new /v0/issues/supergroups/cluster-lightweight endpoint
on new issue creation, gated per-org via sentry-options. This sends
issue event data to Seer for lightweight root cause analysis and
clustering into supergroups.

Also renames the existing explorer-based lightweight RCA files to
explorer_lightweight_rca to avoid confusion with the new direct
endpoint-based clustering approach.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Serialized event data from EventSerializer can contain non-string dict
keys (integer keys in _meta.entries). Without this option orjson.dumps
raises TypeError.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Backend Test Failures

Failures on 35a6636 in this run:

tests/sentry/taskworker/test_config.py::test_all_instrumented_tasks_registeredlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/taskworker/test_config.py:120: in test_all_instrumented_tasks_registered
    raise AssertionError(
E   AssertionError: Found 1 module(s) with @instrumented_task that are NOT registered in TASKWORKER_IMPORTS.
E   These tasks will not be discovered by the taskworker in production!
E   
E   Missing modules:
E     - sentry.tasks.seer.lightweight_rca_cluster
E   
E   Add these to TASKWORKER_IMPORTS in src/sentry/conf/server.py

Without this registration the task won't be discovered by the
taskworker in production.
@yuvmen yuvmen marked this pull request as ready for review April 3, 2026 21:20
@yuvmen yuvmen requested review from a team as code owners April 3, 2026 21:20
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Backend Test Failures

Failures on b442df5 in this run:

tests/sentry/taskworker/test_config.py::test_import_pathslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/taskworker/test_config.py:25: in test_import_paths
    __import__(path)
src/sentry/tasks/seer/lightweight_rca_cluster.py:10: in <module>
    @instrumented_task(
E   TypeError: instrumented_task() missing 1 required positional argument: 'namespace'
tests/sentry/test_devimports.py::test_startup_imports[sentry]log
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/test_devimports.py:121: in test_startup_imports
    validate_package(pkg, EXCLUDED, XFAIL)
tests/sentry/test_devimports.py:116: in validate_package
    raise AssertionError(ret.stdout)
E   AssertionError: /home/runner/work/sentry/sentry/src/sentry/spans/consumers/process_segments/enrichment.py:38: DeprecationWarning: ATTRIBUTE_NAMES.SENTRY_BROWSER_NAME is deprecated.
E     ATTRIBUTE_NAMES.SENTRY_BROWSER_NAME,
E   error importing sentry.tasks.seer.lightweight_rca_cluster:
E   
E   Traceback (most recent call last):
E     File "<string>", line 35, in <module>
E       __import__(name)
E       ~~~~~~~~~~^^^^^^
E     File "<string>", line 15, in _import
E       return orig(name, globals=globals, locals=locals, fromlist=fromlist, level=level)
E     File "/home/runner/work/sentry/sentry/src/sentry/tasks/seer/lightweight_rca_cluster.py", line 10, in <module>
E       @instrumented_task(
E        ~~~~~~~~~~~~~~~~~^
E           name="sentry.tasks.seer.lightweight_rca_cluster.trigger_lightweight_rca_cluster_task",
E           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       ...<2 lines>...
E           taskworker_namespace=issues_tasks,
E           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       )
E       ^
E   TypeError: instrumented_task() missing 1 required positional argument: 'namespace'

)

# Supergroups / Lightweight RCA
register(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it make sense to duplicate the options between here and seer? i thought the original plan was to have seer do this check

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea I was conflicted about it, I think that now I got options in Seer I can have protections there, but I also dont want to queue tasks for all issues for nothing, seems very wasteful... and now I can basically have both be controlled by the same repo so I think its ok to protect from both sides using same config

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could just do the check only in sentry the? not sure it makes sense to duplicate the options, especially if the options have exactly the same name + purpose

This option is used on the Seer side, not in Sentry. Remove it until
it's actually needed here.
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6f9d2d1. Configure here.

"""
enabled_orgs: list[int] = options.get("supergroups.lightweight-enabled-orgs")
if group.organization.id not in enabled_orgs:
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated org enablement check increases maintenance risk

Low Severity

The supergroups.lightweight-enabled-orgs option check is duplicated in kick_off_lightweight_rca_cluster and trigger_lightweight_rca_cluster. The check in trigger_lightweight_rca_cluster is redundant since kick_off_lightweight_rca_cluster already performs this gating before dispatching the task. This duplication creates a maintenance risk if the logic changes, potentially leading to inconsistencies.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6f9d2d1. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Backend Test Failures

Failures on c02c388 in this run:

tests/sentry/taskworker/test_config.py::test_import_pathslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/taskworker/test_config.py:25: in test_import_paths
    __import__(path)
src/sentry/tasks/seer/lightweight_rca_cluster.py:10: in <module>
    @instrumented_task(
E   TypeError: instrumented_task() missing 1 required positional argument: 'namespace'
tests/sentry/test_devimports.py::test_startup_imports[sentry]log
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/test_devimports.py:121: in test_startup_imports
    validate_package(pkg, EXCLUDED, XFAIL)
tests/sentry/test_devimports.py:116: in validate_package
    raise AssertionError(ret.stdout)
E   AssertionError: /home/runner/work/sentry/sentry/src/sentry/spans/consumers/process_segments/enrichment.py:38: DeprecationWarning: ATTRIBUTE_NAMES.SENTRY_BROWSER_NAME is deprecated.
E     ATTRIBUTE_NAMES.SENTRY_BROWSER_NAME,
E   error importing sentry.tasks.seer.lightweight_rca_cluster:
E   
E   Traceback (most recent call last):
E     File "<string>", line 35, in <module>
E       __import__(name)
E       ~~~~~~~~~~^^^^^^
E     File "<string>", line 15, in _import
E       return orig(name, globals=globals, locals=locals, fromlist=fromlist, level=level)
E     File "/home/runner/work/sentry/sentry/src/sentry/tasks/seer/lightweight_rca_cluster.py", line 10, in <module>
E       @instrumented_task(
E        ~~~~~~~~~~~~~~~~~^
E           name="sentry.tasks.seer.lightweight_rca_cluster.trigger_lightweight_rca_cluster_task",
E           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       ...<2 lines>...
E           taskworker_namespace=issues_tasks,
E           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       )
E       ^
E   TypeError: instrumented_task() missing 1 required positional argument: 'namespace'

The instrumented_task decorator requires `namespace` not
`taskworker_namespace`, and doesn't accept `queue` or `max_retries`.
GroupEvent.group is typed as non-optional, so the None check is
unreachable and mypy flags it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants