Skip to content

feat(evaluation): Added the callback support for notifications in Evaluation Run - #1115

Open
Ayush8923 wants to merge 4 commits into
mainfrom
feat/evals-callback-support-for-notification
Open

feat(evaluation): Added the callback support for notifications in Evaluation Run#1115
Ayush8923 wants to merge 4 commits into
mainfrom
feat/evals-callback-support-for-notification

Conversation

@Ayush8923

@Ayush8923 Ayush8923 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Issue

Closes #1100

Summary

  • Added optional HTTPS completion webhooks for v2 evaluation runs.
  • Webhooks are sent when runs complete or fail and include the full run response.
  • Invalid callback URLs are rejected with a validation error.

Checklist

Before submitting a pull request, please ensure that you mark these task.

  • Ran fastapi run --reload app/main.py or docker compose up in the repository root and test.
  • If you've fixed a bug or added code that is tested and has test cases.

Summary by CodeRabbit

  • New Features

    • Added optional HTTPS completion webhooks for v2 evaluation runs.
    • Callbacks are sent on successful or failed terminal runs and may include signing.
    • Callback delivery is asynchronous and best-effort.
  • Bug Fixes

    • Invalid or insecure callback URLs are rejected with a validation error.
  • Documentation

    • Documented callback configuration, payloads, delivery behavior, and limitations.

@Ayush8923 Ayush8923 self-assigned this Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

V2 evaluations now accept optional HTTPS callback URLs. The URL is persisted with the run, and terminal transitions enqueue a Celery task that sends success or failure webhook payloads with best-effort delivery.

Changes

Evaluation callback workflow

Layer / File(s) Summary
Callback contract and evaluation start
backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py, backend/app/models/evaluation.py, backend/app/api/routes/evaluations/evaluation_v2.py, backend/app/services/evaluations/fast.py, backend/app/tests/api/routes/test_evaluation_v2.py, backend/app/api/docs/evaluation/create_evaluation_v2.md
The v2 API validates and persists optional HTTPS callback_url values. The field remains absent from public responses.
Terminal transition dispatch
backend/app/crud/evaluations/core.py, backend/app/celery/tasks/job_execution.py, backend/app/tests/crud/evaluations/test_completion_callback_trigger.py
Terminal transitions enqueue the callback task when a URL exists. Broker errors do not propagate.
Webhook delivery and payload validation
backend/app/services/notifications/eval_completion.py, backend/app/tests/celery/test_notifications.py, docs/wiki/modules/evaluations.md
The callback service sends slim success or failure response envelopes, applies webhook signing, skips missing targets, and reports delivery outcomes without propagating delivery errors.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EvaluationRun
  participant send_eval_completion_callback
  participant execute_eval_completion_callback
  participant CallbackEndpoint
  EvaluationRun->>send_eval_completion_callback: terminal transition dispatch
  send_eval_completion_callback->>execute_eval_completion_callback: evaluation_id
  execute_eval_completion_callback->>CallbackEndpoint: signed success or failure payload
  CallbackEndpoint-->>execute_eval_completion_callback: delivery result
Loading

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: akhileshnegi, nishika26

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding callback support for evaluation run notifications.
Linked Issues check ✅ Passed The PR accepts, stores, and delivers callback URLs with evaluation completion status payloads as required by issue #1100.
Out of Scope Changes check ✅ Passed The code, migration, documentation, and tests all support the callback webhook objectives in issue #1100.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/evals-callback-support-for-notification

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment on lines +523 to +532
class EvalCompletionCallbackData(SQLModel):
"""Slim run snapshot for the completion webhook — identity + status only."""

id: int
run_name: str
dataset_name: str
status: str
run_mode: RunModeEnum
inserted_at: datetime
updated_at: datetime

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

these are all the parameters that we are sending in the callback response.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
backend/app/crud/evaluations/core.py (1)

273-283: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the emitting function name in the log prefix.

Line 280 emits [update_evaluation_run] from _enqueue_eval_completion_callback. Change the prefix to [_enqueue_eval_completion_callback].

