import { Suspense, useCallback, useEffect, useRef, useState, type ComponentType } from "react"; import { useAtomSet } from "@effect/atom-react"; import * as Exit from "effect/Exit"; import { type Connection, type IntegrationSlug } from "@executor-js/sdk/shared"; import type { EditSheetApplyResult, EditSheetSectionProps } from "@executor-js/sdk/client"; import { toast } from "sonner"; import { updateConnection, updateIntegration } from "../api/atoms"; import { connectionWriteKeys, integrationWriteKeys } from "../api/reactivity-keys"; import { trackEvent } from "../api/analytics"; import { messageFromExit } from "../api/error-reporting"; import { Button } from "./button"; import { Input } from "./input"; import { Label } from "./label"; import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "./sheet"; import { Textarea } from "./textarea"; // --------------------------------------------------------------------------- // Metadata edit sheets — the user-curated, AGENT-VISIBLE metadata for an // integration and for a connection. The point of the sheet (vs. an inline // input) is the preview: it shows the exact inventory line an agent reads, so // editing the description is editing what the model sees. // --------------------------------------------------------------------------- /** The connection's callable prefix under `tools.` — the line item agents see * in the execute tool's "Available connection prefixes" inventory. */ const connectionPrefix = (connection: Connection): string => { const address = String(connection.address); return address.startsWith("tools.") ? address.slice("tools.".length) : address; }; function AgentPreview(props: { readonly label: string; readonly line: string }) { return (

{props.label}

        {props.line}
      
); } export function ConnectionEditSheet(props: { readonly connection: Connection | null; readonly onOpenChange: (open: boolean) => void; }) { const { connection } = props; const doUpdate = useAtomSet(updateConnection, { mode: "promiseExit" }); const [description, setDescription] = useState(""); const [identityLabel, setIdentityLabel] = useState(""); const [saving, setSaving] = useState(false); useEffect(() => { setDescription(connection?.description ?? ""); setIdentityLabel(connection?.identityLabel ?? ""); }, [connection]); const handleSave = async () => { if (!connection) return; setSaving(true); const exit = await doUpdate({ params: { owner: connection.owner, integration: connection.integration, name: connection.name, }, payload: { description: description.trim().length > 0 ? description.trim() : null, identityLabel: identityLabel.trim().length > 0 ? identityLabel.trim() : null, }, reactivityKeys: connectionWriteKeys, }); setSaving(false); if (Exit.isFailure(exit)) { toast.error(messageFromExit(exit, "Failed to update connection")); return; } props.onOpenChange(false); }; const previewDescription = description.trim().split("\n", 1)[0]; const prefix = connection ? connectionPrefix(connection) : ""; return ( Edit connection The description is agent-visible: it rides this connection's prefix in the tool inventory, so it is the place to say what this credential reaches and how to use it.