eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
3 lines • 3.53 kB
JavaScript
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{createLinearAgentActivity}from"#public/channels/linear/api.js";import{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(n={}){return{async"turn.started"(e,t,r){t.state.pendingToolCallMessage=null,await postActivity(t,n,{body:`Working on this.`,type:`thought`},{ephemeral:!0})},async"actions.requested"(e,t,r){let i=t.state.pendingToolCallMessage;if(t.state.pendingToolCallMessage=null,i){await postActivity(t,n,{body:i,type:`thought`},{ephemeral:!0});return}if(e.actions.length!==0){if(e.actions.length>1){await postActivity(t,n,{action:`Running`,parameter:e.actions.map(actionLabel).join(`, `),type:`action`},{ephemeral:!0});return}for(let r of e.actions)await postActivity(t,n,{action:actionLabel(r),parameter:actionParameter(r),type:`action`},{ephemeral:!0})}},async"input.requested"(e,t,i){await postActivity(t,n,{body:renderLinearInputRequests(e.requests),type:`elicitation`})},async"message.completed"(e,t,r){if(e.finishReason===`tool-calls`){t.state.pendingToolCallMessage=e.message?firstNonEmptyLine(e.message)??null:null;return}t.state.pendingToolCallMessage=null,e.message&&await postActivity(t,n,{body:e.message,type:`response`})},async"session.failed"(r,i){let a=formatErrorHint(r),o=extractErrorId(r.details);await postActivity(i,n,{body:[`This session could not recover from an error${a}.`,``,`Start a new Linear agent session to continue.`,...o?[``,`Error id: ${o}`]:[]].join(`
`),type:`error`})},async"turn.failed"(r,i,a){let o=formatErrorHint(r),s=extractErrorId(r.details);await postActivity(i,n,{body:[`I hit an error while handling your request${o}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...s?[``,`Error id: ${s}`]:[]].join(`
`),type:`error`})}}}function postActivity(e,t,r,i={}){return createLinearAgentActivity({api:t.api,credentials:t.credentials,activity:{agentSessionId:requireAgentSessionId(e.state.agentSessionId),content:r,ephemeral:i.ephemeral}})}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 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};