diff --git a/ui/src/api/access.ts b/ui/src/api/access.ts index f43d2713..94496cdb 100644 --- a/ui/src/api/access.ts +++ b/ui/src/api/access.ts @@ -40,7 +40,16 @@ type AgentJoinRequestAccepted = JoinRequest & { type InviteOnboardingManifest = { invite: InviteSummary; - onboarding: Record; + onboarding: { + inviteMessage?: string | null; + connectivity?: { + guidance?: string; + connectionCandidates?: string[]; + }; + textInstructions?: { + url?: string; + }; + }; }; type BoardClaimStatus = { diff --git a/ui/src/pages/CompanySettings.tsx b/ui/src/pages/CompanySettings.tsx index ebab1bbf..91aae044 100644 --- a/ui/src/pages/CompanySettings.tsx +++ b/ui/src/pages/CompanySettings.tsx @@ -10,6 +10,13 @@ import { Settings, Check, Copy } from "lucide-react"; import { CompanyPatternIcon } from "../components/CompanyPatternIcon"; import { Field, ToggleField, HintIcon } from "../components/agent-config-primitives"; +type AgentFallbackSnippetInput = { + onboardingTextUrl: string; + inviteMessage?: string | null; + guidance?: string | null; + connectionCandidates?: string[] | null; +}; + export function CompanySettings() { const { companies, selectedCompany, selectedCompanyId, setSelectedCompanyId } = useCompany(); const { setBreadcrumbs } = useBreadcrumbs(); @@ -34,6 +41,9 @@ export function CompanySettings() { const [frozenInviteMessage, setFrozenInviteMessage] = useState(null); const [copied, setCopied] = useState(false); const [copyDelightId, setCopyDelightId] = useState(0); + const [inviteSnippet, setInviteSnippet] = useState(null); + const [snippetCopied, setSnippetCopied] = useState(false); + const [snippetCopyDelightId, setSnippetCopyDelightId] = useState(0); const generalDirty = !!selectedCompany && @@ -77,8 +87,27 @@ export function CompanySettings() { : `${base}${onboardingTextLink}`; setInviteLink(absoluteUrl); const submittedMessage = inviteMessage.trim() || null; + const nextInviteMessage = invite.inviteMessage ?? submittedMessage; setInviteMessage(submittedMessage ?? ""); - setFrozenInviteMessage(invite.inviteMessage ?? submittedMessage); + setFrozenInviteMessage(nextInviteMessage); + setSnippetCopied(false); + setSnippetCopyDelightId(0); + try { + const manifest = await accessApi.getInviteOnboarding(invite.token); + setInviteSnippet(buildAgentFallbackSnippet({ + onboardingTextUrl: absoluteUrl, + inviteMessage: nextInviteMessage, + guidance: manifest.onboarding.connectivity?.guidance ?? null, + connectionCandidates: manifest.onboarding.connectivity?.connectionCandidates ?? null, + })); + } catch { + setInviteSnippet(buildAgentFallbackSnippet({ + onboardingTextUrl: absoluteUrl, + inviteMessage: nextInviteMessage, + guidance: null, + connectionCandidates: null, + })); + } try { await navigator.clipboard.writeText(absoluteUrl); setCopied(true); @@ -99,6 +128,9 @@ export function CompanySettings() { setFrozenInviteMessage(null); setCopied(false); setCopyDelightId(0); + setInviteSnippet(null); + setSnippetCopied(false); + setSnippetCopyDelightId(0); }, [selectedCompanyId]); const archiveMutation = useMutation({ mutationFn: ({ @@ -299,6 +331,8 @@ export function CompanySettings() { setInviteLink(null); setFrozenInviteMessage(null); setCopied(false); + setInviteSnippet(null); + setSnippetCopied(false); }} > New message @@ -340,6 +374,42 @@ export function CompanySettings() { )} + {inviteSnippet && ( +
+
+
Fallback snippet for agent chat
+ {snippetCopied && ( + + + Copied + + )} +
+
+