As per coding guidelines, “Prefix every log line with the function name in square brackets.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/crud/evaluations/core.py` around lines 273 - 283, Update the
logger.error message in _enqueue_eval_completion_callback to use
[_enqueue_eval_completion_callback] as its prefix instead of
[update_evaluation_run], while preserving the existing evaluation ID, error
details, and traceback logging.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py`:
- Around line 21-38: Apply narrow Python 3.11+ annotations throughout the
affected functions: annotate upgrade and downgrade with -> None in
backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py:21-38;
replace bare dict results with TypedDict-style narrow types in
eval_completion.py:215-260 and job_execution.py:450-456; annotate test methods
with -> None in test_evaluation_v2.py:150-256 and
test_completion_callback_trigger.py:29-122; narrow the score mapping and add
precise return annotations for test methods and helpers in
test_notifications.py:109-118 and 383-634.

In `@backend/app/models/evaluation.py`:
- Around line 523-532: Update backend/app/models/evaluation.py:523-532 so
EvalCompletionCallbackData matches the complete EvaluationRunPublic payload
while excluding callback_url. Update
backend/app/services/notifications/eval_completion.py:215-226 to serialize and
deliver that complete public run payload, including score, score_trace_url,
cost, and error_message.

In `@backend/app/services/notifications/eval_completion.py`:
- Around line 229-260: Update execute_eval_completion_callback to accept
force_send, defer completed runs when their trace URL is unavailable by
returning a retry signal instead of delivering, and preserve forced summary-only
delivery when force_send is true. In backend/app/celery/tasks/job_execution.py
lines 448-456, handle that retry signal with self.retry and, after retry
exhaustion, invoke execute_eval_completion_callback with force_send=True.

---

Nitpick comments:
In `@backend/app/crud/evaluations/core.py`:
- Around line 273-283: Update the logger.error message in
_enqueue_eval_completion_callback to use [_enqueue_eval_completion_callback] as
its prefix instead of [update_evaluation_run], while preserving the existing
evaluation ID, error details, and traceback logging.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 32b77b10-7909-40c6-8ee2-ee7d9d3f1dbb

📥 Commits

Reviewing files that changed from the base of the PR and between efaf42a and 21e9450.

📒 Files selected for processing (12)
  • backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py
  • backend/app/api/docs/evaluation/create_evaluation_v2.md
  • backend/app/api/routes/evaluations/evaluation_v2.py
  • backend/app/celery/tasks/job_execution.py
  • backend/app/crud/evaluations/core.py
  • backend/app/models/evaluation.py
  • backend/app/services/evaluations/fast.py
  • backend/app/services/notifications/eval_completion.py
  • backend/app/tests/api/routes/test_evaluation_v2.py
  • backend/app/tests/celery/test_notifications.py
  • backend/app/tests/crud/evaluations/test_completion_callback_trigger.py
  • docs/wiki/modules/evaluations.md

Comment on lines +21 to +38
def upgrade():
op.add_column(
"evaluation_run",
sa.Column(
"callback_url",
sa.Text(),
nullable=True,
comment=(
"Optional HTTPS webhook (v2 runs only) POSTed the run's "
"APIResponse[EvaluationRunPublic] once the run reaches a terminal "
"state (completed/failed). NULL when no callback was requested"
),
),
)


def downgrade():
op.drop_column("evaluation_run", "callback_url")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Add narrow annotations to every changed function.

Several changed functions omit return annotations. Several callback result annotations use bare dict. Add -> None where appropriate. Define narrow result types, such as TypedDict models, for callback task and delivery results.

  • backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py#L21-L38: annotate migration functions with -> None.
  • backend/app/services/notifications/eval_completion.py#L215-L260: replace bare dict return annotations with narrow result types.
  • backend/app/celery/tasks/job_execution.py#L450-L456: use a narrow callback-task return type.
  • backend/app/tests/api/routes/test_evaluation_v2.py#L150-L256: annotate test methods with -> None.
  • backend/app/tests/crud/evaluations/test_completion_callback_trigger.py#L29-L122: annotate test methods with -> None.
  • backend/app/tests/celery/test_notifications.py#L109-L118: narrow the score mapping type.
  • backend/app/tests/celery/test_notifications.py#L383-L634: annotate test methods and helper functions with narrow return types.

As per coding guidelines, “Use Python 3.11+ and provide narrow type hints for every function parameter and return value.”

