Skip to content

fix: stop marking newly created apps as draft in playground#4569

Open
GanJiaKouN16 wants to merge 9 commits into
Agenta-AI:mainfrom
GanJiaKouN16:fix/playground-draft-tag-4556
Open

fix: stop marking newly created apps as draft in playground#4569
GanJiaKouN16 wants to merge 9 commits into
Agenta-AI:mainfrom
GanJiaKouN16:fix/playground-draft-tag-4556

Conversation

@GanJiaKouN16
Copy link
Copy Markdown

Problem

Playground shows an unexpected "draft" badge on the node name tag for newly created apps (#4556).

The workflowIsDirtyAtomFamily atom returned !!entityData when serverData was null. For ephemeral / newly-created entities (no server baseline yet), entityData always exists — so the expression evaluated to true, falsely marking every new app as dirty.

Fix

Changed the !serverData fallback from return !!entityData to return false. An entity with no server baseline is clean until the user makes actual edits.

This is safe because:

  • Local drafts cloned from a server revision always have serverData (the source revision's data is fetched via the redirect chain in workflowServerDataSelectorFamily).
  • Ephemeral entities (created from templates, never saved) have no server baseline — returning false is correct since the entity starts in its template-defined state.
  • The variable-level draft badges (VariableCard) are a separate mechanism and remain unchanged — they correctly guide users to fill in template variables.

Testing

  • Create a new simple completion app → node name tag should NOT show "draft"
  • Edit a prompt parameter → "draft" badge appears
  • Save → "draft" badge disappears
  • Variable cards still show "draft" for unfilled {{variables}} (correct behavior)

Fixes #4556

Wire the existing GenerateResetLinkModal and PasswordResetLinkModal
into the Actions dropdown in the workspace members table.

- Add 'Reset password' menu item for workspace members (not self)
- Add resetPassword API function in profile service
- Show confirmation dialog before generating the reset link
- Display the generated password reset link with copy functionality

Closes Agenta-AI#2572
Several tables with row-level click navigation were missing the
shouldIgnoreRowClick guard, causing clicks on interactive elements
(checkboxes, dropdowns, buttons) to accidentally trigger row navigation.

Changes:
- Consolidate shouldIgnoreRowClick with broader selector list (merges
  EvaluationRunsTablePOC's extra selectors: [role='button'],
  [role='menuitem'], [role='checkbox'], .ant-btn, etc.)
- Export INTERACTIVE_ROW_SELECTORS constant for reuse
- Add guard to ObservabilityTable (traces)
- Add guard to SessionsTable
- Add guard to PromptsPage
- Add guard to TestcasesTableShell
- Add guard to EntityTable
- Replace partial data-ivt-stop-row-click check in ScenarioListView
  with full shouldIgnoreRowClick
- Update useEntityTableState to use consolidated selectors
- Remove duplicate shouldIgnoreRowClick from navigationActions.ts
- Update EvaluationRunsTablePOC to import from shared utility

Closes Agenta-AI#3254
The evaluation table was showing a generic 'too many requests' message
instead of the actual provider error because:

1. executeViaFetch never checked for body-level errors on HTTP 200.
   The Python SDK can return HTTP 200 with a non-200 status.code
   embedded in the response body (WorkflowBatchResponse.status.code).
   This path was silently treated as success.

2. Error stacktrace/type/code were not propagated through the pipeline.
   Even when the HTTP error path was taken, only the message was
   extracted — the SDK's status.type, status.code, and status.stacktrace
   were dropped.

Changes:
- executeViaFetch: detect body-level errors on HTTP 200 by checking
  responseData.status.code !== 200 and return an error result
- executeViaFetch: extract stacktrace (coercing string[] to string),
  type, and code from both HTTP-error and body-error paths
- Add stacktrace and type to ExecutionResult, RunResult, and
  ExecuteWorkflowRevisionResult error shapes
- runInvocationAction: pass stacktrace and type through to
  upsertStepResultWithInvocation
- upsertStepResultWithInvocation: accept type field in error param

No UI changes needed — InvocationCell already renders stepError.message
and stepError.stacktrace when present; extractStepError already reads
error.code, error.type, error.stacktrace from persisted step data.

Closes Agenta-AI#3324
…iddleware

The vault middleware built env var names using f'{provider.upper()}_API_KEY'
which produces TOGETHER_AI_API_KEY for the 'together_ai' provider kind.
The actual env var is TOGETHERAI_API_KEY (no underscore), matching the
frontend (llmProviders.ts, transforms.ts), backend (env.py), and the
Daytona sandbox runner (daytona.py).

Add an explicit _PROVIDER_ENV_VAR_MAP dict (mirroring the Daytona runner
pattern) that maps each provider kind to its correct env var name, with
fallback to the original f-string pattern for any future providers.

Closes Agenta-AI#3659
… drawer

The 'Open evaluator registry' button in the Trace Drawer's
EvaluatorDetailsPopover navigated human evaluators to the registry
page (/evaluators?tab=human&openEvaluator=...) instead of the
evaluator playground. Automatic evaluators already linked correctly.

Unify both evaluator types to navigate to the playground
(/evaluators/playground?revisions=...), consistent with how other
parts of the codebase link to evaluators (EvaluatorSection,
ConfigurationView). Update button text to 'Open evaluator playground'.

Closes Agenta-AI#4535
Replace the SendGrid-only email backend with SMTP support, keeping
SendGrid as a legacy fallback for existing deployments.

Changes:
- email_service.py: use smtplib for SMTP (priority), SendGrid as
  fallback, no-op when neither is configured
- env.py: add SmtpConfig (SMTP_HOST, SMTP_PORT, SMTP_USERNAME,
  SMTP_PASSWORD, SMTP_FROM_ADDRESS, SMTP_USE_TLS), keep SendgridConfig
  for backwards compatibility; update AuthFacade.email_method to check
  both
- OSS/EE organization_service.py: use env.smtp.enabled || env.sendgrid
  .enabled; use configured from_address instead of hardcoded email
- user_service.py: same email-enabled check update
- db_manager_ee.py: remove dead sendgrid import and unused sg client
- pyproject.toml: remove sendgrid dependency (imported lazily only when
  SENDGRID_API_KEY is set)
- env example files: add SMTP vars, mark SendGrid as legacy
- docs: add SMTP config table, mark SendGrid as legacy

Closes Agenta-AI#4536
The breadcrumb always showed 'Auto Evals' for SDK evaluations because:

1. test.tsx normalized type='custom' to 'auto' before passing to
   EvalRunPreviewPage, losing the SDK type information
2. Page.tsx typeMap had no 'custom' entry
3. buildBreadcrumbs.ts hardcoded 'auto evaluation' as fallback label

Fix:
- Remove the custom→auto normalization in test.tsx
- Add 'custom' → 'SDK Evals' entry to Page.tsx typeMap (matches the
  tab label in EvaluationsView.tsx)
- Change buildBreadcrumbs.ts fallback from 'auto evaluation' to
  'Evaluations'

Closes Agenta-AI#4549
Add Playwright acceptance tests for the annotation queue feature,
following the existing human-annotation test patterns.

Tests cover (WEB-ACC-ANNOTATION-001 through 006):
1. Navigate to annotation queues page and verify empty state or list
2. Create a new annotation queue with testcases kind
3. Create a new annotation queue with traces kind
4. Open a queue detail page by clicking a queue row
5. Search for annotation queues by name
6. Delete an annotation queue via the actions menu

Structure mirrors human-annotation/:
- annotation-queue.spec.ts — entry point
- index.ts — test definitions with tags
- tests.ts — fixtures (navigateToAnnotations, createAnnotationQueue)
- assets/types.ts — type definitions

Closes Agenta-AI#4528
The  atom returned  when
 was null. For ephemeral/newly-created entities (no server
baseline),  always exists, so every new app was falsely
marked as dirty — showing an unexpected "draft" badge on the node
name tag in SingleLayout.

Change the fallback to : an entity with no server
baseline is clean until the user makes actual edits.

Fixes Agenta-AI#4556
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 6, 2026

Someone is attempting to deploy a commit to the agenta projects Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 6, 2026

CLA assistant check
All committers have signed the CLA.

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working Frontend labels Jun 6, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • SMTP added as the primary email backend; SendGrid marked legacy.
    • Password reset flow for workspace members (UI + API client).
    • Annotation Queue end-to-end acceptance tests added.
  • Improvements

    • Dynamic email sender selection and broader email enablement checks.
    • Richer error payloads (type, stacktrace) surface across runtimes.
    • Improved table row click handling and evaluator navigation (playground); added SDK Evals.
  • Documentation

    • Added SMTP configuration docs and updated example env files.

Walkthrough

This PR implements SMTP email backend support (SMTP-first, SendGrid fallback), enriches execution error payloads with type/stacktrace, centralizes row-click suppression selectors and migrates consumers, adds evaluation-type/navigation tweaks, implements workspace member password-reset UI+API, and adds annotation-queue Playwright tests.

Changes

Email Infrastructure: SMTP Support

Layer / File(s) Summary
SMTP Configuration Model
api/oss/src/utils/env.py
Adds SmtpConfig model (host, port, username, password, from_address, use_tls), exposes env.smtp, and updates AuthFacade.email_method to treat SMTP or SendGrid as enabling email OTP.
Email Service Backend Dispatch
api/oss/src/services/email_service.py
Implements SMTP send helper (_send_via_smtp), conditional SendGrid init and _send_via_sendgrid, and dispatches in send_email; no-ops when neither backend enabled.
Service Email Integration
api/ee/src/services/organization_service.py, api/oss/src/services/organization_service.py, api/oss/src/services/user_service.py
Gate invitation and reset flows on env.smtp.enabled or env.sendgrid.enabled, resolve from_address preferring SMTP then SendGrid (with fallbacks/validation), and pass from_email to send_email.
Dependency & Docs
api/ee/src/services/db_manager_ee.py, api/pyproject.toml, docs/docs/self-host/02-configuration.mdx, hosting/docker-compose/*/env.*.example
Removes module-level SendGrid client in EE and SendGrid dependency; adds SMTP docs and example env vars; marks SendGrid as legacy.

Execution Error Enrichment

Layer / File(s) Summary
Error Type Definitions
web/packages/agenta-entities/src/runnable/types.ts, web/packages/agenta-playground/src/state/execution/types.ts, web/packages/agenta-playground/src/executeWorkflowRevision.ts, web/oss/src/services/evaluations/invocations/api.ts
Extends error shapes to include optional type and stacktrace alongside message and code.
Error Parsing and Fetch Execution
web/packages/agenta-playground/src/state/execution/executionRunner.ts
Parses code, type, and stacktrace from HTTP and body-level failures, formats stacktraces, attaches trace metadata, and returns enriched ExecutionResult on failures.
Error Persistence in Results
web/oss/src/components/EvalRunDetails/atoms/runInvocationAction.ts
Persists expanded error payload (message, optional stacktrace, optional type) for failed invocation steps.

Interactive Row Click Refactoring

Layer / File(s) Summary
Centralized Interactive Selectors
web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
Adds INTERACTIVE_ROW_SELECTORS (consolidated CSS selectors) and refactors shouldIgnoreRowClick to use target.closest(INTERACTIVE_ROW_SELECTORS).
Shared Import and Local Cleanup
web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts, web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts
Removes local helper exports and updates consumers to import shared selector/guard and derive defaults from the consolidated selector.
Table Component Adoption
multiple table components across OSS and packages
Multiple table components now pass the click event into row handlers and early-return when shouldIgnoreRowClick(event) is true to avoid navigating/toggling on interactive-element clicks.

Evaluation Types, Navigation, and Features

Layer / File(s) Summary
Evaluation Type and Navigation Updates
web/oss/src/components/EvalRunDetails/components/Page.tsx, web/oss/src/components/EvalRunDetails/test.tsx, web/oss/src/components/SharedDrawers/TraceDrawer/hooks/useEvaluatorNavigation.ts, web/oss/src/lib/helpers/buildBreadcrumbs.ts
Adds custom evaluation mapping ("SDK Evals"), preserves type==='custom' in test page state, routes evaluator links to playground revisions with type param, and updates breadcrumb label to "Evaluations".
Password Reset Feature
web/oss/src/services/profile/index.ts, web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx
Adds resetPassword API that returns a reset link and UI modals/actions to generate and display password-reset links for workspace members with loading/error handling.
Annotation Queue Test Suite
web/oss/tests/playwright/acceptance/annotation-queue/*
Adds Playwright fixtures and acceptance tests covering listing, creation (testcases/traces), detail navigation, name search, and deletion flows.
Workflow & SDK tweaks
web/packages/agenta-entities/src/workflow/state/store.ts, sdks/python/agenta/sdk/middlewares/running/vault.py
Treats missing server baseline as not dirty; adds provider-kind->env-var mapping for local secrets lookup.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The changeset includes extensive modifications to email/SMTP configuration, SDK evaluations error handling, table row-click behavior, password reset functionality, annotation queue tests, and other unrelated features that go well beyond the stated objective of fixing the draft badge issue. Review and separate the email/SMTP changes, evaluation error handling, table interactions, password reset, annotation queue tests, and other features into distinct pull requests aligned with their specific objectives, keeping only the workflowIsDirtyAtomFamily fix in this PR.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and specifically describes the main change: fixing the issue where newly created apps incorrectly show a 'draft' badge in the playground.
Description check ✅ Passed The description provides comprehensive context about the problem, the fix, and the rationale, and is directly related to the changeset addressing the draft badge issue for newly created apps.
Linked Issues check ✅ Passed The PR addresses issue #4556 by fixing the workflowIsDirtyAtomFamily logic to return false for entities with no server baseline, which directly resolves the symptom of unwanted draft badges on newly created apps.
Docstring Coverage ✅ Passed Docstring coverage is 86.67% which is sufficient. The required threshold is 60.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
web/packages/agenta-playground/src/state/execution/executionRunner.ts (1)

671-742: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

The new error metadata still gets dropped on the persisted execution paths.

This runner now returns type and stacktrace, but the provided reducer snippet still accepts only {message; code?}, and the chat path in webWorkerIntegration.ts forwards only err.message. The new fields will not survive into stored RunResults until those downstream writers are widened too.

web/oss/src/components/EvalRunDetails/components/Page.tsx (1)

26-30: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Expand evaluationType prop union to include "custom"

Line 28 currently excludes "custom", but the caller now passes it through. This creates a TypeScript contract break (assignability/build failure).

🔧 Proposed fix
 interface EvalRunPreviewPageProps {
     runId: string
-    evaluationType: "auto" | "human" | "online"
+    evaluationType: "auto" | "human" | "online" | "custom"
     projectId?: string | null
 }

Also applies to: 49-52

🧹 Nitpick comments (1)
api/oss/src/services/email_service.py (1)

47-47: ⚡ Quick win

Adopt keyword-only parameters for new helper signatures.

These new helper signatures should use * to enforce keyword-only args per API conventions.

Proposed fix
-def _send_via_smtp(to_email: str, subject: str, html_content: str, from_email: str) -> None:
+def _send_via_smtp(
+    *,
+    to_email: str,
+    subject: str,
+    html_content: str,
+    from_email: str,
+) -> None:
@@
-def _send_via_sendgrid(to_email: str, subject: str, html_content: str, from_email: str) -> None:
+def _send_via_sendgrid(
+    *,
+    to_email: str,
+    subject: str,
+    html_content: str,
+    from_email: str,
+) -> None:

As per coding guidelines, “Prefer keyword-only parameters using * in function signatures.”

Also applies to: 74-74

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b89d5f05-4ac7-4227-a7e4-f2bd7d261e81

📥 Commits

Reviewing files that changed from the base of the PR and between 98b8a9d and 2a8d74c.

📒 Files selected for processing (42)
  • api/ee/src/services/db_manager_ee.py
  • api/ee/src/services/organization_service.py
  • api/oss/src/services/email_service.py
  • api/oss/src/services/organization_service.py
  • api/oss/src/services/user_service.py
  • api/oss/src/utils/env.py
  • api/pyproject.toml
  • docs/docs/self-host/02-configuration.mdx
  • hosting/docker-compose/ee/env.ee.dev.example
  • hosting/docker-compose/ee/env.ee.gh.example
  • hosting/docker-compose/oss/env.oss.dev.example
  • hosting/docker-compose/oss/env.oss.gh.example
  • sdks/python/agenta/sdk/middlewares/running/vault.py
  • web/oss/src/components/EvalRunDetails/atoms/runInvocationAction.ts
  • web/oss/src/components/EvalRunDetails/components/Page.tsx
  • web/oss/src/components/EvalRunDetails/test.tsx
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts
  • web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx
  • web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/oss/src/components/SharedDrawers/TraceDrawer/components/EvaluatorDetailsPopover.tsx
  • web/oss/src/components/SharedDrawers/TraceDrawer/hooks/useEvaluatorNavigation.ts
  • web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
  • web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
  • web/oss/src/components/pages/observability/components/SessionsTable/index.tsx
  • web/oss/src/components/pages/prompts/PromptsPage.tsx
  • web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx
  • web/oss/src/lib/helpers/buildBreadcrumbs.ts
  • web/oss/src/services/evaluations/invocations/api.ts
  • web/oss/src/services/profile/index.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/annotation-queue.spec.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/assets/types.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/index.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/tests.ts
  • web/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsx
  • web/packages/agenta-entities/src/runnable/types.ts
  • web/packages/agenta-entities/src/workflow/state/store.ts
  • web/packages/agenta-entity-ui/src/shared/EntityTable.tsx
  • web/packages/agenta-playground/src/executeWorkflowRevision.ts
  • web/packages/agenta-playground/src/state/execution/executionRunner.ts
  • web/packages/agenta-playground/src/state/execution/types.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
💤 Files with no reviewable changes (3)
  • api/pyproject.toml
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts
  • api/ee/src/services/db_manager_ee.py

Comment on lines +111 to +114
if _USE_SMTP:
_send_via_smtp(to_email, subject, html_content, from_email)
else:
_send_via_sendgrid(to_email, subject, html_content, from_email)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Offload blocking backend sends from the async request path.

send_email is async, but both backend calls here are synchronous network I/O. A slow SMTP/SendGrid call can block the event loop and hurt API responsiveness.

Proposed fix
+import asyncio
 import os
 import smtplib
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
@@
     try:
         if _USE_SMTP:
-            _send_via_smtp(to_email, subject, html_content, from_email)
+            await asyncio.to_thread(
+                _send_via_smtp,
+                to_email=to_email,
+                subject=subject,
+                html_content=html_content,
+                from_email=from_email,
+            )
         else:
-            _send_via_sendgrid(to_email, subject, html_content, from_email)
+            await asyncio.to_thread(
+                _send_via_sendgrid,
+                to_email=to_email,
+                subject=subject,
+                html_content=html_content,
+                from_email=from_email,
+            )
         return True
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if _USE_SMTP:
_send_via_smtp(to_email, subject, html_content, from_email)
else:
_send_via_sendgrid(to_email, subject, html_content, from_email)
if _USE_SMTP:
await asyncio.to_thread(
_send_via_smtp,
to_email=to_email,
subject=subject,
html_content=html_content,
from_email=from_email,
)
else:
await asyncio.to_thread(
_send_via_sendgrid,
to_email=to_email,
subject=subject,
html_content=html_content,
from_email=from_email,
)

Comment thread api/oss/src/utils/env.py
or os.getenv("AGENTA_AUTHN_EMAIL_FROM")
or os.getenv("AGENTA_SEND_EMAIL_FROM_ADDRESS")
)
use_tls: bool = os.getenv("SMTP_USE_TLS", "true").lower() in ("true", "1", "yes")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the shared truthy parser for SMTP_USE_TLS to avoid config surprises.

SMTP_USE_TLS currently accepts fewer true-like values than other config flags (_TRUTHY), so values like on/enabled behave inconsistently.

Proposed fix
-    use_tls: bool = os.getenv("SMTP_USE_TLS", "true").lower() in ("true", "1", "yes")
+    use_tls: bool = (os.getenv("SMTP_USE_TLS") or "true").lower() in _TRUTHY

Comment thread docs/docs/self-host/02-configuration.mdx
Comment on lines 56 to +59
export const shouldIgnoreRowClick = (event: MouseEvent<HTMLElement>): boolean => {
const target = event.target as HTMLElement

// Check if clicking on interactive elements
if (
target.closest("button") ||
target.closest("a") ||
target.closest(".ant-dropdown-trigger") ||
target.closest(".ant-checkbox-wrapper") ||
target.closest(".ant-select") ||
target.closest("input") ||
target.closest("textarea")
) {
return true
}

return false
if (!target) return false
return Boolean(target.closest(INTERACTIVE_ROW_SELECTORS))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Locate the implementation in OSS and any other copies
rg -n "shouldIgnoreRowClick" -S .

# 2) Show the exact code around the referenced lines in the OSS file
FILE="web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx"
if [ -f "$FILE" ]; then
  echo "----- $FILE (relevant section) -----"
  nl -ba "$FILE" | sed -n '40,90p'
fi

# 3) Also inspect the corresponding table manager hook in other packages (if present)
#    (Keep it broad: we only need to find sibling/EE or shared copies.)
rg -n "useTableManager\.tsx" -S web || true

Repository: Agenta-AI/agenta

Length of output: 2995


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show exact implementations in both OSS and agenta-ui (shared)
for FILE in \
  "web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx" \
  "web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx"
do
  echo "===== $FILE (shouldIgnoreRowClick) ====="
  sed -n '1,140p' "$FILE" | rg -n "shouldIgnoreRowClick|INTERACTIVE_ROW_SELECTORS" -n || true
  # Print a tighter window around the function definition
  rg -n "export const shouldIgnoreRowClick" "$FILE" -n | while read -r line; do :; done
  START=$(rg -n "export const shouldIgnoreRowClick" "$FILE" | head -n1 | cut -d: -f1)
  # fall back
  if [ -z "${START:-}" ]; then START=40; fi
  sed -n "$((START-5)),$((START+25))p" "$FILE"
  echo
done

# Also inspect the OSS re-export line to understand parity/ownership
rg -n "export \\{useTableManager, shouldIgnoreRowClick\\}" web/oss/src/components/InfiniteVirtualTable/index.ts || true

Repository: Agenta-AI/agenta

Length of output: 3151


Guard event.target before calling closest in shouldIgnoreRowClick

shouldIgnoreRowClick in both web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx and web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx casts event.target as HTMLElement and then calls target.closest(...), which can throw if the runtime target isn’t an Element.

Proposed fix
 export const shouldIgnoreRowClick = (event: MouseEvent<HTMLElement>): boolean => {
-    const target = event.target as HTMLElement
-    if (!target) return false
-    return Boolean(target.closest(INTERACTIVE_ROW_SELECTORS))
+    const target = event.target
+    if (!(target instanceof Element)) return false
+    return target.closest(INTERACTIVE_ROW_SELECTORS) !== null
 }

Comment on lines +64 to +70
export const resetPassword = async (userId: string): Promise<string> => {
const base = getBaseUrl()
const url = new URL("api/profile/reset-password", base)
url.searchParams.set("user_id", userId)
const data = await fetchJson<string>(url, {
method: "POST",
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Use the Fern-generated client for this new API method.

This new frontend API call is implemented via fetchJson instead of the Fern client; please route it through getAgentaSdkClient({host: getAgentaApiUrl()}) to keep API contracts centralized and typed.

As per coding guidelines: “All new frontend API code must go through the Fern-generated client, not raw axios.”

Source: Coding guidelines

const base = getBaseUrl()
const url = new URL("api/profile/reset-password", base)
url.searchParams.set("user_id", userId)
const data = await fetchJson<string>(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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Checking fetchJson declaration(s)..."
rg -n --type=ts 'export\s+async\s+function\s+fetchJson\s*<' web/oss/src/lib/api/assets/fetchClient.ts || true
rg -n --type=ts 'export\s+async\s+function\s+fetchJson\s*\(' web/oss/src/lib/api/assets/fetchClient.ts

echo
echo "Checking typed invocations of fetchJson..."
rg -n --type=ts 'fetchJson<[^>]+>\(' web/oss/src/services/profile/index.ts

Repository: Agenta-AI/agenta

Length of output: 278


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- resetPassword implementation ----"
sed -n '40,110p' web/oss/src/services/profile/index.ts | nl -ba

echo
echo "---- fetchJson definition ----"
sed -n '1,120p' web/oss/src/lib/api/assets/fetchClient.ts | nl -ba

Repository: Agenta-AI/agenta

Length of output: 160


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- resetPassword implementation (web/oss/src/services/profile/index.ts) ----"
sed -n '1,160p' web/oss/src/services/profile/index.ts | cat -n

echo
echo "---- fetchJson definition (web/oss/src/lib/api/assets/fetchClient.ts) ----"
sed -n '1,200p' web/oss/src/lib/api/assets/fetchClient.ts | cat -n

Repository: Agenta-AI/agenta

Length of output: 11720


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '190,280p' web/oss/src/lib/api/assets/fetchClient.ts | cat -n

Repository: Agenta-AI/agenta

Length of output: 611


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n --type=ts "safeParseWithLogging" web/oss/src/services/profile/index.ts web/oss/src/services/profile -S || true
rg -n --type=ts "safeParseWithLogging" web/oss/src/lib/api/assets -S || true

Repository: Agenta-AI/agenta

Length of output: 42


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- safeParseWithLogging occurrences (web/oss) ----"
rg -n --type=ts "safeParseWithLogging" web/oss/src -S || true

echo
echo "---- getAgentaSdkClient occurrences (web/oss) ----"
rg -n --type=ts "getAgentaSdkClient" web/oss/src -S || true

echo
echo "---- fetchJson calls in profile service ----"
rg -n --type=ts "fetchJson" web/oss/src/services/profile/index.ts

Repository: Agenta-AI/agenta

Length of output: 755


Fix TypeScript error and API-call guideline violations in resetPassword

  • web/oss/src/services/profile/index.ts:68 uses fetchJson<string>(...), but web/oss/src/lib/api/assets/fetchClient.ts:11 defines fetchJson(url: URL, init?: RequestInit): Promise<any> (non-generic), so the <string> type argument will not compile. Remove <string> and cast/validate the response as string.
  • resetPassword calls fetchJson directly instead of the Fern-generated client (getAgentaSdkClient({host: getAgentaApiUrl()})) and it returns raw data without safeParseWithLogging response validation at the API boundary.

Comment thread web/packages/agenta-entities/src/runnable/types.ts
Comment on lines 1625 to 1629
if (!serverData) {
return !!entityData
// No server baseline (ephemeral / newly created entity) —
// treat as clean until the user makes actual edits.
return false
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

This makes edited ephemeral workflows permanently look clean.

workflowServerDataSelectorFamily intentionally returns null for ephemeral entities (Lines 1847-1852). With this early return, a template-backed local-* workflow stays false even after a draft overlay exists, so the "edit → draft badge appears" behavior in this PR's objective regresses. Use the local baseline (workflowLocalServerDataAtomFamily) when no server baseline exists instead of returning false unconditionally.

@GanJiaKouN16 GanJiaKouN16 force-pushed the fix/playground-draft-tag-4556 branch from 2a8d74c to 77f3ec1 Compare June 6, 2026 16:00
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ea9bb7cb-75f4-43de-9393-1c77040dc82b

📥 Commits

Reviewing files that changed from the base of the PR and between 2a8d74c and 77f3ec1.

📒 Files selected for processing (42)
  • api/ee/src/services/db_manager_ee.py
  • api/ee/src/services/organization_service.py
  • api/oss/src/services/email_service.py
  • api/oss/src/services/organization_service.py
  • api/oss/src/services/user_service.py
  • api/oss/src/utils/env.py
  • api/pyproject.toml
  • docs/docs/self-host/02-configuration.mdx
  • hosting/docker-compose/ee/env.ee.dev.example
  • hosting/docker-compose/ee/env.ee.gh.example
  • hosting/docker-compose/oss/env.oss.dev.example
  • hosting/docker-compose/oss/env.oss.gh.example
  • sdks/python/agenta/sdk/middlewares/running/vault.py
  • web/oss/src/components/EvalRunDetails/atoms/runInvocationAction.ts
  • web/oss/src/components/EvalRunDetails/components/Page.tsx
  • web/oss/src/components/EvalRunDetails/test.tsx
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts
  • web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx
  • web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/oss/src/components/SharedDrawers/TraceDrawer/components/EvaluatorDetailsPopover.tsx
  • web/oss/src/components/SharedDrawers/TraceDrawer/hooks/useEvaluatorNavigation.ts
  • web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
  • web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
  • web/oss/src/components/pages/observability/components/SessionsTable/index.tsx
  • web/oss/src/components/pages/prompts/PromptsPage.tsx
  • web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx
  • web/oss/src/lib/helpers/buildBreadcrumbs.ts
  • web/oss/src/services/evaluations/invocations/api.ts
  • web/oss/src/services/profile/index.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/annotation-queue.spec.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/assets/types.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/index.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/tests.ts
  • web/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsx
  • web/packages/agenta-entities/src/runnable/types.ts
  • web/packages/agenta-entities/src/workflow/state/store.ts
  • web/packages/agenta-entity-ui/src/shared/EntityTable.tsx
  • web/packages/agenta-playground/src/executeWorkflowRevision.ts
  • web/packages/agenta-playground/src/state/execution/executionRunner.ts
  • web/packages/agenta-playground/src/state/execution/types.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
💤 Files with no reviewable changes (3)
  • api/pyproject.toml
  • api/ee/src/services/db_manager_ee.py
  • web/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.ts
✅ Files skipped from review due to trivial changes (4)
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.ts
  • docs/docs/self-host/02-configuration.mdx
  • hosting/docker-compose/oss/env.oss.dev.example
  • web/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsx
🚧 Files skipped from review as they are similar to previous changes (30)
  • web/oss/src/components/EvalRunDetails/atoms/runInvocationAction.ts
  • web/oss/src/components/pages/observability/components/ObservabilityTable/index.tsx
  • web/packages/agenta-playground/src/executeWorkflowRevision.ts
  • web/packages/agenta-playground/src/state/execution/types.ts
  • web/packages/agenta-entity-ui/src/shared/EntityTable.tsx
  • web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
  • web/oss/tests/playwright/acceptance/annotation-queue/assets/types.ts
  • web/oss/tests/playwright/acceptance/annotation-queue/annotation-queue.spec.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
  • api/oss/src/services/user_service.py
  • web/packages/agenta-entities/src/workflow/state/store.ts
  • web/oss/src/components/EvalRunDetails/components/Page.tsx
  • web/oss/src/components/EvalRunDetails/test.tsx
  • web/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsx
  • sdks/python/agenta/sdk/middlewares/running/vault.py
  • web/oss/src/components/SharedDrawers/TraceDrawer/hooks/useEvaluatorNavigation.ts
  • api/oss/src/services/organization_service.py
  • web/oss/src/components/pages/prompts/PromptsPage.tsx
  • web/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsx
  • web/oss/tests/playwright/acceptance/annotation-queue/index.ts
  • web/oss/src/services/profile/index.ts
  • hosting/docker-compose/ee/env.ee.dev.example
  • api/oss/src/services/email_service.py
  • hosting/docker-compose/oss/env.oss.gh.example
  • hosting/docker-compose/ee/env.ee.gh.example
  • api/ee/src/services/organization_service.py
  • api/oss/src/utils/env.py
  • web/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/oss/tests/playwright/acceptance/annotation-queue/tests.ts
  • web/packages/agenta-entities/src/runnable/types.ts

// The Python SDK's WorkflowBatchResponse may embed a non-200 status.code
// inside the response body even when the HTTP status is 200.
const bodyStatus = responseData?.status
if (bodyStatus && typeof bodyStatus === "object" && bodyStatus.code && bodyStatus.code !== 200) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Type-safe comparison needed for bodyStatus.code.

If the SDK returns code as a string (e.g., "200"), the strict comparison "200" !== 200 evaluates to true, incorrectly triggering the error path for successful responses. Normalize to number for safe comparison.

🐛 Proposed fix
-        if (bodyStatus && typeof bodyStatus === "object" && bodyStatus.code && bodyStatus.code !== 200) {
+        if (bodyStatus && typeof bodyStatus === "object" && bodyStatus.code && Number(bodyStatus.code) !== 200) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (bodyStatus && typeof bodyStatus === "object" && bodyStatus.code && bodyStatus.code !== 200) {
if (bodyStatus && typeof bodyStatus === "object" && bodyStatus.code && Number(bodyStatus.code) !== 200) {

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

Labels

bug Something isn't working Frontend size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Playground shows draft tags and messages unexpectedly

2 participants