fix: stop marking newly created apps as draft in playground#4569
fix: stop marking newly created apps as draft in playground#4569GanJiaKouN16 wants to merge 9 commits into
Conversation
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
|
Someone is attempting to deploy a commit to the agenta projects Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis 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. ChangesEmail Infrastructure: SMTP Support
Execution Error Enrichment
Interactive Row Click Refactoring
Evaluation Types, Navigation, and Features
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 winThe new error metadata still gets dropped on the persisted execution paths.
This runner now returns
typeandstacktrace, but the provided reducer snippet still accepts only{message; code?}, and the chat path inwebWorkerIntegration.tsforwards onlyerr.message. The new fields will not survive into storedRunResults until those downstream writers are widened too.web/oss/src/components/EvalRunDetails/components/Page.tsx (1)
26-30:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winExpand
evaluationTypeprop 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 winAdopt 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
📒 Files selected for processing (42)
api/ee/src/services/db_manager_ee.pyapi/ee/src/services/organization_service.pyapi/oss/src/services/email_service.pyapi/oss/src/services/organization_service.pyapi/oss/src/services/user_service.pyapi/oss/src/utils/env.pyapi/pyproject.tomldocs/docs/self-host/02-configuration.mdxhosting/docker-compose/ee/env.ee.dev.examplehosting/docker-compose/ee/env.ee.gh.examplehosting/docker-compose/oss/env.oss.dev.examplehosting/docker-compose/oss/env.oss.gh.examplesdks/python/agenta/sdk/middlewares/running/vault.pyweb/oss/src/components/EvalRunDetails/atoms/runInvocationAction.tsweb/oss/src/components/EvalRunDetails/components/Page.tsxweb/oss/src/components/EvalRunDetails/test.tsxweb/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.tsweb/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsxweb/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsxweb/oss/src/components/SharedDrawers/TraceDrawer/components/EvaluatorDetailsPopover.tsxweb/oss/src/components/SharedDrawers/TraceDrawer/hooks/useEvaluatorNavigation.tsweb/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsxweb/oss/src/components/pages/observability/components/ObservabilityTable/index.tsxweb/oss/src/components/pages/observability/components/SessionsTable/index.tsxweb/oss/src/components/pages/prompts/PromptsPage.tsxweb/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsxweb/oss/src/lib/helpers/buildBreadcrumbs.tsweb/oss/src/services/evaluations/invocations/api.tsweb/oss/src/services/profile/index.tsweb/oss/tests/playwright/acceptance/annotation-queue/annotation-queue.spec.tsweb/oss/tests/playwright/acceptance/annotation-queue/assets/types.tsweb/oss/tests/playwright/acceptance/annotation-queue/index.tsweb/oss/tests/playwright/acceptance/annotation-queue/tests.tsweb/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsxweb/packages/agenta-entities/src/runnable/types.tsweb/packages/agenta-entities/src/workflow/state/store.tsweb/packages/agenta-entity-ui/src/shared/EntityTable.tsxweb/packages/agenta-playground/src/executeWorkflowRevision.tsweb/packages/agenta-playground/src/state/execution/executionRunner.tsweb/packages/agenta-playground/src/state/execution/types.tsweb/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.tsweb/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
| if _USE_SMTP: | ||
| _send_via_smtp(to_email, subject, html_content, from_email) | ||
| else: | ||
| _send_via_sendgrid(to_email, subject, html_content, from_email) |
There was a problem hiding this comment.
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.
| 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, | |
| ) |
| 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") |
There was a problem hiding this comment.
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| 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)) |
There was a problem hiding this comment.
🧩 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 || trueRepository: 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 || trueRepository: 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
}| 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", | ||
| }) |
There was a problem hiding this comment.
🛠️ 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, { |
There was a problem hiding this comment.
🧩 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.tsRepository: 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 -baRepository: 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 -nRepository: 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 -nRepository: 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 || trueRepository: 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.tsRepository: Agenta-AI/agenta
Length of output: 755
Fix TypeScript error and API-call guideline violations in resetPassword
web/oss/src/services/profile/index.ts:68usesfetchJson<string>(...), butweb/oss/src/lib/api/assets/fetchClient.ts:11definesfetchJson(url: URL, init?: RequestInit): Promise<any>(non-generic), so the<string>type argument will not compile. Remove<string>and cast/validate the response asstring.resetPasswordcallsfetchJsondirectly instead of the Fern-generated client (getAgentaSdkClient({host: getAgentaApiUrl()})) and it returns raw data withoutsafeParseWithLoggingresponse validation at the API boundary.
| if (!serverData) { | ||
| return !!entityData | ||
| // No server baseline (ephemeral / newly created entity) — | ||
| // treat as clean until the user makes actual edits. | ||
| return false | ||
| } |
There was a problem hiding this comment.
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.
2a8d74c to
77f3ec1
Compare
There was a problem hiding this comment.
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
📒 Files selected for processing (42)
api/ee/src/services/db_manager_ee.pyapi/ee/src/services/organization_service.pyapi/oss/src/services/email_service.pyapi/oss/src/services/organization_service.pyapi/oss/src/services/user_service.pyapi/oss/src/utils/env.pyapi/pyproject.tomldocs/docs/self-host/02-configuration.mdxhosting/docker-compose/ee/env.ee.dev.examplehosting/docker-compose/ee/env.ee.gh.examplehosting/docker-compose/oss/env.oss.dev.examplehosting/docker-compose/oss/env.oss.gh.examplesdks/python/agenta/sdk/middlewares/running/vault.pyweb/oss/src/components/EvalRunDetails/atoms/runInvocationAction.tsweb/oss/src/components/EvalRunDetails/components/Page.tsxweb/oss/src/components/EvalRunDetails/test.tsxweb/oss/src/components/EvaluationRunsTablePOC/actions/navigationActions.tsweb/oss/src/components/EvaluationRunsTablePOC/components/EvaluationRunsTable/index.tsxweb/oss/src/components/InfiniteVirtualTable/hooks/useTableManager.tsxweb/oss/src/components/SharedDrawers/TraceDrawer/components/EvaluatorDetailsPopover.tsxweb/oss/src/components/SharedDrawers/TraceDrawer/hooks/useEvaluatorNavigation.tsweb/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsxweb/oss/src/components/pages/observability/components/ObservabilityTable/index.tsxweb/oss/src/components/pages/observability/components/SessionsTable/index.tsxweb/oss/src/components/pages/prompts/PromptsPage.tsxweb/oss/src/components/pages/settings/WorkspaceManage/cellRenderers.tsxweb/oss/src/lib/helpers/buildBreadcrumbs.tsweb/oss/src/services/evaluations/invocations/api.tsweb/oss/src/services/profile/index.tsweb/oss/tests/playwright/acceptance/annotation-queue/annotation-queue.spec.tsweb/oss/tests/playwright/acceptance/annotation-queue/assets/types.tsweb/oss/tests/playwright/acceptance/annotation-queue/index.tsweb/oss/tests/playwright/acceptance/annotation-queue/tests.tsweb/packages/agenta-annotation-ui/src/components/AnnotationSession/ScenarioListView.tsxweb/packages/agenta-entities/src/runnable/types.tsweb/packages/agenta-entities/src/workflow/state/store.tsweb/packages/agenta-entity-ui/src/shared/EntityTable.tsxweb/packages/agenta-playground/src/executeWorkflowRevision.tsweb/packages/agenta-playground/src/state/execution/executionRunner.tsweb/packages/agenta-playground/src/state/execution/types.tsweb/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useEntityTableState.tsweb/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) { |
There was a problem hiding this comment.
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.
| if (bodyStatus && typeof bodyStatus === "object" && bodyStatus.code && bodyStatus.code !== 200) { | |
| if (bodyStatus && typeof bodyStatus === "object" && bodyStatus.code && Number(bodyStatus.code) !== 200) { |
Problem
Playground shows an unexpected "draft" badge on the node name tag for newly created apps (#4556).
The
workflowIsDirtyAtomFamilyatom returned!!entityDatawhenserverDatawasnull. For ephemeral / newly-created entities (no server baseline yet),entityDataalways exists — so the expression evaluated totrue, falsely marking every new app as dirty.Fix
Changed the
!serverDatafallback fromreturn !!entityDatatoreturn false. An entity with no server baseline is clean until the user makes actual edits.This is safe because:
serverData(the source revision's data is fetched via the redirect chain inworkflowServerDataSelectorFamily).falseis correct since the entity starts in its template-defined state.VariableCard) are a separate mechanism and remain unchanged — they correctly guide users to fill in template variables.Testing
{{variables}}(correct behavior)Fixes #4556