📍 Affects 6 files
  • backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py#L21-L38 (this comment)
  • backend/app/services/notifications/eval_completion.py#L215-L260
  • backend/app/celery/tasks/job_execution.py#L450-L456
  • backend/app/tests/api/routes/test_evaluation_v2.py#L150-L256
  • backend/app/tests/crud/evaluations/test_completion_callback_trigger.py#L29-L122
  • backend/app/tests/celery/test_notifications.py#L109-L118
  • backend/app/tests/celery/test_notifications.py#L383-L634
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py`
around lines 21 - 38, Apply narrow Python 3.11+ annotations throughout the
affected functions: annotate upgrade and downgrade with -> None in
backend/app/alembic/versions/076_add_callback_url_to_evaluation_run.py:21-38;
replace bare dict results with TypedDict-style narrow types in
eval_completion.py:215-260 and job_execution.py:450-456; annotate test methods
with -> None in test_evaluation_v2.py:150-256 and
test_completion_callback_trigger.py:29-122; narrow the score mapping and add
precise return annotations for test methods and helpers in
test_notifications.py:109-118 and 383-634.

Source: Coding guidelines

Comment thread backend/app/services/notifications/eval_completion.py
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

OpenAPI changes   🟢 1 non-breaking change

Tip

Safe to merge from an API-contract perspective.

Full changelog  ·  1
Method Path Change
🟢 POST /api/v2/evaluations added the new optional request property callback_url

main7ee2e956 · generated by oasdiff

@ProjectTech4DevAI ProjectTech4DevAI deleted a comment from coderabbitai Bot Aug 6, 2026
@Ayush8923
Ayush8923 requested a review from AkhileshNegi August 6, 2026 16:48
@Ayush8923
Ayush8923 requested review from AkhileshNegi and removed request for AkhileshNegi August 6, 2026 17:05
@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/app/tests/celery/test_notifications.py`:
- Around line 373-381: Update the callback schema and the related assertions in
the notification tests around _SLIM_KEYS and the referenced cases to validate
the full public evaluation-run response envelope. Remove the slim-payload
restriction and ensure fields such as scores, traces, and costs remain available
to webhook consumers.
- Around line 383-385: Add narrow annotations to the added test methods,
including test_completed_run_delivers_slim_success_payload and the other newly
introduced tests, using the repository’s established test-class self type and an
explicit -> None return annotation for each method.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9395e14b-07d0-499a-aca3-ac3a708a61db

📥 Commits

Reviewing files that changed from the base of the PR and between 21e9450 and 7d0dc1a.

📒 Files selected for processing (1)
  • backend/app/tests/celery/test_notifications.py

Comment on lines +373 to +381
_SLIM_KEYS = {
"id",
"run_name",
"dataset_name",
"status",
"run_mode",
"inserted_at",
"updated_at",
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Do not lock the callback to a partial run response.

The PR objective requires the webhook to include the full evaluation-run response. These assertions require a slim payload and explicitly exclude fields such as scores, traces, and costs. This will prevent webhook consumers from receiving the required result data.

Update the callback schema and these tests to validate the agreed full public run-response envelope.

Also applies to: 415-421, 448-452

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/tests/celery/test_notifications.py` around lines 373 - 381,
Update the callback schema and the related assertions in the notification tests
around _SLIM_KEYS and the referenced cases to validate the full public
evaluation-run response envelope. Remove the slim-payload restriction and ensure
fields such as scores, traces, and costs remain available to webhook consumers.

Comment on lines +383 to +385
def test_completed_run_delivers_slim_success_payload(
self, patched_session: Session
):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add narrow annotations to the new test methods.

Add a narrow type annotation for self and -> None for each test method. The repository rule applies to every Python function parameter and return value.

Proposed pattern
+from typing import Self

-    def test_completed_run_delivers_slim_success_payload(
-        self, patched_session: Session
-    ):
+    def test_completed_run_delivers_slim_success_payload(
+        self: Self, patched_session: Session
+    ) -> None:

Apply the same pattern to the remaining added test methods.

Also applies to: 423-423, 470-470, 481-481, 505-506

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/tests/celery/test_notifications.py` around lines 383 - 385, Add
narrow annotations to the added test methods, including
test_completed_run_delivers_slim_success_payload and the other newly introduced
tests, using the repository’s established test-class self type and an explicit
-> None return annotation for each method.

Source: Coding guidelines

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Evaluation: Add callback support for notifications

1 participant