diff --git a/apps/api/src/browserbase/browserbase.service.ts b/apps/api/src/browserbase/browserbase.service.ts index dc6a7176b8..c4c63d8dd4 100644 --- a/apps/api/src/browserbase/browserbase.service.ts +++ b/apps/api/src/browserbase/browserbase.service.ts @@ -15,6 +15,10 @@ import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; const BROWSER_WIDTH = 1440; const BROWSER_HEIGHT = 900; +/** Stagehand v3 requires 'provider/model' format. */ +const STAGEHAND_MODEL = 'anthropic/claude-sonnet-4-6'; +const STAGEHAND_CUA_MODEL = 'anthropic/claude-sonnet-4-6'; + const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const PENDING_CONTEXT_ID = '__PENDING__'; @@ -205,7 +209,7 @@ export class BrowserbaseService { projectId: this.getProjectId(), browserbaseSessionID: sessionId, model: { - modelName: 'claude-3-7-sonnet-latest', + modelName: STAGEHAND_MODEL, apiKey: process.env.ANTHROPIC_API_KEY, }, verbose: 1, @@ -784,7 +788,7 @@ export class BrowserbaseService { .agent({ cua: true, model: { - modelName: 'anthropic/claude-3-7-sonnet-latest', + modelName: STAGEHAND_CUA_MODEL, apiKey: process.env.ANTHROPIC_API_KEY, }, }) diff --git a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/BrowserAutomations.tsx b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/BrowserAutomations.tsx index 821c7d425a..fd529b5cff 100644 --- a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/BrowserAutomations.tsx +++ b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/components/BrowserAutomations.tsx @@ -130,6 +130,8 @@ export function BrowserAutomations({ taskId, isManualTask = false }: BrowserAuto onRun={execution.runAutomation} onCreateClick={isManualTask ? undefined : () => setDialogState({ open: true, mode: 'create' })} onEditClick={(automation) => setDialogState({ open: true, mode: 'edit', automation })} + onDelete={automations.deleteAutomation} + onToggleEnabled={automations.toggleAutomation} /> void; onRun: () => void; onEdit: () => void; + onDelete: () => void; + onToggleEnabled: (enabled: boolean) => void; } export function AutomationItem({ @@ -25,23 +36,30 @@ export function AutomationItem({ onToggleExpand, onRun, onEdit, + onDelete, + onToggleEnabled, }: AutomationItemProps) { + const [confirmDelete, setConfirmDelete] = useState(false); const runs: BrowserAutomationRun[] = automation.runs || []; const latestRun = runs[0]; // status dot const hasFailed = latestRun?.status === 'failed'; const isCompleted = latestRun?.status === 'completed'; - const dotColor = hasFailed - ? 'bg-destructive shadow-[0_0_8px_rgba(255,0,0,0.3)]' - : isCompleted - ? 'bg-primary shadow-[0_0_8px_rgba(0,77,64,0.4)]' - : 'bg-muted-foreground'; + const isDisabled = !automation.isEnabled; + const dotColor = isDisabled + ? 'bg-muted-foreground/40' + : hasFailed + ? 'bg-destructive shadow-[0_0_8px_rgba(255,0,0,0.3)]' + : isCompleted + ? 'bg-primary shadow-[0_0_8px_rgba(0,77,64,0.4)]' + : 'bg-muted-foreground'; return (
-

- {automation.name} -

+
+

+ {automation.name} +

+ {isDisabled && ( + + Paused + + )} +
{latestRun ? (

Last ran {formatDistanceToNow(new Date(latestRun.createdAt), { addSuffix: true })} @@ -63,15 +88,75 @@ export function AutomationItem({ )}

-
+
{!readOnly && ( - )} {!readOnly && ( - + )} + + {!readOnly && ( + confirmDelete ? ( +
+ + +
+ ) : ( + + ) + )} + + {!readOnly && ( +