chore: ran linting

This commit is contained in:
Anish Sarkar 2026-03-21 13:20:13 +05:30
parent 772150eb66
commit de8841fb86
110 changed files with 2673 additions and 1918 deletions

View file

@ -1,13 +1,13 @@
"use client";
import { makeAssistantToolUI } from "@assistant-ui/react";
import {
CornerDownLeftIcon,
Pen,
UserIcon,
UsersIcon,
} from "lucide-react";
import { useSetAtom } from "jotai";
import { CornerDownLeftIcon, Pen, UserIcon, UsersIcon } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import type { ExtraField } from "@/atoms/chat/hitl-edit-panel.atom";
import { openHitlEditPanelAtom } from "@/atoms/chat/hitl-edit-panel.atom";
import { PlateEditor } from "@/components/editor/plate-editor";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { Button } from "@/components/ui/button";
import {
Select,
@ -16,11 +16,6 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { PlateEditor } from "@/components/editor/plate-editor";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { useSetAtom } from "jotai";
import { openHitlEditPanelAtom } from "@/atoms/chat/hitl-edit-panel.atom";
import type { ExtraField } from "@/atoms/chat/hitl-edit-panel.atom";
import { useHitlPhase } from "@/hooks/use-hitl-phase";
interface GmailAccount {
@ -132,7 +127,11 @@ function ApprovalCard({
const [isPanelOpen, setIsPanelOpen] = useState(false);
const openHitlEditPanel = useSetAtom(openHitlEditPanelAtom);
const [pendingEdits, setPendingEdits] = useState<{
subject: string; body: string; to: string; cc: string; bcc: string;
subject: string;
body: string;
to: string;
cc: string;
bcc: string;
} | null>(null);
const accounts = interruptData.context?.accounts ?? [];
@ -175,7 +174,18 @@ function ApprovalCard({
},
},
});
}, [phase, isPanelOpen, canApprove, allowedDecisions, setProcessing, onDecision, interruptData, args, selectedAccountId, pendingEdits]);
}, [
phase,
isPanelOpen,
canApprove,
allowedDecisions,
setProcessing,
onDecision,
interruptData,
args,
selectedAccountId,
pendingEdits,
]);
useEffect(() => {
const handler = (e: KeyboardEvent) => {
@ -200,16 +210,17 @@ function ApprovalCard({
? "Gmail Draft Approved"
: "Create Gmail Draft"}
</p>
{phase === "processing" ? (
<TextShimmerLoader text={pendingEdits ? "Creating draft with your changes" : "Creating draft"} size="sm" />
{phase === "processing" ? (
<TextShimmerLoader
text={pendingEdits ? "Creating draft with your changes" : "Creating draft"}
size="sm"
/>
) : phase === "complete" ? (
<p className="text-xs text-muted-foreground mt-0.5">
{pendingEdits ? "Draft created with your changes" : "Draft created"}
</p>
) : phase === "rejected" ? (
<p className="text-xs text-muted-foreground mt-0.5">
Draft creation was cancelled
</p>
<p className="text-xs text-muted-foreground mt-0.5">Draft creation was cancelled</p>
) : (
<p className="text-xs text-muted-foreground mt-0.5">
Requires your approval to proceed
@ -225,13 +236,28 @@ function ApprovalCard({
onClick={() => {
setIsPanelOpen(true);
const extraFields: ExtraField[] = [
{ key: "to", label: "To", type: "emails", value: pendingEdits?.to ?? args.to ?? "" },
{ key: "cc", label: "CC", type: "emails", value: pendingEdits?.cc ?? args.cc ?? "" },
{ key: "bcc", label: "BCC", type: "emails", value: pendingEdits?.bcc ?? args.bcc ?? "" },
{
key: "to",
label: "To",
type: "emails",
value: pendingEdits?.to ?? args.to ?? "",
},
{
key: "cc",
label: "CC",
type: "emails",
value: pendingEdits?.cc ?? args.cc ?? "",
},
{
key: "bcc",
label: "BCC",
type: "emails",
value: pendingEdits?.bcc ?? args.bcc ?? "",
},
];
openHitlEditPanel({
title: pendingEdits?.subject ?? (args.subject ?? ""),
content: pendingEdits?.body ?? (args.body ?? ""),
title: pendingEdits?.subject ?? args.subject ?? "",
content: pendingEdits?.body ?? args.body ?? "",
toolName: "Gmail Draft",
extraFields,
onSave: (newTitle, newContent, extraFieldValues) => {
@ -322,7 +348,9 @@ function ApprovalCard({
<div className="px-5 pt-1">
{(pendingEdits?.subject ?? args.subject) != null && (
<p className="text-sm font-medium text-foreground">{pendingEdits?.subject ?? args.subject}</p>
<p className="text-sm font-medium text-foreground">
{pendingEdits?.subject ?? args.subject}
</p>
)}
{(pendingEdits?.body ?? args.body) != null && (
<div
@ -398,9 +426,7 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) {
return (
<div className="my-4 max-w-lg overflow-hidden rounded-2xl border bg-muted/30 select-none">
<div className="px-5 pt-5 pb-4">
<p className="text-sm font-semibold text-destructive">
Gmail authentication expired
</p>
<p className="text-sm font-semibold text-destructive">Gmail authentication expired</p>
</div>
<div className="mx-5 h-px bg-border/50" />
<div className="px-5 py-4">

View file

@ -1,14 +1,13 @@
"use client";
import { makeAssistantToolUI } from "@assistant-ui/react";
import {
CornerDownLeftIcon,
MailIcon,
Pen,
UserIcon,
UsersIcon,
} from "lucide-react";
import { useSetAtom } from "jotai";
import { CornerDownLeftIcon, MailIcon, Pen, UserIcon, UsersIcon } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import type { ExtraField } from "@/atoms/chat/hitl-edit-panel.atom";
import { openHitlEditPanelAtom } from "@/atoms/chat/hitl-edit-panel.atom";
import { PlateEditor } from "@/components/editor/plate-editor";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { Button } from "@/components/ui/button";
import {
Select,
@ -17,11 +16,6 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { PlateEditor } from "@/components/editor/plate-editor";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { useSetAtom } from "jotai";
import { openHitlEditPanelAtom } from "@/atoms/chat/hitl-edit-panel.atom";
import type { ExtraField } from "@/atoms/chat/hitl-edit-panel.atom";
import { useHitlPhase } from "@/hooks/use-hitl-phase";
interface GmailAccount {
@ -132,7 +126,11 @@ function ApprovalCard({
const [isPanelOpen, setIsPanelOpen] = useState(false);
const openHitlEditPanel = useSetAtom(openHitlEditPanelAtom);
const [pendingEdits, setPendingEdits] = useState<{
subject: string; body: string; to: string; cc: string; bcc: string;
subject: string;
body: string;
to: string;
cc: string;
bcc: string;
} | null>(null);
const accounts = interruptData.context?.accounts ?? [];
@ -175,7 +173,18 @@ function ApprovalCard({
},
},
});
}, [phase, isPanelOpen, canApprove, allowedDecisions, setProcessing, onDecision, interruptData, args, selectedAccountId, pendingEdits]);
}, [
phase,
isPanelOpen,
canApprove,
allowedDecisions,
setProcessing,
onDecision,
interruptData,
args,
selectedAccountId,
pendingEdits,
]);
useEffect(() => {
const handler = (e: KeyboardEvent) => {
@ -200,16 +209,17 @@ function ApprovalCard({
? "Email Sending Approved"
: "Send Email"}
</p>
{phase === "processing" ? (
<TextShimmerLoader text={pendingEdits ? "Sending email with your changes" : "Sending email"} size="sm" />
{phase === "processing" ? (
<TextShimmerLoader
text={pendingEdits ? "Sending email with your changes" : "Sending email"}
size="sm"
/>
) : phase === "complete" ? (
<p className="text-xs text-muted-foreground mt-0.5">
{pendingEdits ? "Email sent with your changes" : "Email sent"}
</p>
) : phase === "rejected" ? (
<p className="text-xs text-muted-foreground mt-0.5">
Email sending was cancelled
</p>
<p className="text-xs text-muted-foreground mt-0.5">Email sending was cancelled</p>
) : (
<p className="text-xs text-muted-foreground mt-0.5">
Requires your approval to proceed
@ -225,13 +235,28 @@ function ApprovalCard({
onClick={() => {
setIsPanelOpen(true);
const extraFields: ExtraField[] = [
{ key: "to", label: "To", type: "emails", value: pendingEdits?.to ?? args.to ?? "" },
{ key: "cc", label: "CC", type: "emails", value: pendingEdits?.cc ?? args.cc ?? "" },
{ key: "bcc", label: "BCC", type: "emails", value: pendingEdits?.bcc ?? args.bcc ?? "" },
{
key: "to",
label: "To",
type: "emails",
value: pendingEdits?.to ?? args.to ?? "",
},
{
key: "cc",
label: "CC",
type: "emails",
value: pendingEdits?.cc ?? args.cc ?? "",
},
{
key: "bcc",
label: "BCC",
type: "emails",
value: pendingEdits?.bcc ?? args.bcc ?? "",
},
];
openHitlEditPanel({
title: pendingEdits?.subject ?? (args.subject ?? ""),
content: pendingEdits?.body ?? (args.body ?? ""),
title: pendingEdits?.subject ?? args.subject ?? "",
content: pendingEdits?.body ?? args.body ?? "",
toolName: "Send Email",
extraFields,
onSave: (newTitle, newContent, extraFieldValues) => {
@ -264,32 +289,32 @@ function ApprovalCard({
<p className="text-sm text-destructive">{interruptData.context.error}</p>
) : (
accounts.length > 0 && (
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">
Gmail Account <span className="text-destructive">*</span>
</p>
<Select value={selectedAccountId} onValueChange={setSelectedAccountId}>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select an account" />
</SelectTrigger>
<SelectContent>
{validAccounts.map((account) => (
<SelectItem key={account.id} value={String(account.id)}>
{account.name}
</SelectItem>
))}
{expiredAccounts.map((a) => (
<div
key={a.id}
className="relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 px-2 text-sm select-none opacity-50 pointer-events-none"
>
{a.name} (expired, retry after re-auth)
</div>
))}
</SelectContent>
</Select>
</div>
)
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">
Gmail Account <span className="text-destructive">*</span>
</p>
<Select value={selectedAccountId} onValueChange={setSelectedAccountId}>
<SelectTrigger className="w-full">
<SelectValue placeholder="Select an account" />
</SelectTrigger>
<SelectContent>
{validAccounts.map((account) => (
<SelectItem key={account.id} value={String(account.id)}>
{account.name}
</SelectItem>
))}
{expiredAccounts.map((a) => (
<div
key={a.id}
className="relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 px-2 text-sm select-none opacity-50 pointer-events-none"
>
{a.name} (expired, retry after re-auth)
</div>
))}
</SelectContent>
</Select>
</div>
)
)}
</div>
</>
@ -320,7 +345,9 @@ function ApprovalCard({
<div className="px-5 pt-1">
{(pendingEdits?.subject ?? args.subject) != null && (
<p className="text-sm font-medium text-foreground">{pendingEdits?.subject ?? args.subject}</p>
<p className="text-sm font-medium text-foreground">
{pendingEdits?.subject ?? args.subject}
</p>
)}
{(pendingEdits?.body ?? args.body) != null && (
<div
@ -396,9 +423,7 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) {
return (
<div className="my-4 max-w-lg overflow-hidden rounded-2xl border bg-muted/30 select-none">
<div className="px-5 pt-5 pb-4">
<p className="text-sm font-semibold text-destructive">
Gmail authentication expired
</p>
<p className="text-sm font-semibold text-destructive">Gmail authentication expired</p>
</div>
<div className="mx-5 h-px bg-border/50" />
<div className="px-5 py-4">

View file

@ -1,16 +1,11 @@
"use client";
import { makeAssistantToolUI } from "@assistant-ui/react";
import {
CalendarIcon,
CornerDownLeftIcon,
MailIcon,
UserIcon,
} from "lucide-react";
import { CalendarIcon, CornerDownLeftIcon, MailIcon, UserIcon } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { useHitlPhase } from "@/hooks/use-hitl-phase";
interface GmailAccount {
@ -192,14 +187,12 @@ function ApprovalCard({
? "Email Trash Approved"
: "Trash Email"}
</p>
{phase === "processing" ? (
{phase === "processing" ? (
<TextShimmerLoader text="Trashing email" size="sm" />
) : phase === "complete" ? (
<p className="text-xs text-muted-foreground mt-0.5">Email trashed</p>
) : phase === "rejected" ? (
<p className="text-xs text-muted-foreground mt-0.5">
Email trash was cancelled
</p>
<p className="text-xs text-muted-foreground mt-0.5">Email trash was cancelled</p>
) : (
<p className="text-xs text-muted-foreground mt-0.5">
Requires your approval to proceed
@ -280,11 +273,7 @@ function ApprovalCard({
<>
<div className="mx-5 h-px bg-border/50" />
<div className="px-5 py-4 flex items-center gap-2 select-none">
<Button
size="sm"
className="rounded-lg gap-1.5"
onClick={handleApprove}
>
<Button size="sm" className="rounded-lg gap-1.5" onClick={handleApprove}>
Approve
<CornerDownLeftIcon className="size-3 opacity-60" />
</Button>
@ -324,9 +313,7 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) {
return (
<div className="my-4 max-w-lg overflow-hidden rounded-2xl border bg-muted/30 select-none">
<div className="px-5 pt-5 pb-4">
<p className="text-sm font-semibold text-destructive">
Gmail authentication expired
</p>
<p className="text-sm font-semibold text-destructive">Gmail authentication expired</p>
</div>
<div className="mx-5 h-px bg-border/50" />
<div className="px-5 py-4">

View file

@ -1,20 +1,14 @@
"use client";
import { makeAssistantToolUI } from "@assistant-ui/react";
import {
CornerDownLeftIcon,
MailIcon,
Pen,
UserIcon,
UsersIcon,
} from "lucide-react";
import { useSetAtom } from "jotai";
import { CornerDownLeftIcon, MailIcon, Pen, UserIcon, UsersIcon } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import type { ExtraField } from "@/atoms/chat/hitl-edit-panel.atom";
import { openHitlEditPanelAtom } from "@/atoms/chat/hitl-edit-panel.atom";
import { PlateEditor } from "@/components/editor/plate-editor";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { useSetAtom } from "jotai";
import { openHitlEditPanelAtom } from "@/atoms/chat/hitl-edit-panel.atom";
import type { ExtraField } from "@/atoms/chat/hitl-edit-panel.atom";
import { Button } from "@/components/ui/button";
import { useHitlPhase } from "@/hooks/use-hitl-phase";
interface GmailAccount {
@ -127,15 +121,12 @@ function isAuthErrorResult(result: unknown): result is AuthErrorResult {
);
}
function isInsufficientPermissionsResult(
result: unknown,
): result is InsufficientPermissionsResult {
function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult {
return (
typeof result === "object" &&
result !== null &&
"status" in result &&
(result as InsufficientPermissionsResult).status ===
"insufficient_permissions"
(result as InsufficientPermissionsResult).status === "insufficient_permissions"
);
}
@ -177,17 +168,11 @@ function ApprovalCard({
const existingBody = context?.existing_body;
const reviewConfig = interruptData.review_configs?.[0];
const allowedDecisions = reviewConfig?.allowed_decisions ?? [
"approve",
"reject",
];
const allowedDecisions = reviewConfig?.allowed_decisions ?? ["approve", "reject"];
const canEdit = allowedDecisions.includes("edit");
const currentSubject =
pendingEdits?.subject ??
args.subject ??
email?.subject ??
args.draft_subject_or_id;
pendingEdits?.subject ?? args.subject ?? email?.subject ?? args.draft_subject_or_id;
const currentBody = pendingEdits?.body ?? args.body;
const currentTo = pendingEdits?.to ?? args.to ?? "";
const currentCc = pendingEdits?.cc ?? args.cc ?? "";
@ -259,23 +244,15 @@ function ApprovalCard({
</p>
{phase === "processing" ? (
<TextShimmerLoader
text={
pendingEdits
? "Updating draft with your changes"
: "Updating draft"
}
text={pendingEdits ? "Updating draft with your changes" : "Updating draft"}
size="sm"
/>
) : phase === "complete" ? (
<p className="text-xs text-muted-foreground mt-0.5">
{pendingEdits
? "Draft updated with your changes"
: "Draft updated"}
{pendingEdits ? "Draft updated with your changes" : "Draft updated"}
</p>
) : phase === "rejected" ? (
<p className="text-xs text-muted-foreground mt-0.5">
Draft update was cancelled
</p>
<p className="text-xs text-muted-foreground mt-0.5">Draft update was cancelled</p>
) : (
<p className="text-xs text-muted-foreground mt-0.5">
Requires your approval to proceed
@ -310,16 +287,12 @@ function ApprovalCard({
value: currentBcc,
},
];
openHitlEditPanel({
title: currentSubject,
content: editableBody,
toolName: "Gmail Draft",
openHitlEditPanel({
title: currentSubject,
content: editableBody,
toolName: "Gmail Draft",
extraFields,
onSave: (
newTitle,
newContent,
extraFieldValues,
) => {
onSave: (newTitle, newContent, extraFieldValues) => {
setIsPanelOpen(false);
const extras = extraFieldValues ?? {};
setPendingEdits({
@ -346,16 +319,12 @@ function ApprovalCard({
<div className="mx-5 h-px bg-border/50" />
<div className="px-5 py-4 space-y-4 select-none">
{context.error ? (
<p className="text-sm text-destructive">
{context.error}
</p>
<p className="text-sm text-destructive">{context.error}</p>
) : (
<>
{account && (
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">
Gmail Account
</p>
<p className="text-xs font-medium text-muted-foreground">Gmail Account</p>
<div className="w-full rounded-md border border-input bg-muted/50 px-3 py-2 text-sm">
{account.name}
</div>
@ -364,15 +333,11 @@ function ApprovalCard({
{email && (
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">
Draft to Update
</p>
<p className="text-xs font-medium text-muted-foreground">Draft to Update</p>
<div className="w-full rounded-md border border-input bg-muted/50 px-3 py-2 text-sm space-y-1">
<div className="flex items-center gap-1.5">
<MailIcon className="size-3 shrink-0 text-muted-foreground" />
<span className="font-medium">
{email.subject}
</span>
<span className="font-medium">{email.subject}</span>
</div>
</div>
</div>
@ -408,18 +373,14 @@ function ApprovalCard({
<div className="px-5 pt-1">
{currentSubject != null && (
<p className="text-sm font-medium text-foreground">
{currentSubject}
</p>
<p className="text-sm font-medium text-foreground">{currentSubject}</p>
)}
{editableBody ? (
<div
{editableBody ? (
<div
className="mt-2 max-h-[7rem] overflow-hidden text-sm"
style={{
maskImage:
"linear-gradient(to bottom, black 50%, transparent 100%)",
WebkitMaskImage:
"linear-gradient(to bottom, black 50%, transparent 100%)",
maskImage: "linear-gradient(to bottom, black 50%, transparent 100%)",
WebkitMaskImage: "linear-gradient(to bottom, black 50%, transparent 100%)",
}}
>
<PlateEditor
@ -477,9 +438,7 @@ function ErrorCard({ result }: { result: ErrorResult }) {
return (
<div className="my-4 max-w-lg overflow-hidden rounded-2xl border bg-muted/30 select-none">
<div className="px-5 pt-5 pb-4">
<p className="text-sm font-semibold text-destructive">
Failed to update Gmail draft
</p>
<p className="text-sm font-semibold text-destructive">Failed to update Gmail draft</p>
</div>
<div className="mx-5 h-px bg-border/50" />
<div className="px-5 py-4">
@ -493,9 +452,7 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) {
return (
<div className="my-4 max-w-lg overflow-hidden rounded-2xl border bg-muted/30 select-none">
<div className="px-5 pt-5 pb-4">
<p className="text-sm font-semibold text-destructive">
Gmail authentication expired
</p>
<p className="text-sm font-semibold text-destructive">Gmail authentication expired</p>
</div>
<div className="mx-5 h-px bg-border/50" />
<div className="px-5 py-4">
@ -505,9 +462,7 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) {
);
}
function InsufficientPermissionsCard({
result,
}: { result: InsufficientPermissionsResult }) {
function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) {
return (
<div className="my-4 max-w-lg overflow-hidden rounded-2xl border bg-muted/30 select-none">
<div className="px-5 pt-5 pb-4">
@ -577,7 +532,7 @@ export const UpdateGmailDraftToolUI = makeAssistantToolUI<
window.dispatchEvent(
new CustomEvent("hitl-decision", {
detail: { decisions: [decision] },
}),
})
);
}}
/>