eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
5 lines (4 loc) • 4.98 kB
JavaScript
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{createLinearAgentActivity}from"#public/channels/linear/api.js";import{linearInputRequestSignal,renderLinearInputRequests}from"#public/channels/linear/hitl.js";function defaultLinearAuth(e){let t=e.agentActivity?.user??e.agentSession.creator,n=e.agentActivity?.userId??e.agentSession.creatorId??t?.id??`unknown`,r={action:e.action,agent_session_id:e.agentSession.id,organization_id:e.organizationId??e.agentSession.organizationId??``};if(e.delivery.id!==void 0&&(r.delivery_id=e.delivery.id),e.agentSession.issueId!==void 0&&e.agentSession.issueId!==null&&(r.issue_id=e.agentSession.issueId),e.agentSession.issue?.identifier!==void 0&&(r.issue_identifier=e.agentSession.issue.identifier),t!==void 0){let e=linearUserLabel(t);e!==void 0&&(r.user=e)}return{attributes:r,authenticator:`linear-agent-webhook`,issuer:e.organizationId?`linear:${e.organizationId}`:`linear`,principalId:`linear:${n}`,principalType:`user`,subject:n}}function defaultOnAgentSession(e,t){return t.action!==`created`&&t.action!==`prompted`?null:{auth:defaultLinearAuth(t)}}function createDefaultEvents(e={}){return{async"turn.started"(t,n,r){n.state.pendingToolCallMessage=null,await postActivity(n,e,{body:`Working on this.`,type:`thought`},{ephemeral:!0})},async"actions.requested"(t,n,r){let i=n.state.pendingToolCallMessage;if(n.state.pendingToolCallMessage=null,i){await postActivity(n,e,{body:i,type:`thought`},{ephemeral:!0});return}if(t.actions.length!==0){if(t.actions.length>1){await postActivity(n,e,{action:`Running`,parameter:t.actions.map(actionLabel).join(`, `),type:`action`},{ephemeral:!0});return}for(let r of t.actions)await postActivity(n,e,{action:actionLabel(r),parameter:actionParameter(r),type:`action`},{ephemeral:!0})}},async"input.requested"(t,n,r){let i=linearInputRequestSignal(t.requests);await postActivity(n,e,{body:renderLinearInputRequests(t.requests),type:`elicitation`},i)},async"authorization.required"(t,n,r){let i=authorizationDisplayName(t.name,t.authorization?.displayName),a=t.authorization?.url,o=linearUserId(r),s;if(a!==void 0){let e={providerName:i,url:a};o!==void 0&&(e.userId=o),s={signal:`auth`,signalMetadata:e}}await postActivity(n,e,{body:authorizationRequiredBody({displayName:i,instructions:t.authorization?.instructions,userCode:t.authorization?.userCode}),type:`elicitation`},s)},async"authorization.completed"(t,n,r){let i=authorizationDisplayName(t.name,t.authorization?.displayName);if(t.outcome===`authorized`){await postActivity(n,e,{body:`Connected to ${i}. Resuming.`,type:`thought`},{ephemeral:!0});return}let a=t.reason===void 0?``:` (${t.reason})`;await postActivity(n,e,{body:`${i} authorization ${formatAuthorizationOutcome(t.outcome)}${a}.`,type:`thought`})},async"message.completed"(t,n,r){if(t.finishReason===`tool-calls`){n.state.pendingToolCallMessage=t.message?firstNonEmptyLine(t.message)??null:null;return}n.state.pendingToolCallMessage=null,t.message&&await postActivity(n,e,{body:t.message,type:`response`})},async"session.failed"(t,n){let r=formatErrorHint(t),i=extractErrorId(t.details);await postActivity(n,e,{body:[`This session could not recover from an error${r}.`,``,`Start a new Linear agent session to continue.`,...i?[``,`Error id: ${i}`]:[]].join(`
`),type:`error`})},async"turn.failed"(t,n,r){let i=formatErrorHint(t),a=extractErrorId(t.details);await postActivity(n,e,{body:[`I hit an error while handling your request${i}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...a?[``,`Error id: ${a}`]:[]].join(`
`),type:`error`})}}}function postActivity(e,t,n,r={}){return createLinearAgentActivity({api:t.api,credentials:t.credentials,activity:{agentSessionId:requireAgentSessionId(e.state.agentSessionId),content:n,ephemeral:r.ephemeral,signal:r.signal,signalMetadata:r.signalMetadata}})}function requireAgentSessionId(e){if(e===null)throw Error(`linearChannel: cannot post Agent Activity without an Agent Session id.`);return e}function linearUserLabel(e){return e.displayName??e.name??e.email}function authorizationDisplayName(e,t){return t===void 0?e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1):t}function authorizationRequiredBody(e){return[`Authorization required for ${e.displayName}.`,e.instructions,e.userCode===void 0?void 0:`Code: ${e.userCode}`].filter(e=>e!==void 0&&e.length>0).join(`
`)}function linearUserId(e){let t=e.session.auth.current;return t?.authenticator===`linear-agent-webhook`?t.subject:void 0}function formatAuthorizationOutcome(e){return e===`timed-out`?`timed out`:e}function firstNonEmptyLine(e){for(let t of e.split(/\r?\n/u)){let e=t.trim();if(e.length>0)return e}}function actionLabel(e){return e.kind===`tool-call`&&e.toolName?e.toolName:e.kind}function actionParameter(e){if(e.description)return e.description;if(e.name)return e.name;if(e.input!==void 0)try{return JSON.stringify(e.input)}catch{return``}return``}export{createDefaultEvents,defaultLinearAuth,defaultOnAgentSession};