PageSourceSearch

https://app.xlift.ai/assets/CopilotPage-CBpHiwkU.js

js xlift.ai collected 2026-10-05 13:20:32 UTC 8,607 bytes, 1 lines download raw bytes

1import{ai as U,o as c,A as z,al as P,a4 as R,a5 as K,U as A,j as e,C as S,G as u,ac as H,$ as N,T as n,D as T,I as x,a7 as j,ag as E,aR as W,aS as Q,E as I,au as X,a0 as Y,aa as _,L as J,X as V}from"./index-dE8a1mPK.js";import{S as $}from"./Select-DebRlW67.js";import{I as Z}from"./IconArrowRight-Ajq43paw.js";import{S as L}from"./Switch-Bm85N10X.js";import{S as ee}from"./SegmentedControl-CNEtbfTu.js";import{T as ae}from"./Textarea-BtbUvWWM.js";import{N as te}from"./NumberInput-EbCp_odp.js";import{T as oe}from"./TagsInput-BFXHhTYh.js";import"./OptionsDropdown-wonErrz5.js";import"./CheckIcon-DkMc45y2.js";import"./InputsGroupFieldset-C0syow2C.js";import"./get-env-uyVen0u2.js";import"./Pill-yNBbBYnE.js";import"./PillsInput-BO1u7Wrq.js";const g={draft:0,assisted:1,"full-auto":2},se={draft:'Manual. The co-pilot drafts a reply when you click "AI draft" on the Chat page. You review + send.',assisted:"Hands-off drafting, you approve. Every 5 min the poller scans the DM inbox; for each new inbound, it drafts and queues an action in Approvals. You approve in one click and the worker sends it on the next tick.","full-auto":"Hands-off everything. Same scan + draft, but the action skips Approvals and goes straight into the dispatch queue. Blocklist, opt-out detection, escalation keywords, and the max-replies cap still apply."},ne=[{value:"book-call",label:"Book a call"},{value:"collect-email",label:"Collect email"},{value:"send-to-link",label:"Send to link"}];function be(){var k,l,b,p,C,m;const o=U(),[t,y]=c.useState(null),r=(((k=z({queryKey:["accounts"],queryFn:()=>A.listAccounts()}).data)==null?void 0:k.accounts)||[]).filter(a=>a.executionMode==="cookie"&&a.status==="active");c.useEffect(()=>{!t&&r.length&&y(r[0].id)},[t,r]);const d=z({queryKey:["copilot-config",t],queryFn:()=>A.copilotConfig(t),enabled:!!t}),i=z({queryKey:["copilot-threads"],queryFn:()=>A.copilotThreads()}),w=P({mutationFn:a=>A.saveCopilotConfig(t,a),onSuccess:()=>{o.invalidateQueries({queryKey:["copilot-config",t]}),K("Co-pilot config saved.")},onError:a=>R(a)}),h=(l=d.data)==null?void 0:l.config;return e.jsxs(S,{gap:"md",children:[e.jsxs("div",{children:[e.jsxs(u,{gap:"xs",children:[e.jsx(H,{size:20}),e.jsx(N,{order:2,children:"DM Co-pilot"})]}),e.jsx(n,{c:"dimmed",size:"sm",children:"Drafts replies to inbound DMs in your voice, working toward a goal. Pick a mode — Draft (manual), Assisted (auto-drafts → you approve), or Full-auto (drafts + sends). Powered by Gemini with your brand profile, escalation keywords, opt-out detection, and the blocklist gating every send."})]}),e.jsx(T,{withBorder:!0,children:e.jsxs(S,{gap:"sm",children:[e.jsx($,{label:"Account",placeholder:r.length?"Pick a cookie-mode account":"No cookie-mode accounts",value:t,onChange:y,data:r.map(a=>({value:a.id,label:`@${a.handle}`})),disabled:!r.length}),!r.length&&e.jsxs(n,{size:"xs",c:"dimmed",children:["Connect a cookie-mode X account in ",e.jsx(x,{component:j,to:"/accounts",children:"Accounts"})," to configure the co-pilot."]})]})}),t&&d.isLoading&&e.jsx(E,{}),t&&h&&e.jsx(re,{initial:h,onSave:a=>w.mutate(a),saving:w.isPending},t),e.jsxs(T,{withBorder:!0,children:[e.jsxs(u,{gap:"xs",mb:"xs",children:[e.jsx(W,{size:16}),e.jsx(n,{fw:600,size:"sm",children:"Tracked threads"})]}),i.isLoading&&e.jsx(E,{}),i.error&&e.jsx(n,{c:"red",size:"sm",children:i.error.message}),((p=(b=i.data)==null?void 0:b.threads)==null?void 0:p.length)===0&&e.jsx(n,{size:"sm",c:"dimmed",children:"No threads yet. The co-pilot starts tracking a conversation the first time you ask for a draft."}),(m=(C=i.data)==null?void 0:C.threads)==null?void 0:m.map(a=>{const f=a.accountId&&a.conversationId?`/chat?account=${encodeURIComponent(a.accountId)}&conversation=${encodeURIComponent(a.conversationId)}`:"/chat";return e.jsxs(u,{justify:"space-between",wrap:"nowrap",py:6,style:{borderTop:"1px solid var(--xb-line-soft)"},children:[e.jsxs(u,{gap:"xs",wrap:"nowrap",style:{minWidth:0},children:[e.jsx(Q,{size:14}),e.jsxs(S,{gap:0,style:{minWidth:0},children:[e.jsx(x,{component:j,to:f,size:"sm",fw:500,truncate:!0,maw:320,children:a.theirHandle?`@${a.theirHandle}`:"Unknown handle"}),e.jsxs(n,{size:"xs",c:"dimmed",children:[a.accountHandle?`via @${a.accountHandle}`:"",a.lastDraftAt?` · last draft ${ie(a.lastDraftAt)}`:""]}),a.summary&&e.jsx(n,{size:"xs",c:"dimmed",lineClamp:1,title:a.summary,children:a.summary})]})]}),e.jsxs(u,{gap:"xs",wrap:"nowrap",children:[a.category&&e.jsx(I,{variant:"dot",size:"xs",children:a.category}),e.jsx(I,{variant:"light",color:le(a.status),children:a.status||"active"}),a.repliesByMe?e.jsxs(I,{variant:"outline",children:[a.repliesByMe," sent"]}):null,e.jsx(x,{component:j,to:f,size:"xs",children:e.jsx(Z,{size:14})})]})]},a.id)})]})]})}function re({initial:o,onSave:t,saving:y}){const{features:v,planLabel:r}=X(),d=(v==null?void 0:v.copilotMode)||"draft",i=g[d]??0,w=[{value:"draft",label:"Draft"},{value:"assisted",label:g.assisted>i?"🔒 Assisted":"Assisted"},{value:"full-auto",label:g["full-auto"]>i?"🔒 Full-auto":"Full-auto"}],[h,k]=c.useState(!!o.enabled),[l,b]=c.useState(o.mode||"draft"),[p,C]=c.useState(o.goal||"book-call"),[m,a]=c.useState(o.goalLink||""),[f,B]=c.useState(o.goalContext||""),[D,O]=c.useState(o.maxRepliesPerConversation||5),[F,q]=c.useState(o.escalationKeywords||[]),[M,G]=c.useState(!!o.autoFollowOnFirstDm);return e.jsx(T,{withBorder:!0,children:e.jsxs(S,{gap:"sm",children:[e.jsxs(u,{justify:"space-between",children:[e.jsxs("div",{children:[e.jsx(n,{fw:600,size:"sm",children:"Co-pilot config"}),e.jsx(n,{size:"xs",c:"dimmed",children:"Settings apply to drafts for this account."})]}),e.jsx(L,{label:"Enabled",checked:h,onChange:s=>k(s.currentTarget.checked)})]}
1),e.jsx(ee,{value:l,onChange:s=>{if((g[s]??0)>i){R(new Error(`Your ${r} plan caps Co-pilot at "${d}". Upgrade to unlock ${s}.`));return}b(s)},data:w}),e.jsx(n,{size:"xs",c:"dimmed",children:se[l]}),i<g["full-auto"]&&e.jsxs(n,{size:"xs",c:"grape",children:[r," plan caps Co-pilot at ",e.jsx("b",{children:d}),". ",e.jsx(x,{component:j,to:"/billing",children:"Upgrade"})," to unlock ",d==="draft"?"Assisted + Full-auto":"Full-auto","."]}),(l==="assisted"||l==="full-auto")&&e.jsx(Y,{color:l==="full-auto"?"red":"blue",icon:e.jsx(_,{size:16}),variant:"light",children:l==="full-auto"?e.jsxs(e.Fragment,{children:["Full-auto sends without human review. Test with Assisted first, set a tight ",e.jsx("b",{children:"Max replies per conversation"}),", and double-check your ",e.jsx("b",{children:"Escalation keywords"}),"."]}):e.jsxs(e.Fragment,{children:["Drafted replies land in ",e.jsx(x,{component:j,to:"/approvals",inherit:!0,children:"Approvals"})," as ",e.jsx("i",{children:"awaiting-approval"}),". Approving dispatches on the next worker tick."]})}),e.jsx($,{label:"Goal",value:p,onChange:C,data:ne}),e.jsx(J,{label:"Goal link",description:"Cal.com URL, signup page, etc. Used by 'Send to link' and surfaced in 'Book a call' when warm.",placeholder:"https://cal.com/you/intro",value:m,onChange:s=>a(s.currentTarget.value)}),e.jsx(ae,{label:"Goal context",description:"What info to collect (for email goal), or extra framing for the link.",placeholder:"e.g. their company size + current SEO setup",autosize:!0,minRows:2,value:f,onChange:s=>B(s.currentTarget.value)}),e.jsx(te,{label:"Max replies per conversation",description:"Assisted + Full-auto stop drafting after this many outbound replies in one thread (per warming, X dislikes machine-gun threads). Draft mode is human-gated and ignores this — the count is shown for reference.",value:D,onChange:s=>O(Number(s)||5),min:1,max:20}),e.jsx(oe,{label:"Escalation keywords",description:"Active in Draft mode too: if any recent inbound contains one, AI draft refuses to fire and flags the thread.",value:F,onChange:q,placeholder:"add a word + Enter"}),e.jsx(L,{label:"Auto-follow on first DM",description:"When someone sends this account a DM for the first time, queue a follow action. Once per handle per account; respects daily caps.",checked:M,onChange:s=>G(s.currentTarget.checked)}),e.jsx(u,{justify:"flex-end",children:e.jsx(V,{loading:y,onClick:()=>t({enabled:h,mode:l,goal:p,goalLink:m,goalContext:f,maxRepliesPerConversation:D,escalationKeywords:F,autoFollowOnFirstDm:M}),children:"Save"})})]})})}function ie(o){if(!o)return"";const t=Date.now()-o;return t<6e4?"just now":t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}function le(o){return o==="goal-reached"?"green":o==="declined"?"gray":o==="escalated"?"red":o==="cap-reached"?"orange":o==="human-takeover"?"blue":"gray"}export{be as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.