eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 7.04 kB
JavaScript
import{C as e,Et as t,Ft as n,Mt as r,b as i,bt as a,kt as o,tt as s,u as c}from"../../_chunks/node/dist-BweCayKF.js";import{a as l,d as u,f as d,i as f,u as p}from"../../_chunks/node/dist-DvkWiagq.js";import{n as m,r as h,t as g}from"../../_chunks/node/chunk-PFJ2G64A-B79fSABi.js";import{a as _,l as v,o as y,r as b,s as x}from"../../_chunks/node/chunk-5OX2R7AJ-CxVV-owP.js";import{a as S,n as C,r as w}from"../../_chunks/node/chunk-QZV7YRVM-Dzw4WEBv.js";function T(e){return l(e).replace(/\*/g,``)}var E=class extends s{toAst(e){return t(e)}fromAst(e){return o(n(structuredClone(e),e=>a(e)?{type:`code`,value:r(e)}:e)).trim()}renderPostable(e){return typeof e==`string`?e:`raw`in e?e.raw:`markdown`in e?this.fromMarkdown(e.markdown):`ast`in e?this.fromAst(e.ast):super.renderPostable(e)}};function D(e){return`twilio:${encodeURIComponent(e.sender)}:${encodeURIComponent(e.recipient)}`}function O(e){let[t,n,r]=e.split(`:`);if(t!==`twilio`||!n||!r)throw new f(`twilio`,`Invalid Twilio thread ID: ${e}`);return{recipient:decodeURIComponent(r),sender:decodeURIComponent(n)}}function k(e){let t=O(e);return`twilio:${encodeURIComponent(t.sender)}`}function A(){return new Response(`<Response></Response>`,{headers:{"content-type":`application/xml`},status:200})}function j(e){return e.startsWith(`MG`)?{messagingServiceSid:e}:{from:e}}function M(e){return e?.startsWith(`image/`)?`image`:e?.startsWith(`video/`)?`video`:e?.startsWith(`audio/`)?`audio`:`file`}var N=class{name=`twilio`;lockScope=`channel`;persistThreadHistory=!0;userName;chat=null;accountSid;apiUrl;authToken;fetch;formatConverter=new E;logger;messagingServiceSid;phoneNumber;statusCallbackUrl;webhookUrl;webhookVerifier;constructor(e={}){this.accountSid=e.accountSid,this.apiUrl=e.apiUrl,this.authToken=e.authToken,this.fetch=e.fetch,this.logger=e.logger??new c(`info`).child(`twilio`),this.messagingServiceSid=e.messagingServiceSid??process.env.TWILIO_MESSAGING_SERVICE_SID,this.phoneNumber=e.phoneNumber??process.env.TWILIO_PHONE_NUMBER,this.statusCallbackUrl=e.statusCallbackUrl,this.userName=e.userName??`bot`,this.webhookUrl=e.webhookUrl,this.webhookVerifier=e.webhookVerifier}async initialize(e){this.chat=e,this.logger.info(`Twilio adapter initialized`,{messagingServiceSid:this.messagingServiceSid,phoneNumber:this.phoneNumber})}async handleWebhook(e,t){let n;try{n=await S(e,{authToken:this.authToken,webhookUrl:this.webhookUrl,webhookVerifier:this.webhookVerifier})}catch(e){if(e instanceof w)return new Response(`Invalid signature`,{status:401});if(e instanceof C)return new Response(`Invalid webhook`,{status:400});throw e}if(n.kind!==`text`||!this.chat)return A();let r=this.encodeThreadId({recipient:n.from,sender:n.to}),i=this.parseTwilioTextPayload(n,r);return this.chat.processMessage(this,r,i,t),A()}async postMessage(e,t){let n=this.decodeThreadId(e),r=this.renderPostableText(t),i=this.mediaUrls(t);if(!r&&i.length===0)throw new f(`twilio`,`Message text cannot be empty`);let a=await v({...this.apiOptions(),body:r||i.length===0?h(r):void 0,mediaUrl:i,statusCallbackUrl:this.statusCallbackUrl,to:n.recipient,...j(n.sender)});return{id:a.sid,raw:a,threadId:this.threadIdForResource(a,n)}}async editMessage(){throw new e(`Twilio does not support editing sent messages`,`editMessage`)}async deleteMessage(e,t){await b({...this.apiOptions(),messageSid:t})}async addReaction(){throw new e(`Twilio does not support message reactions`,`addReaction`)}async removeReaction(){throw new e(`Twilio does not support message reactions`,`removeReaction`)}async startTyping(){}parseMessage(e){if(F(e)){if(e.kind!==`text`)throw new f(`twilio`,`Cannot parse unsupported webhook`);return this.parseTwilioTextPayload(e,this.encodeThreadId({recipient:e.from,sender:e.to}))}return this.parseTwilioResource(e,void 0)}async fetchMessage(e,t){let n=this.decodeThreadId(e);try{let e=await y({...this.apiOptions(),messageSid:t});return this.parseTwilioResource(e,n)}catch{return null}}async fetchMessages(e,t={}){let n=this.decodeThreadId(e),r=t.limit??50,[i,a]=await Promise.all([x({...this.apiOptions(),from:n.sender,limit:r,to:n.recipient}),x({...this.apiOptions(),from:n.recipient,limit:r,to:n.sender})]);return{messages:[...i,...a].map(e=>this.parseTwilioResource(e,n)).sort((e,t)=>e.metadata.dateSent.getTime()-t.metadata.dateSent.getTime()).slice(-r)}}async fetchThread(e){let t=this.decodeThreadId(e);return{channelId:this.channelIdFromThreadId(e),channelName:t.sender,id:e,isDM:!0,metadata:{...t}}}async getUser(e){return{fullName:e,isBot:!1,userId:e,userName:e}}async openDM(e){return this.encodeThreadId({recipient:e,sender:this.defaultSender()})}isDM(e){return e.startsWith(`twilio:`)}channelIdFromThreadId(e){return k(e)}encodeThreadId(e){return D(e)}decodeThreadId(e){return O(e)}renderFormatted(e){return this.formatConverter.fromAst(e)}rehydrateAttachment(e){let t=e.fetchMetadata?.twilioMediaUrl??e.url;return t?this.twilioAttachment({contentType:e.mimeType,url:t}):e}parseTwilioTextPayload(e,t){return new i({attachments:e.media.map(e=>this.twilioAttachment(e)),author:this.author(e.from,!1),formatted:this.formatConverter.toAst(e.body),id:e.messageSid??`twilio:${Date.now()}`,metadata:{dateSent:new Date,edited:!1},raw:e,text:e.body,threadId:t})}parseTwilioResource(e,t){let n=e.direction?.startsWith(`outbound`)??!1,r=e.from??e.messaging_service_sid??(n?t?.sender:t?.recipient),a=e.to??(n?t?.recipient:t?.sender);if(!(r&&a))throw new f(`twilio`,`Twilio message is missing routing`);let o=e.body??``,s=n?{recipient:t?.recipient??a,sender:t?.sender??r}:{recipient:r,sender:a};return new i({attachments:[],author:this.author(n?s.sender:r,n),formatted:this.formatConverter.toAst(o),id:e.sid,metadata:{dateSent:I(e.date_sent??e.date_created),edited:!1},raw:e,text:o,threadId:this.encodeThreadId(s)})}renderPostableText(e){let t=p(e);return m(t?T(t):this.formatConverter.renderPostable(e),{limit:g}).text}mediaUrls(e){if(u(e).length>0)throw new f(`twilio`,`Twilio adapter supports media attachments by public URL only`);let t=d(e),n=[];for(let e of t){if(typeof e.url!=`string`||e.url.length===0)throw new f(`twilio`,`Twilio adapter supports media attachments by public URL only`);n.push(e.url)}return n}twilioAttachment(e){return{fetchData:async()=>Buffer.from(await _({...this.apiOptions(),url:e.url})),fetchMetadata:{twilioMediaUrl:e.url},mimeType:e.contentType,type:M(e.contentType),url:e.url}}apiOptions(){return{apiUrl:this.apiUrl,credentials:{accountSid:this.accountSid,authToken:this.authToken},fetch:this.fetch}}defaultSender(){let e=this.phoneNumber??this.messagingServiceSid;if(!e)throw new f(`twilio`,`phoneNumber or messagingServiceSid is required`);return e}author(e,t){return{fullName:e,isBot:t,isMe:t,userId:e,userName:e}}threadIdForResource(e,t){return this.parseTwilioResource(e,t).threadId}};function P(e={}){return new N(e)}function F(e){return`kind`in e}function I(e){let t=e?new Date(e):new Date;return Number.isNaN(t.getTime())?new Date:t}export{N as TwilioAdapter,E as TwilioFormatConverter,T as cardToTwilioText,P as createTwilioAdapter};