eve 0.47.2 → 0.47.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/src/channel/activity-renderer.d.ts +21 -0
  3. package/dist/src/channel/activity-renderer.js +1 -0
  4. package/dist/src/channel/activity-sink.d.ts +2 -0
  5. package/dist/src/channel/activity-sink.js +1 -0
  6. package/dist/src/channel/auth/oidc.js +1 -1
  7. package/dist/src/channel/channel-address.js +1 -1
  8. package/dist/src/channel/compiled-channel.d.ts +2 -0
  9. package/dist/src/channel/compiled-channel.js +2 -2
  10. package/dist/src/channel/forwarded-principal.js +1 -1
  11. package/dist/src/channel/session.d.ts +3 -2
  12. package/dist/src/channel/session.js +1 -1
  13. package/dist/src/channel/types.d.ts +11 -0
  14. package/dist/src/chunks/{use-eve-agent-CacMaX4P.js → use-eve-agent-DjYwFJF7.js} +1 -0
  15. package/dist/src/chunks/{use-eve-agent-kmlFdOBB.js → use-eve-agent-DkUB0Ok4.js} +1 -0
  16. package/dist/src/cli/dev/tui/status-line.d.ts +6 -0
  17. package/dist/src/cli/dev/tui/status-line.js +1 -1
  18. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
  19. package/dist/src/cli/dev/tui/tui.js +1 -1
  20. package/dist/src/compiler/extension-compatibility.d.ts +4 -4
  21. package/dist/src/compiler/extension-compatibility.js +1 -1
  22. package/dist/src/compiler/normalize-subagent.js +1 -1
  23. package/dist/src/context/keys.d.ts +2 -1
  24. package/dist/src/context/keys.js +1 -1
  25. package/dist/src/eve-channel/activity-observer-request.d.ts +7 -0
  26. package/dist/src/eve-channel/activity-observer-request.js +1 -0
  27. package/dist/src/eve-channel/index.js +1 -1
  28. package/dist/src/eve-channel/request.d.ts +3 -1
  29. package/dist/src/eve-channel/request.js +1 -1
  30. package/dist/src/execution/activity-collector.d.ts +12 -0
  31. package/dist/src/execution/activity-collector.js +1 -0
  32. package/dist/src/execution/activity-events.d.ts +7 -0
  33. package/dist/src/execution/activity-events.js +1 -0
  34. package/dist/src/execution/activity-route.d.ts +2 -0
  35. package/dist/src/execution/activity-route.js +1 -0
  36. package/dist/src/execution/activity-text.d.ts +3 -0
  37. package/dist/src/execution/activity-text.js +1 -0
  38. package/dist/src/execution/activity-work-id.d.ts +9 -0
  39. package/dist/src/execution/activity-work-id.js +1 -0
  40. package/dist/src/execution/activity-work.d.ts +20 -0
  41. package/dist/src/execution/activity-work.js +1 -0
  42. package/dist/src/execution/agent-handle-dispatch.d.ts +3 -1
  43. package/dist/src/execution/agent-handle-dispatch.js +1 -1
  44. package/dist/src/execution/delegated-parent-notification.js +1 -1
  45. package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +8 -0
  46. package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -1
  47. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  48. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  49. package/dist/src/execution/remote-agent-dispatch.d.ts +3 -1
  50. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  51. package/dist/src/execution/runtime-context.js +1 -1
  52. package/dist/src/execution/sandbox/bindings/vercel-credentials.js +1 -1
  53. package/dist/src/execution/session-activity-projection.d.ts +14 -0
  54. package/dist/src/execution/session-activity-projection.js +1 -0
  55. package/dist/src/execution/session-activity-renderer-step.d.ts +15 -0
  56. package/dist/src/execution/session-activity-renderer-step.js +1 -0
  57. package/dist/src/execution/session-activity.d.ts +6 -0
  58. package/dist/src/execution/session-activity.js +1 -0
  59. package/dist/src/execution/session-callback-request.d.ts +1 -0
  60. package/dist/src/execution/session-callback-request.js +1 -1
  61. package/dist/src/execution/session-callback-route.js +1 -1
  62. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  63. package/dist/src/execution/subagent-start-local.d.ts +1 -0
  64. package/dist/src/execution/subagent-start-local.js +1 -1
  65. package/dist/src/execution/subagent-start-remote.d.ts +1 -0
  66. package/dist/src/execution/subagent-start-remote.js +1 -1
  67. package/dist/src/execution/subagent-tool.d.ts +2 -1
  68. package/dist/src/execution/subagent-tool.js +1 -1
  69. package/dist/src/execution/submit-activity.d.ts +7 -0
  70. package/dist/src/execution/submit-activity.js +1 -0
  71. package/dist/src/execution/tasks/child/steps.d.ts +8 -0
  72. package/dist/src/execution/tasks/child/steps.js +1 -1
  73. package/dist/src/execution/tasks/child/update.js +1 -1
  74. package/dist/src/execution/tasks/child/workflow.d.ts +3 -0
  75. package/dist/src/execution/tasks/child/workflow.js +1 -1
  76. package/dist/src/execution/tasks/parent/delegate.d.ts +3 -0
  77. package/dist/src/execution/tasks/parent/delegate.js +1 -1
  78. package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -1
  79. package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
  80. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  81. package/dist/src/execution/terminate-child-sessions-step.js +1 -1
  82. package/dist/src/execution/tools/connection-search.js +1 -1
  83. package/dist/src/execution/tools/subagent/local.js +1 -1
  84. package/dist/src/execution/turn-control-receiver.js +1 -1
  85. package/dist/src/execution/turn-workflow.js +1 -1
  86. package/dist/src/execution/web-fetch/request.js +1 -1
  87. package/dist/src/execution/wire/session-inbox-contract.d.ts +2 -2
  88. package/dist/src/execution/wire/session-inbox-contract.js +1 -1
  89. package/dist/src/execution/wire/session-inbox-encoder.d.ts +6 -2
  90. package/dist/src/execution/wire/session-inbox-encoder.js +1 -1
  91. package/dist/src/execution/wire/session-inbox-wire.js +1 -1
  92. package/dist/src/execution/wire/session-inbox-wire.v2-migration.d.ts +4 -0
  93. package/dist/src/execution/wire/session-inbox-wire.v2-migration.js +1 -0
  94. package/dist/src/execution/wire/session-inbox-wire.v2.d.ts +478 -0
  95. package/dist/src/execution/wire/session-inbox-wire.v2.js +1 -0
  96. package/dist/src/execution/workflow-entry.js +1 -1
  97. package/dist/src/execution/workflow-runtime.d.ts +4 -0
  98. package/dist/src/execution/workflow-runtime.js +1 -1
  99. package/dist/src/execution/workflow-steps.js +1 -1
  100. package/dist/src/harness/ai-sdk-telemetry.d.ts +5 -1
  101. package/dist/src/harness/ai-sdk-telemetry.js +1 -1
  102. package/dist/src/harness/approval-delivery-coordinator.js +1 -1
  103. package/dist/src/harness/authorization.js +1 -1
  104. package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
  105. package/dist/src/harness/instrumentation/content-policy.d.ts +3 -5
  106. package/dist/src/harness/instrumentation/content-policy.js +1 -1
  107. package/dist/src/harness/instrumentation/dispatch.js +1 -1
  108. package/dist/src/harness/instrumentation/lifecycle.d.ts +10 -4
  109. package/dist/src/harness/instrumentation/runtime-context.js +1 -1
  110. package/dist/src/harness/instrumentation/runtime.d.ts +3 -3
  111. package/dist/src/harness/prepare-trace-context.d.ts +3 -3
  112. package/dist/src/harness/prepare-trace-context.js +1 -1
  113. package/dist/src/harness/tool-loop.js +2 -2
  114. package/dist/src/harness/tool-model-output.js +1 -1
  115. package/dist/src/internal/application/compiled-artifacts.js +1 -1
  116. package/dist/src/internal/application/package.js +1 -1
  117. package/dist/src/internal/user-agent.d.ts +2 -0
  118. package/dist/src/internal/user-agent.js +1 -1
  119. package/dist/src/protocol/activity.d.ts +105 -0
  120. package/dist/src/protocol/activity.js +1 -0
  121. package/dist/src/protocol/message.js +2 -2
  122. package/dist/src/protocol/routes.d.ts +4 -0
  123. package/dist/src/protocol/routes.js +1 -1
  124. package/dist/src/public/channels/auth.js +1 -1
  125. package/dist/src/public/channels/slack/defaults.js +1 -1
  126. package/dist/src/runtime/channels/registry.js +1 -1
  127. package/dist/src/runtime/connections/openapi-client.js +1 -1
  128. package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
  129. package/dist/src/setup/gateway-models.js +1 -1
  130. package/dist/src/setup/scaffold/create/project.js +1 -1
  131. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  132. package/dist/src/setup/scaffold/create/web-template.js +9 -5
  133. package/dist/src/svelte/index.js +1 -1
  134. package/dist/src/svelte/use-eve-agent.js +1 -1
  135. package/dist/src/tracing/agent-approval-instrumentation.d.ts +0 -2
  136. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  137. package/dist/src/tracing/agent-otel-provider.d.ts +3 -3
  138. package/dist/src/tracing/agent-otel-provider.js +2 -2
  139. package/dist/src/tracing/agent-otel-session-context.d.ts +3 -3
  140. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  141. package/dist/src/tracing/agent-trace-context-store.d.ts +3 -0
  142. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  143. package/dist/src/tracing/agent-trace-state.d.ts +2 -0
  144. package/dist/src/tracing/otel-declaration.d.ts +7 -3
  145. package/dist/src/vue/index.js +1 -1
  146. package/dist/src/vue/use-eve-agent.js +1 -1
  147. package/docs/reference/cli.md +4 -4
  148. package/package.json +1 -1
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{decodeJwt}from"#compiled/jose/index.js";import{isVercelOidcIssuer}from"#shared/vercel-project.js";import{isLoopbackHostname}from"#shared/network-address.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{resolveVercelOidcCurrentProject}from"#channel/auth/vercel-oidc-project.js";import{authenticateHttpBasicStrategy}from"#channel/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#channel/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#channel/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#channel/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#channel/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#channel/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let n=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1,currentVercelProject:void 0});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){if(e===null||e.length===0)return{kind:`not-authenticated`};let n={acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}};return await authenticateOidcStrategy({strategy:t.currentVercelProject===void 0?n:{...n,currentVercelProject:t.currentVercelProject},token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e!==null&&isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeAuthChallengeParameter(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeAuthChallengeParameter(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}function isValidOAuthIdentifierUrl(e){try{let t=new URL(e);return(t.protocol===`https:`||t.protocol===`http:`&&isLoopbackHostname(t.hostname))&&t.username.length===0&&t.password.length===0&&t.search.length===0&&t.hash.length===0}catch{return!1}}function isValidMetadataPath(e){if(!e.startsWith(`/`)||e.startsWith(`//`))return!1;let t=new URL(e,`https://eve.invalid`);return t.origin===`https://eve.invalid`&&t.search.length===0&&t.hash.length===0}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};const OAUTH_RESOURCE_SYMBOL=Symbol.for(`eve.channels.auth.oauthResource`);function oauthResource(e,t){let n=t.issuer===void 0?t.authorizationServers:[t.issuer];if(n.length===0||n.some(e=>!isValidOAuthIdentifierUrl(e)))throw Error(`oauthResource requires at least one HTTPS authorization server URL (HTTP is allowed only on loopback).`);if(t.resource!==void 0&&!isValidOAuthIdentifierUrl(t.resource))throw Error(`oauthResource resource must be an HTTPS URL without credentials, query, or fragment (HTTP is allowed only on loopback).`);if(t.metadataPath!==void 0&&!isValidMetadataPath(t.metadataPath))throw Error(`oauthResource metadataPath must be an absolute path without a host, query, or fragment.`);let r=Array.isArray(e)?e:[e],composed=async e=>{for(let t of r){let n=await t(e);if(n)return n}return null},i=collectDeclaredChallenges(r),a=withAuthChallenges(composed,i.length>0?i:[{scheme:`Bearer`}]);return Object.defineProperty(a,OAUTH_RESOURCE_SYMBOL,{enumerable:!1,value:t}),a}function readOAuthResourceOptions(e){if(!Array.isArray(e))return e[OAUTH_RESOURCE_SYMBOL]}const AUTH_CHALLENGES_SYMBOL=Symbol.for(`eve.channels.auth.challenges`);function withAuthChallenges(e,t){let wrapped=t=>e(t);return Object.defineProperty(wrapped,AUTH_CHALLENGES_SYMBOL,{value:t}),wrapped}function getDeclaredChallenges(e){return e[AUTH_CHALLENGES_SYMBOL]}function collectDeclaredChallenges(e){let t=new Set,n=[];for(let r of e)for(let e of getDeclaredChallenges(r)??[]){let r=formatChallenge(e);t.has(r)||(t.add(r),n.push(e))}return n}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}let r=collectDeclaredChallenges(n);return createUnauthorizedResponse({challenges:r.length>0?addInvalidBearerTokenError(e,r):[{scheme:`Bearer`}]})}function addInvalidBearerTokenError(e,t){let n=e.headers.get(`authorization`);return n===null||!/^Bearer(?:\s|$)/i.test(n.trim())||!t.some(e=>e.scheme===`Bearer`)?t:t.map(e=>e.scheme!==`Bearer`||e.parameters?.error!==void 0?e:{...e,parameters:{...e.parameters,error:`invalid_token`}})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return()=>isLocalDevelopmentServer()?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}function isLocalDevelopmentServer(){return process.env.VERCEL&&process.env.VERCEL_ENV===`development`?!0:isEveDevEnvironment()}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let r=decodeUnverifiedJwtClaims(e);if(r===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!isVercelOidcIssuer(r.issuer))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:r.issuer}),{ok:!1};if(r.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:r.issuer}),{ok:!1};if(!r.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:r.audiences,issuer:r.issuer}),{ok:!1};let i=resolveCurrentVercelProject(t),a=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:r.audiences,currentVercelProject:i,issuer:r.issuer,subjects:t.subjects??[]});return a.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:r.issuer,principalType:a.principal.principalType,subject:a.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(a.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:r.audiences,issuer:r.issuer,reason:a.kind,subjectsConfigured:(t.subjects??[]).length>0,...a.kind===`misconfigured`?{detail:a.message}:{}}),{ok:!1})}function resolveCurrentVercelProject(e){if(e.currentVercelProject!==void 0)return e.currentVercelProject;let t=process.env.VERCEL_PROJECT_ID?.trim();if(t===void 0||t.length===0)return;let n=process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim();return n===void 0||n.length===0?{projectId:t}:{environment:n,projectId:t}}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){return withAuthChallenges(async t=>{let n=extractBearerToken(t.headers.get(`authorization`)),r=e.currentVercelProject??(n!==null&&isLocalDevelopmentVercelOidc()?await resolveVercelOidcCurrentProject(t):void 0),i=await verifyVercelOidc(n,r===void 0?e:{...e,currentVercelProject:r});return i.ok?i.sessionAuth:null},[{scheme:`Bearer`}])}function isLocalDevelopmentVercelOidc(){return process.env.VERCEL_ENV===`development`?!0:process.env.VERCEL_ENV===`preview`||process.env.VERCEL_ENV===`production`?!1:isEveDevEnvironment()}function httpBasic(e,t){return withAuthChallenges(t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null},[{parameters:{realm:t?.realm??`eve`,charset:`UTF-8`},scheme:`Basic`}])}function jwtHmac(e){return withAuthChallenges(async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function jwtEcdsa(e){return withAuthChallenges(async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function oidc(e){return withAuthChallenges(async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function decodeUnverifiedJwtClaims(e){let n;try{n=decodeJwt(e)}catch{return null}return typeof n.iss!=`string`||n.iss.length===0?null:{audiences:typeof n.aud==`string`?[n.aud]:Array.isArray(n.aud)?n.aud.filter(e=>typeof e==`string`):[],issuer:n.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,escapeAuthChallengeParameter,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oauthResource,oidc,placeholderAuth,readOAuthResourceOptions,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc,withAuthChallenges};
1
+ import{isLoopbackHostname}from"#shared/network-address.js";import{createLogger}from"#internal/logging.js";import{decodeJwt}from"#compiled/jose/index.js";import{isVercelOidcIssuer}from"#shared/vercel-project.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{resolveVercelOidcCurrentProject}from"#channel/auth/vercel-oidc-project.js";import{authenticateHttpBasicStrategy}from"#channel/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#channel/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#channel/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#channel/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#channel/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#channel/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let n=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1,currentVercelProject:void 0});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){if(e===null||e.length===0)return{kind:`not-authenticated`};let n={acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}};return await authenticateOidcStrategy({strategy:t.currentVercelProject===void 0?n:{...n,currentVercelProject:t.currentVercelProject},token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e!==null&&isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeAuthChallengeParameter(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeAuthChallengeParameter(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}function isValidOAuthIdentifierUrl(t){try{let n=new URL(t);return(n.protocol===`https:`||n.protocol===`http:`&&isLoopbackHostname(n.hostname))&&n.username.length===0&&n.password.length===0&&n.search.length===0&&n.hash.length===0}catch{return!1}}function isValidMetadataPath(e){if(!e.startsWith(`/`)||e.startsWith(`//`))return!1;let t=new URL(e,`https://eve.invalid`);return t.origin===`https://eve.invalid`&&t.search.length===0&&t.hash.length===0}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};const OAUTH_RESOURCE_SYMBOL=Symbol.for(`eve.channels.auth.oauthResource`);function oauthResource(e,t){let n=t.issuer===void 0?t.authorizationServers:[t.issuer];if(n.length===0||n.some(e=>!isValidOAuthIdentifierUrl(e)))throw Error(`oauthResource requires at least one HTTPS authorization server URL (HTTP is allowed only on loopback).`);if(t.resource!==void 0&&!isValidOAuthIdentifierUrl(t.resource))throw Error(`oauthResource resource must be an HTTPS URL without credentials, query, or fragment (HTTP is allowed only on loopback).`);if(t.metadataPath!==void 0&&!isValidMetadataPath(t.metadataPath))throw Error(`oauthResource metadataPath must be an absolute path without a host, query, or fragment.`);let r=Array.isArray(e)?e:[e],composed=async e=>{for(let t of r){let n=await t(e);if(n)return n}return null},i=collectDeclaredChallenges(r),a=withAuthChallenges(composed,i.length>0?i:[{scheme:`Bearer`}]);return Object.defineProperty(a,OAUTH_RESOURCE_SYMBOL,{enumerable:!1,value:t}),a}function readOAuthResourceOptions(e){if(!Array.isArray(e))return e[OAUTH_RESOURCE_SYMBOL]}const AUTH_CHALLENGES_SYMBOL=Symbol.for(`eve.channels.auth.challenges`);function withAuthChallenges(e,t){let wrapped=t=>e(t);return Object.defineProperty(wrapped,AUTH_CHALLENGES_SYMBOL,{value:t}),wrapped}function getDeclaredChallenges(e){return e[AUTH_CHALLENGES_SYMBOL]}function collectDeclaredChallenges(e){let t=new Set,n=[];for(let r of e)for(let e of getDeclaredChallenges(r)??[]){let r=formatChallenge(e);t.has(r)||(t.add(r),n.push(e))}return n}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}let r=collectDeclaredChallenges(n);return createUnauthorizedResponse({challenges:r.length>0?addInvalidBearerTokenError(e,r):[{scheme:`Bearer`}]})}function addInvalidBearerTokenError(e,t){let n=e.headers.get(`authorization`);return n===null||!/^Bearer(?:\s|$)/i.test(n.trim())||!t.some(e=>e.scheme===`Bearer`)?t:t.map(e=>e.scheme!==`Bearer`||e.parameters?.error!==void 0?e:{...e,parameters:{...e.parameters,error:`invalid_token`}})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return()=>isLocalDevelopmentServer()?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}function isLocalDevelopmentServer(){return process.env.VERCEL&&process.env.VERCEL_ENV===`development`?!0:isEveDevEnvironment()}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let n=decodeUnverifiedJwtClaims(e);if(n===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!isVercelOidcIssuer(n.issuer))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};if(!n.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:n.audiences,issuer:n.issuer}),{ok:!1};let i=resolveCurrentVercelProject(t),a=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,currentVercelProject:i,issuer:n.issuer,subjects:t.subjects??[]});return a.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:a.principal.principalType,subject:a.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(a.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:a.kind,subjectsConfigured:(t.subjects??[]).length>0,...a.kind===`misconfigured`?{detail:a.message}:{}}),{ok:!1})}function resolveCurrentVercelProject(e){if(e.currentVercelProject!==void 0)return e.currentVercelProject;let t=process.env.VERCEL_PROJECT_ID?.trim();if(t===void 0||t.length===0)return;let n=process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim();return n===void 0||n.length===0?{projectId:t}:{environment:n,projectId:t}}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){return withAuthChallenges(async t=>{let n=extractBearerToken(t.headers.get(`authorization`)),r=e.currentVercelProject??(n!==null&&isLocalDevelopmentVercelOidc()?await resolveVercelOidcCurrentProject(t):void 0),i=await verifyVercelOidc(n,r===void 0?e:{...e,currentVercelProject:r});return i.ok?i.sessionAuth:null},[{scheme:`Bearer`}])}function isLocalDevelopmentVercelOidc(){return process.env.VERCEL_ENV===`development`?!0:process.env.VERCEL_ENV===`preview`||process.env.VERCEL_ENV===`production`?!1:isEveDevEnvironment()}function httpBasic(e,t){return withAuthChallenges(t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null},[{parameters:{realm:t?.realm??`eve`,charset:`UTF-8`},scheme:`Basic`}])}function jwtHmac(e){return withAuthChallenges(async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function jwtEcdsa(e){return withAuthChallenges(async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function oidc(e){return withAuthChallenges(async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function decodeUnverifiedJwtClaims(e){let t;try{t=decodeJwt(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,escapeAuthChallengeParameter,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oauthResource,oidc,placeholderAuth,readOAuthResourceOptions,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc,withAuthChallenges};
@@ -1,4 +1,4 @@
1
1
  import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{SLACK_MAX_BLOCKS_PER_MESSAGE,truncateMessageText,truncateTypingStatus}from"#public/channels/slack/limits.js";import{describeActionRequests}from"#public/channels/slack/action-status.js";import{buildSlackAuthContext,slackUserIdFromAuthContext}from"#public/channels/slack/auth.js";import{buildAuthCompletedText,buildAuthEphemeralBlocks,buildAuthRequiredPublicText,formatConnectionDisplayName}from"#public/channels/slack/connections.js";import{buildAnsweredBlocks,renderInputRequestPostParts}from"#public/channels/slack/hitl.js";const log=createLogger(`slack.defaults`);function blockContainsRequestAction(e,t){if(typeof e!=`object`||!e)return!1;let n=e,r=`eve_input:${t}`,i=`eve_input:tool-approval:${t}`;return[n.actions,n.elements].some(e=>Array.isArray(e)&&e.some(e=>{if(typeof e!=`object`||!e)return!1;let t=e.action_id;return typeof t==`string`&&(t.startsWith(r)||t.startsWith(i))}))}function defaultSlackAuth(e,t){let n=e.author;return n?buildSlackAuthContext({channelId:t.slack.channelId,fullName:n.fullName,isBot:n.isBot,teamId:e.teamId,threadTs:t.slack.threadTs,userId:n.userId,userName:n.userName}):null}async function defaultOnAppMention(e,t){return await e.thread.startTyping(`Thinking...`),{auth:defaultSlackAuth(t,e)}}async function defaultOnDirectMessage(e,t){return await e.thread.startTyping(`Thinking...`),{auth:defaultSlackAuth(t,e)}}function firstNonEmptyLine(e){for(let t of e.split(/\r?\n/u)){let e=t.trim();if(e.length>0)return e}}function defaultInputRequestedHandler(){return async(e,t,n)=>{for(let n of buildInputRequestPosts(e.requests)){let e=await t.thread.post({blocks:n.blocks,text:n.text});if(!e.id)continue;let r={...t.state.pendingApprovalCards};for(let t of n.requests)t.kind===`tool-approval`&&(r[t.requestId]={messageBlocks:n.blocks,messageTs:e.id});t.state.pendingApprovalCards=r}}}function buildInputRequestPosts(e){let t=[],n=[];for(let r of e){let e=renderInputRequestPostParts(r);e.details&&t.push({...e.details,request:r}),n.push({...e.controls,request:r})}return[...groupInputRequestPostParts(t),...groupInputRequestPostParts(n)]}function groupInputRequestPostParts(e){let t=[];for(let n of e){let e=t.at(-1);e&&e.blocks.length+n.blocks.length<=SLACK_MAX_BLOCKS_PER_MESSAGE?(e.blocks.push(...n.blocks),e.fallbacks.push(n.text),e.requests.push(n.request)):t.push({blocks:[...n.blocks],fallbacks:[n.text],requests:[n.request]})}return t.map(e=>({blocks:e.blocks,requests:e.requests,text:truncateMessageText(e.fallbacks.join(`
2
- `))}))}const defaultEvents={async"approval.candidate"(e,t,n){let r=t.state.pendingApprovalCandidateUsers?.[e.candidateId];if(e.outcome===`pending`&&r!==void 0){await t.thread.postEphemeral(r,`Checking whether you can approve this action…`);return}r!==void 0&&(e.outcome===`rejected`||e.outcome===`failed`)&&await t.thread.postEphemeral(r,e.reason??`We couldn’t verify your approval. Please try again.`)},async"approval.settled"(e,t,n){let r=t.state.pendingApprovalCards??{},i=r[e.requestId];if(i===void 0||t.state.channelId===null)return;let a=e.outcome===`approved`?`Approve`:`Cancel`,o=t.state.approvalResponderUsers?.[e.responderPrincipalId],s=i.messageBlocks.flatMap(t=>{if(!blockContainsRequestAction(t,e.requestId))return[t];if(typeof t!=`object`||!t)return[];let n=t;if(n.type!==`card`)return buildAnsweredBlocks({answerLabel:a,promptBlocks:[],userId:o});let{actions:r,...i}=n;return buildAnsweredBlocks({answerLabel:a,promptBlocks:[i],userId:o})});await t.slack.request(`chat.update`,{blocks:s,channel:t.state.channelId,text:`Answered: ${a}`,ts:i.messageTs});let c={...r};delete c[e.requestId],t.state.pendingApprovalCards=c},async"turn.started"(e,t,n){t.state.pendingToolCallMessage=null,t.state.lastReasoningTypingAtMs=null,t.state.lastReasoningTypingStatus=null,await t.thread.startTyping(`Working...`)},async"reasoning.appended"(e,t,n){let r=firstNonEmptyLine(e.reasoningSoFar);if(r===void 0)return;let i=truncateTypingStatus(r),o=t.state.lastReasoningTypingStatus,s=o!=null&&i.startsWith(o)&&i.length>=o.length+4,c=Date.now(),l=t.state.lastReasoningTypingAtMs;if(!s&&l!=null){let e=c-l;if(e>=0&&e<5e3)return}await t.thread.startTyping(i),t.state.lastReasoningTypingAtMs=c,t.state.lastReasoningTypingStatus=i},async"actions.requested"(e,t,n){let r=t.state.pendingToolCallMessage;if(t.state.pendingToolCallMessage=null,r){await t.thread.startTyping(truncateTypingStatus(r));return}await t.thread.startTyping(truncateTypingStatus(describeActionRequests(e.actions)))},async"message.completed"(e,t,n){if(e.finishReason===`tool-calls`){t.state.pendingToolCallMessage=e.message?firstNonEmptyLine(e.message)??null:null;return}if(t.state.pendingToolCallMessage=null,!e.message){await t.thread.startTyping();return}await t.thread.post(e.message)},async"turn.failed"(e,r,i){let a=formatErrorHint(e),o=extractErrorId(e.details);await r.thread.post([`I hit an error while handling your request${a}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...o?[``,`_Error id: \`${o}\`_`]:[]].join(`
2
+ `))}))}const defaultEvents={async"approval.candidate"(e,t,n){let r=t.state.pendingApprovalCandidateUsers?.[e.candidateId];if(e.outcome===`pending`&&r!==void 0){await t.thread.postEphemeral(r,`Checking whether you can approve this action…`);return}r!==void 0&&(e.outcome===`rejected`||e.outcome===`failed`)&&await t.thread.postEphemeral(r,e.reason??`We couldn’t verify your approval. Please try again.`)},async"approval.settled"(e,t,n){let r=t.state.pendingApprovalCards??{},i=r[e.requestId];if(i===void 0||t.state.channelId===null)return;let a=e.outcome===`approved`?`Approve`:`Cancel`,o=t.state.approvalResponderUsers?.[e.responderPrincipalId],s=i.messageBlocks.flatMap(t=>{if(!blockContainsRequestAction(t,e.requestId))return[t];if(typeof t!=`object`||!t)return[];let n=t;if(n.type!==`card`)return buildAnsweredBlocks({answerLabel:a,promptBlocks:[],userId:o});let{actions:r,...i}=n;return buildAnsweredBlocks({answerLabel:a,promptBlocks:[i],userId:o})});await t.slack.request(`chat.update`,{blocks:s,channel:t.state.channelId,text:`Answered: ${a}`,ts:i.messageTs});let c={...r};delete c[e.requestId];for(let[e,t]of Object.entries(c))t.messageTs===i.messageTs&&(c[e]={...t,messageBlocks:s});t.state.pendingApprovalCards=c},async"turn.started"(e,t,n){t.state.pendingToolCallMessage=null,t.state.lastReasoningTypingAtMs=null,t.state.lastReasoningTypingStatus=null,await t.thread.startTyping(`Working...`)},async"reasoning.appended"(e,t,n){let r=firstNonEmptyLine(e.reasoningSoFar);if(r===void 0)return;let i=truncateTypingStatus(r),o=t.state.lastReasoningTypingStatus,s=o!=null&&i.startsWith(o)&&i.length>=o.length+4,c=Date.now(),l=t.state.lastReasoningTypingAtMs;if(!s&&l!=null){let e=c-l;if(e>=0&&e<5e3)return}await t.thread.startTyping(i),t.state.lastReasoningTypingAtMs=c,t.state.lastReasoningTypingStatus=i},async"actions.requested"(e,t,n){let r=t.state.pendingToolCallMessage;if(t.state.pendingToolCallMessage=null,r){await t.thread.startTyping(truncateTypingStatus(r));return}await t.thread.startTyping(truncateTypingStatus(describeActionRequests(e.actions)))},async"message.completed"(e,t,n){if(e.finishReason===`tool-calls`){t.state.pendingToolCallMessage=e.message?firstNonEmptyLine(e.message)??null:null;return}if(t.state.pendingToolCallMessage=null,!e.message){await t.thread.startTyping();return}await t.thread.post(e.message)},async"turn.failed"(e,r,i){let a=formatErrorHint(e),o=extractErrorId(e.details);await r.thread.post([`I hit an error while handling your request${a}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...o?[``,`_Error id: \`${o}\`_`]:[]].join(`
3
3
  `))},async"session.failed"(e,r){let i=formatErrorHint(e),a=extractErrorId(e.details);await r.thread.post([`This session couldn't recover from an error${i}.`,``,`Start a new thread to continue — I can't pick this one back up.`,...a?[``,`_Error id: \`${a}\`_`]:[]].join(`
4
4
  `))},async"authorization.required"(e,t,n){let r=e.authorization?.displayName??formatConnectionDisplayName(e.name),i=e.candidateId===void 0?slackUserIdFromAuthContext(n.session.auth.current)??t.state.triggeringUserId??null:t.state.pendingApprovalCandidateUsers?.[e.candidateId]??null,a=e.authorization?.url,o=t.state.pendingAuthMessageTs??{};if(e.candidateId===void 0&&o[e.name]===void 0){let n=buildAuthRequiredPublicText({displayName:r,hasUser:i!==null});try{let r=await t.thread.post(n);r.id&&(t.state.pendingAuthMessageTs={...o,[e.name]:r.id})}catch(t){log.error(`Slack auth public message delivery failed`,{name:e.name,error:t})}}if(i&&a){let n=e.authorization?.userCode;try{await t.thread.postEphemeral(i,{blocks:buildAuthEphemeralBlocks({displayName:r,url:a,userCode:n}),text:n?`Sign in with ${r}: ${a} (code: ${n})`:`Sign in with ${r}: ${a}`})}catch(t){log.error(`Slack auth ephemeral delivery failed`,{name:e.name,error:t})}}},async"authorization.completed"(e,t,n){let r=e.authorization?.displayName??formatConnectionDisplayName(e.name);e.outcome===`authorized`&&e.candidateId===void 0&&await t.thread.startTyping(`Connected to ${r}. Resuming...`);let i=t.state.pendingAuthMessageTs??{},a=i[e.name];if(a===void 0)return;let o=buildAuthCompletedText({displayName:r,outcome:e.outcome,reason:e.reason});try{await t.slack.request(`chat.update`,{channel:t.slack.channelId,ts:a,text:o})}catch(t){log.error(`Slack auth status edit failed`,{name:e.name,error:t})}let s={...i};delete s[e.name],t.state.pendingAuthMessageTs=s}};export{defaultEvents,defaultInputRequestedHandler,defaultOnAppMention,defaultOnDirectMessage,defaultSlackAuth};
@@ -1 +1 @@
1
- import{getAdapterKind}from"#channel/adapter.js";import{SCHEDULE_ADAPTER}from"#channel/schedule.js";import{HTTP_ADAPTER}from"#channel/http.js";import{SUBAGENT_ADAPTER}from"#execution/subagent-adapter.js";import{RuntimeRegistryError}from"#internal/runtime-registry.js";const FRAMEWORK_ADAPTERS=[HTTP_ADAPTER,SUBAGENT_ADAPTER,SCHEDULE_ADAPTER],ADAPTER_NON_EVENT_FIELDS=new Set([`kind`,`state`,`deliver`,`createAdapterContext`,`fetchFile`,`instrumentation`]);function createRuntimeAdapterRegistry(e){let t=new Map,n=new Set;for(let e of FRAMEWORK_ADAPTERS){let r=requireAdapterKind(e);n.add(r),t.set(r,e)}for(let r of e.channels){if(r.adapter===void 0)continue;let e={logicalPath:r.logicalPath,sourceId:r.sourceId},i=r.adapter,a=requireAdapterKind(i,e);if(n.has(a)){if(carriesAdapterBehavior(i))throw new RuntimeRegistryError(`adapter`,`Channel adapter kind "${a}" is reserved by the framework. A route-declared adapter may share a framework kind only as a pass-through with no \`deliver\` hook, event handlers, \`attachments\` resolver, or \`createAdapterContext\` factory. Use a custom \`kind\` to add channel-specific behavior.`,{...e,entryName:a});continue}t.set(a,i)}return{adaptersByKind:t}}function deserializeRuntimeAdapter(e,t){let n=t,r=e.adaptersByKind.get(n.kind);if(r===void 0)throw Error(`Unknown adapter kind: "${n.kind}". Declare the adapter on the route that starts this session so the runtime can rehydrate it.`);return{...r,state:n.state}}function requireAdapterKind(t,n){let r=getAdapterKind(t);if(typeof r!=`string`||r.length===0)throw new RuntimeRegistryError(`adapter`,"Adapters must declare a non-empty `kind` field.",{entryName:`unknown`,logicalPath:n?.logicalPath,sourceId:n?.sourceId});return r}function carriesAdapterBehavior(e){if(e.deliver!==void 0||e.fetchFile!==void 0||e.createAdapterContext!==void 0)return!0;for(let[t,n]of Object.entries(e))if(!ADAPTER_NON_EVENT_FIELDS.has(t)&&typeof n==`function`)return!0;return!1}export{createRuntimeAdapterRegistry,deserializeRuntimeAdapter};
1
+ import{copyChannelActivityPresentation,getChannelActivityPresentation}from"#channel/activity-renderer.js";import{getAdapterKind}from"#channel/adapter.js";import{SCHEDULE_ADAPTER}from"#channel/schedule.js";import{HTTP_ADAPTER}from"#channel/http.js";import{SUBAGENT_ADAPTER}from"#execution/subagent-adapter.js";import{RuntimeRegistryError}from"#internal/runtime-registry.js";const FRAMEWORK_ADAPTERS=[HTTP_ADAPTER,SUBAGENT_ADAPTER,SCHEDULE_ADAPTER],ADAPTER_NON_EVENT_FIELDS=new Set([`kind`,`state`,`deliver`,`createAdapterContext`,`fetchFile`,`instrumentation`]);function createRuntimeAdapterRegistry(e){let t=new Map,n=new Set;for(let e of FRAMEWORK_ADAPTERS){let r=requireAdapterKind(e);n.add(r),t.set(r,e)}for(let r of e.channels){if(r.adapter===void 0)continue;let e={logicalPath:r.logicalPath,sourceId:r.sourceId},i=r.adapter,a=requireAdapterKind(i,e);if(n.has(a)){if(carriesAdapterBehavior(i))throw new RuntimeRegistryError(`adapter`,`Channel adapter kind "${a}" is reserved by the framework. A route-declared adapter may share a framework kind only as a pass-through with no \`deliver\` hook, event handlers, \`attachments\` resolver, or \`createAdapterContext\` factory. Use a custom \`kind\` to add channel-specific behavior.`,{...e,entryName:a});continue}t.set(a,i)}return{adaptersByKind:t}}function deserializeRuntimeAdapter(t,n){let r=n,i=t.adaptersByKind.get(r.kind);if(i===void 0)throw Error(`Unknown adapter kind: "${r.kind}". Declare the adapter on the route that starts this session so the runtime can rehydrate it.`);let a={...i,state:r.state};return copyChannelActivityPresentation(i,a),a}function requireAdapterKind(e,t){let r=getAdapterKind(e);if(typeof r!=`string`||r.length===0)throw new RuntimeRegistryError(`adapter`,"Adapters must declare a non-empty `kind` field.",{entryName:`unknown`,logicalPath:t?.logicalPath,sourceId:t?.sourceId});return r}function carriesAdapterBehavior(e){if(getChannelActivityPresentation(e)!==void 0||e.deliver!==void 0||e.fetchFile!==void 0||e.createAdapterContext!==void 0)return!0;for(let[t,n]of Object.entries(e))if(!ADAPTER_NON_EVENT_FIELDS.has(t)&&typeof n==`function`)return!0;return!1}export{createRuntimeAdapterRegistry,deserializeRuntimeAdapter};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{isLoopbackHostname}from"#shared/network-address.js";import{isObject}from"#shared/guards.js";import{toInputSchema}from"#tools/schema.js";import{tool}from"ai";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";import{passesToolFilter,resolveHeaders}from"#runtime/connections/mcp-client.js";import{HTTP_METHODS,operationDescription,operationName,uniqueName}from"#runtime/connections/openapi-operations.js";import{buildInputSchema,deref,derefSchema,isArray}from"#runtime/connections/openapi-schema.js";import{applySecurity,resolveSecurity}from"#runtime/connections/openapi-security.js";import{extractServerUrl,parseSpecDocument}from"#runtime/connections/openapi-spec.js";const log=createLogger(`runtime.connections.openapi-client`),SWAGGER_PARAMETER_SCHEMA_KEYS=[`default`,`enum`,`exclusiveMaximum`,`exclusiveMinimum`,`format`,`items`,`maximum`,`maxItems`,`maxLength`,`minimum`,`minItems`,`minLength`,`multipleOf`,`pattern`,`type`,`uniqueItems`];var OpenApiConnectionClient=class{#e;#t;#n;constructor(e){this.#n=e}async connect(){return this.#r()}async getToolMetadata(){return(await this.#r()).metadata}async getTools(){return(await this.#r()).tools}async executeTool(e,t,r){let i=await this.#r(),a=i.operations.get(e);if(a===void 0)throw Error(`Tool "${e}" not found in connection "${this.#n.connectionName}".`);return this.#f(a,i.baseUrl,isObject(t)?t:{},{abortSignal:r.abortSignal,callId:r.callId})}async close(){this.#e=void 0,this.#t=void 0}async#r(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#i();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#i(){let e=await this.#o(),t=this.#a(e),o=this.#s(e),c=this.#n.tools,l=c===void 0?o:o.filter(e=>passesToolFilter(e.toolName,c)),u=[],d=new Map,f={},p=Object.keys(this.#n.toolCall?.providedArguments??{});for(let e of l){let o=omitProvidedArgumentsFromSchema(e.inputSchema,p),s;try{s=toInputSchema(o)}catch(t){log.warn(`omitting OpenAPI operation with an invalid input schema`,{connectionName:this.#n.connectionName,error:t,toolName:e.toolName});continue}d.set(e.toolName,e),u.push({description:e.description,inputSchema:o,name:e.toolName}),f[e.toolName]=tool({description:e.description,inputSchema:s,execute:async(r,i)=>this.#f(e,t,isObject(r)?r:{},{abortSignal:i?.abortSignal,callId:i.toolCallId})})}return{metadata:u,operations:d,tools:f,baseUrl:t}}#a(e){let t=this.#n.url,n=typeof t==`string`&&t.trim().length>0?t:extractServerUrl(e,this.#n.spec);if(n===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" has no base URL: set "baseUrl" or ensure the document declares an absolute "servers" entry or Swagger "host".`);return assertSecureUrl(n,this.#n.connectionName,`base`),n}async#o(){let e=this.#n.spec;if(e===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" is missing its "spec" source.`);if(typeof e!=`string`)return e;assertSecureUrl(e,this.#n.connectionName,`spec`);let t;try{t=await fetch(e,{headers:{accept:`application/json, application/yaml, text/yaml, */*`}})}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": ${String(t)}`)}if(t.redirected&&assertSecureUrl(t.url,this.#n.connectionName,`spec`),!t.ok)throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": HTTP ${t.status}.`);let r=await t.text(),i;try{i=parseSpecDocument(r)}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" could not be parsed as JSON or YAML: ${String(t)}`)}if(!isObject(i))throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" is not an OpenAPI document object.`);return i}#s(e){let t=e.paths;if(!isObject(t))return[];let r=[],i=new Set;for(let[a,o]of Object.entries(t)){if(!isObject(o))continue;let t=isArray(o.parameters)?o.parameters:[];for(let s of HTTP_METHODS){let c=o[s];if(!isObject(c))continue;let l=uniqueName(operationName(c,s,a),i),m=isArray(c.parameters)?c.parameters:[],h=[...t,...m],g=this.#c(e,h),_=this.#l(e,c.requestBody,h);r.push({toolName:l,method:s,pathTemplate:a,description:operationDescription(c),parameters:g,requestBody:_,inputSchema:buildInputSchema(g,_),security:resolveSecurity(e,c)})}}return r}#c(e,t){let r=[];for(let i of t){let t=isObject(i)?deref(e,i):i;if(!isObject(t))continue;let a=t.in;if(a!==`path`&&a!==`query`&&a!==`header`&&a!==`cookie`||typeof t.name!=`string`)continue;let o=this.#u(e,t);r.push({name:t.name,location:a,required:t.required===!0||a===`path`,schema:o,description:typeof t.description==`string`?t.description:void 0})}return r}#l(e,t,r=[]){if(isObject(t)){let r=deref(e,t);if(isObject(r)&&isObject(r.content)){let t=r.content,i=`application/json`in t?`application/json`:Object.keys(t)[0];if(i!==void 0){let a=t[i],o=isObject(a)&&isObject(a.schema)?derefSchema(e,a.schema):{};return{required:r.required===!0,contentType:i,schema:o}}}}return this.#d(e,r)}#u(e,t){if(isObject(t.schema))return derefSchema(e,t.schema);let r={};for(let e of SWAGGER_PARAMETER_SCHEMA_KEYS)t[e]!==void 0&&(r[e]=t[e]);return derefSchema(e,r)}#d(e,t){for(let r of t){let t=isObject(r)?deref(e,r):r;if(!isObject(t)||t.in!==`body`)continue;let i=isObject(t.schema)?derefSchema(e,t.schema):{};return{required:t.required===!0,contentType:`application/json`,schema:i}}}async#f(e,t,n,r){let i=await resolveProvidedArguments({args:n,callId:r.callId,connection:this.#n,toolName:e.toolName}),a=await resolveHeaders(this.#n),s=e.pathTemplate,l=new URLSearchParams,u=[];for(let t of e.parameters){let e=i[t.name];e!=null&&(t.location===`path`?s=s.replace(`{${t.name}}`,encodeURIComponent(String(e))):t.location===`query`?appendQuery(l,t.name,e):t.location===`cookie`?u.push(`${t.name}=${encodeURIComponent(String(e))}`):a[t.name]=String(e))}if(applySecurity(e.security,this.#n,a,l,u),u.length>0){let e=a.cookie??a.Cookie;delete a.Cookie,a.cookie=[e,...u].filter(e=>!!e).join(`; `)}let d=new URL(joinPath(t,s));d.search=l.toString();let f;e.requestBody!==void 0&&i.body!==void 0&&(f=JSON.stringify(i.body),a[`content-type`]=e.requestBody.contentType);let p=await fetch(d,{method:e.method.toUpperCase(),headers:a,body:f,signal:r?.abortSignal});return{status:p.status,statusText:p.statusText,body:await readResponseBody(p)}}};function appendQuery(e,t,n){if(isArray(n)){for(let r of n)e.append(t,String(r));return}e.append(t,String(n))}function joinPath(e,t){return`${e.endsWith(`/`)?e.slice(0,-1):e}${t.startsWith(`/`)?t:`/${t}`}`}function assertSecureUrl(e,n,r){let i;try{i=new URL(e)}catch{throw Error(`OpenAPI connection "${n}" has an invalid ${r} URL "${e}".`)}if(i.protocol!==`https:`&&!(i.protocol===`http:`&&isLoopbackHostname(i.hostname)))throw Error(`OpenAPI connection "${n}" must use https for its ${r} (got "${i.protocol}//${i.host}").`)}async function readResponseBody(e){let t=await e.text();if(t.length===0)return null;if((e.headers.get(`content-type`)??``).includes(`application/json`))try{return JSON.parse(t)}catch{return t}return t}export{OpenApiConnectionClient};
1
+ import{isLoopbackHostname}from"#shared/network-address.js";import{createLogger}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{toInputSchema}from"#tools/schema.js";import{tool}from"ai";import{omitProvidedArgumentsFromSchema,resolveProvidedArguments}from"#runtime/connections/provided-arguments.js";import{passesToolFilter,resolveHeaders}from"#runtime/connections/mcp-client.js";import{HTTP_METHODS,operationDescription,operationName,uniqueName}from"#runtime/connections/openapi-operations.js";import{buildInputSchema,deref,derefSchema,isArray}from"#runtime/connections/openapi-schema.js";import{applySecurity,resolveSecurity}from"#runtime/connections/openapi-security.js";import{extractServerUrl,parseSpecDocument}from"#runtime/connections/openapi-spec.js";const log=createLogger(`runtime.connections.openapi-client`),SWAGGER_PARAMETER_SCHEMA_KEYS=[`default`,`enum`,`exclusiveMaximum`,`exclusiveMinimum`,`format`,`items`,`maximum`,`maxItems`,`maxLength`,`minimum`,`minItems`,`minLength`,`multipleOf`,`pattern`,`type`,`uniqueItems`];var OpenApiConnectionClient=class{#e;#t;#n;constructor(e){this.#n=e}async connect(){return this.#r()}async getToolMetadata(){return(await this.#r()).metadata}async getTools(){return(await this.#r()).tools}async executeTool(e,t,r){let i=await this.#r(),a=i.operations.get(e);if(a===void 0)throw Error(`Tool "${e}" not found in connection "${this.#n.connectionName}".`);return this.#f(a,i.baseUrl,isObject(t)?t:{},{abortSignal:r.abortSignal,callId:r.callId})}async close(){this.#e=void 0,this.#t=void 0}async#r(){if(this.#t!==void 0)return this.#t;if(this.#e!==void 0)return this.#e;this.#e=this.#i();try{return this.#t=await this.#e,this.#t}catch(e){throw this.#e=void 0,e}}async#i(){let e=await this.#o(),t=this.#a(e),o=this.#s(e),c=this.#n.tools,l=c===void 0?o:o.filter(e=>passesToolFilter(e.toolName,c)),u=[],d=new Map,f={},p=Object.keys(this.#n.toolCall?.providedArguments??{});for(let e of l){let o=omitProvidedArgumentsFromSchema(e.inputSchema,p),s;try{s=toInputSchema(o)}catch(t){log.warn(`omitting OpenAPI operation with an invalid input schema`,{connectionName:this.#n.connectionName,error:t,toolName:e.toolName});continue}d.set(e.toolName,e),u.push({description:e.description,inputSchema:o,name:e.toolName}),f[e.toolName]=tool({description:e.description,inputSchema:s,execute:async(r,i)=>this.#f(e,t,isObject(r)?r:{},{abortSignal:i?.abortSignal,callId:i.toolCallId})})}return{metadata:u,operations:d,tools:f,baseUrl:t}}#a(e){let t=this.#n.url,n=typeof t==`string`&&t.trim().length>0?t:extractServerUrl(e,this.#n.spec);if(n===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" has no base URL: set "baseUrl" or ensure the document declares an absolute "servers" entry or Swagger "host".`);return assertSecureUrl(n,this.#n.connectionName,`base`),n}async#o(){let e=this.#n.spec;if(e===void 0)throw Error(`OpenAPI connection "${this.#n.connectionName}" is missing its "spec" source.`);if(typeof e!=`string`)return e;assertSecureUrl(e,this.#n.connectionName,`spec`);let t;try{t=await fetch(e,{headers:{accept:`application/json, application/yaml, text/yaml, */*`}})}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": ${String(t)}`)}if(t.redirected&&assertSecureUrl(t.url,this.#n.connectionName,`spec`),!t.ok)throw Error(`OpenAPI connection "${this.#n.connectionName}" failed to fetch its spec from "${e}": HTTP ${t.status}.`);let r=await t.text(),i;try{i=parseSpecDocument(r)}catch(t){throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" could not be parsed as JSON or YAML: ${String(t)}`)}if(!isObject(i))throw Error(`OpenAPI connection "${this.#n.connectionName}" spec at "${e}" is not an OpenAPI document object.`);return i}#s(e){let t=e.paths;if(!isObject(t))return[];let r=[],i=new Set;for(let[a,o]of Object.entries(t)){if(!isObject(o))continue;let t=isArray(o.parameters)?o.parameters:[];for(let s of HTTP_METHODS){let c=o[s];if(!isObject(c))continue;let l=uniqueName(operationName(c,s,a),i),m=isArray(c.parameters)?c.parameters:[],h=[...t,...m],g=this.#c(e,h),_=this.#l(e,c.requestBody,h);r.push({toolName:l,method:s,pathTemplate:a,description:operationDescription(c),parameters:g,requestBody:_,inputSchema:buildInputSchema(g,_),security:resolveSecurity(e,c)})}}return r}#c(e,t){let r=[];for(let i of t){let t=isObject(i)?deref(e,i):i;if(!isObject(t))continue;let a=t.in;if(a!==`path`&&a!==`query`&&a!==`header`&&a!==`cookie`||typeof t.name!=`string`)continue;let o=this.#u(e,t);r.push({name:t.name,location:a,required:t.required===!0||a===`path`,schema:o,description:typeof t.description==`string`?t.description:void 0})}return r}#l(e,t,r=[]){if(isObject(t)){let r=deref(e,t);if(isObject(r)&&isObject(r.content)){let t=r.content,i=`application/json`in t?`application/json`:Object.keys(t)[0];if(i!==void 0){let a=t[i],o=isObject(a)&&isObject(a.schema)?derefSchema(e,a.schema):{};return{required:r.required===!0,contentType:i,schema:o}}}}return this.#d(e,r)}#u(e,t){if(isObject(t.schema))return derefSchema(e,t.schema);let r={};for(let e of SWAGGER_PARAMETER_SCHEMA_KEYS)t[e]!==void 0&&(r[e]=t[e]);return derefSchema(e,r)}#d(e,t){for(let r of t){let t=isObject(r)?deref(e,r):r;if(!isObject(t)||t.in!==`body`)continue;let i=isObject(t.schema)?derefSchema(e,t.schema):{};return{required:t.required===!0,contentType:`application/json`,schema:i}}}async#f(e,t,n,r){let i=await resolveProvidedArguments({args:n,callId:r.callId,connection:this.#n,toolName:e.toolName}),a=await resolveHeaders(this.#n),s=e.pathTemplate,l=new URLSearchParams,u=[];for(let t of e.parameters){let e=i[t.name];e!=null&&(t.location===`path`?s=s.replace(`{${t.name}}`,encodeURIComponent(String(e))):t.location===`query`?appendQuery(l,t.name,e):t.location===`cookie`?u.push(`${t.name}=${encodeURIComponent(String(e))}`):a[t.name]=String(e))}if(applySecurity(e.security,this.#n,a,l,u),u.length>0){let e=a.cookie??a.Cookie;delete a.Cookie,a.cookie=[e,...u].filter(e=>!!e).join(`; `)}let d=new URL(joinPath(t,s));d.search=l.toString();let f;e.requestBody!==void 0&&i.body!==void 0&&(f=JSON.stringify(i.body),a[`content-type`]=e.requestBody.contentType);let p=await fetch(d,{method:e.method.toUpperCase(),headers:a,body:f,signal:r?.abortSignal});return{status:p.status,statusText:p.statusText,body:await readResponseBody(p)}}};function appendQuery(e,t,n){if(isArray(n)){for(let r of n)e.append(t,String(r));return}e.append(t,String(n))}function joinPath(e,t){return`${e.endsWith(`/`)?e.slice(0,-1):e}${t.startsWith(`/`)?t:`/${t}`}`}function assertSecureUrl(t,n,r){let i;try{i=new URL(t)}catch{throw Error(`OpenAPI connection "${n}" has an invalid ${r} URL "${t}".`)}if(i.protocol!==`https:`&&!(i.protocol===`http:`&&isLoopbackHostname(i.hostname)))throw Error(`OpenAPI connection "${n}" must use https for its ${r} (got "${i.protocol}//${i.host}").`)}async function readResponseBody(e){let t=await e.text();if(t.length===0)return null;if((e.headers.get(`content-type`)??``).includes(`application/json`))try{return JSON.parse(t)}catch{return t}return t}export{OpenApiConnectionClient};
@@ -1 +1 @@
1
- import{expectBoolean,expectFunction,expectObjectRecord,expectOnlyKnownKeys,expectString,getOptionalStringRecordProperty}from"#internal/authored-module.js";import{EVE_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{serializeOutputSchema}from"#tools/schema.js";async function normalizeDynamicRemoteAgentConfig(t){let i=`Dynamic subagent "${t.name}" must return defineAgent(...), defineRemoteAgent(...), or null.`,a=expectObjectRecord(t.value,i);if(expectOnlyKnownKeys(a,[`auth`,`description`,`forwardPrincipal`,`headers`,`kind`,`outputSchema`,`path`,`url`],i),a.kind!==`remote`)throw Error(i);let o=await resolveUrl(a.url,i),s=readCredentialsStepId(a);if(validateCredentials(a,i),(a.auth!==void 0||a.headers!==void 0)&&s===void 0)throw Error(`${i} Dynamic remote auth and headers must be compiled by eve so credentials stay out of durable workflow state.`);let c={description:expectString(a.description,i),path:a.path===void 0?EVE_SESSION_ROUTE_PATH:expectString(a.path,i),url:o};return s!==void 0&&(c.credentialsStepId=s),a.forwardPrincipal!==void 0&&(c.forwardPrincipal=expectBoolean(a.forwardPrincipal,i)),a.outputSchema!==void 0&&(c.outputSchema=serializeOutputSchema(a.outputSchema)),c}async function resolveUrl(e,n){let r=typeof e==`function`?await expectFunction(e,n)():expectString(e,n);if(r.length===0)throw Error(`${n} The "url" field must resolve to a non-empty string.`);return r}function validateCredentials(e,n){e.auth!==void 0&&expectFunction(e.auth,n),e.headers!==void 0&&typeof e.headers!=`function`&&getOptionalStringRecordProperty(e,`headers`,n)}function readCredentialsStepId(e){let t=e.__eveResolveRemoteAgentCredentials;if(typeof t!=`function`)return;let n=t.stepId;return typeof n==`string`?n:void 0}export{normalizeDynamicRemoteAgentConfig};
1
+ import{EVE_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{expectBoolean,expectFunction,expectObjectRecord,expectOnlyKnownKeys,expectString,getOptionalStringRecordProperty}from"#internal/authored-module.js";import{serializeOutputSchema}from"#tools/schema.js";async function normalizeDynamicRemoteAgentConfig(n){let i=`Dynamic subagent "${n.name}" must return defineAgent(...), defineRemoteAgent(...), or null.`,a=expectObjectRecord(n.value,i);if(expectOnlyKnownKeys(a,[`auth`,`description`,`forwardPrincipal`,`headers`,`kind`,`outputSchema`,`path`,`url`],i),a.kind!==`remote`)throw Error(i);let o=await resolveUrl(a.url,i),s=readCredentialsStepId(a);if(validateCredentials(a,i),(a.auth!==void 0||a.headers!==void 0)&&s===void 0)throw Error(`${i} Dynamic remote auth and headers must be compiled by eve so credentials stay out of durable workflow state.`);let c={description:expectString(a.description,i),path:a.path===void 0?EVE_SESSION_ROUTE_PATH:expectString(a.path,i),url:o};return s!==void 0&&(c.credentialsStepId=s),a.forwardPrincipal!==void 0&&(c.forwardPrincipal=expectBoolean(a.forwardPrincipal,i)),a.outputSchema!==void 0&&(c.outputSchema=serializeOutputSchema(a.outputSchema)),c}async function resolveUrl(e,t){let r=typeof e==`function`?await expectFunction(e,t)():expectString(e,t);if(r.length===0)throw Error(`${t} The "url" field must resolve to a non-empty string.`);return r}function validateCredentials(e,t){e.auth!==void 0&&expectFunction(e.auth,t),e.headers!==void 0&&typeof e.headers!=`function`&&getOptionalStringRecordProperty(e,`headers`,t)}function readCredentialsStepId(e){let t=e.__eveResolveRemoteAgentCredentials;if(typeof t!=`function`)return;let n=t.stepId;return typeof n==`string`?n:void 0}export{normalizeDynamicRemoteAgentConfig};
@@ -1 +1 @@
1
- import{captureVercel}from"#setup/primitives/index.js";import{AI_GATEWAY_MODELS_URL}from"#internal/gateway.js";import{buildPackageUserAgent}from"#internal/user-agent.js";async function fetchGatewayModelIds(n){let r=await captureVercel([`curl`,AI_GATEWAY_MODELS_URL,`--`,`--silent`,`--header`,`User-Agent: ${buildPackageUserAgent()}`],{cwd:n});if(!r.ok)return null;try{let e=JSON.parse(r.stdout);if(!Array.isArray(e.data))return null;let t=e.data.map(e=>e.id).filter(e=>typeof e==`string`);return new Set(t)}catch{return null}}export{fetchGatewayModelIds};
1
+ import{captureVercel}from"#setup/primitives/index.js";import{buildPackageUserAgent}from"#internal/user-agent.js";import{AI_GATEWAY_MODELS_URL}from"#internal/gateway.js";async function fetchGatewayModelIds(n){let r=await captureVercel([`curl`,AI_GATEWAY_MODELS_URL,`--`,`--silent`,`--header`,`User-Agent: ${buildPackageUserAgent()}`],{cwd:n});if(!r.ok)return null;try{let e=JSON.parse(r.stdout);if(!Array.isArray(e.data))return null;let t=e.data.map(e=>e.id).filter(e=>typeof e==`string`);return new Set(t)}catch{return null}}export{fetchGatewayModelIds};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.58`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.47.2`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,n){let r=parseChatGptModelSelection(e);return r===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(r)}),\n${reasoningTemplateLine(n)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,n){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(n.model)!==void 0?renderAgentTemplate(n.model,n.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,n.appName).replaceAll(`__EVE_INIT_MODEL__`,n.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(n.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(n.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(n.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,n.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,n.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,n.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,n.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,n.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,n.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.58`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.47.3`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,n){let r=parseChatGptModelSelection(e);return r===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(r)}),\n${reasoningTemplateLine(n)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,n){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(n.model)!==void 0?renderAgentTemplate(n.model,n.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,n.appName).replaceAll(`__EVE_INIT_MODEL__`,n.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(n.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(n.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(n.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,n.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,n.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,n.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,n.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,n.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,n.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -44,7 +44,7 @@ export declare const WEB_APP_TEMPLATE_FILES: {
44
44
  export declare const WEB_APP_SIGN_IN_WITH_VERCEL_TEMPLATE_FILES: {
45
45
  readonly "agent/channels/eve.ts": 'import { eveChannel } from "eve/channels/eve";\nimport { localDev, type AuthFn, vercelOidc } from "eve/channels/auth";\nimport { auth } from "@/lib/auth";\n\nconst betterAuthSession: AuthFn<Request> = async (request) => {\n const session = await auth.api.getSession({ headers: request.headers });\n if (!session) return null;\n\n const attributes: Record<string, string> = {\n email: session.user.email,\n name: session.user.name,\n };\n if (session.user.image) {\n attributes.picture = session.user.image;\n }\n\n return {\n attributes,\n authenticator: "better-auth:vercel",\n principalId: session.user.id,\n principalType: "user",\n };\n};\n\nexport default eveChannel({\n auth: [betterAuthSession, vercelOidc(), localDev()],\n});\n';
46
46
  readonly "app/_components/authenticated-agent-chat.tsx": 'import { headers } from "next/headers";\nimport { auth } from "@/lib/auth";\nimport { AgentChat } from "./agent-chat";\nimport { AccountControl, SignIn } from "./web-chat-auth";\n\nexport async function AuthenticatedAgentChat({\n sessionId,\n sessionless,\n}: {\n readonly sessionId?: string;\n readonly sessionless?: boolean;\n}) {\n if (process.env.NODE_ENV === "development") {\n return <AgentChat sessionId={sessionId} sessionless={sessionless} />;\n }\n\n const session = await auth.api.getSession({ headers: await headers() });\n if (!session) return <SignIn />;\n\n return (\n <>\n <AgentChat sessionId={sessionId} sessionless={sessionless} />\n <AccountControl\n email={session.user.email}\n image={session.user.image}\n name={session.user.name}\n />\n </>\n );\n}\n';
47
- readonly "app/_components/web-chat-auth.tsx": '"use client";\n\nimport { LogOutIcon } from "lucide-react";\nimport { useState } from "react";\nimport { Button } from "@/components/ui/button";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from "@/components/ui/dropdown-menu";\nimport { authClient } from "@/lib/auth-client";\n\nconst AGENT_NAME = "__EVE_INIT_APP_NAME__";\n\nexport function SignIn() {\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string>();\n\n async function signIn() {\n setPending(true);\n setError(undefined);\n try {\n const result = await authClient.signIn.social({\n callbackURL: "/",\n provider: "vercel",\n });\n if (!result.error) return;\n setPending(false);\n setError("Sign-in failed. Try again.");\n } catch {\n setPending(false);\n setError("Sign-in failed. Try again.");\n }\n }\n\n return (\n <main className="flex min-h-dvh items-center justify-center bg-background px-8 text-foreground">\n <div className="flex w-full max-w-[22rem] flex-col gap-5">\n <div className="text-foreground opacity-[0.08] dark:opacity-[0.12]">\n <EveWordmark className="h-auto w-[4.875rem]" />\n </div>\n <section aria-label="Sign in" className="flex flex-col gap-2">\n <h1 className="max-w-full break-words font-medium text-sm leading-6">{AGENT_NAME}</h1>\n <p className="flex flex-wrap items-center gap-2 text-muted-foreground text-sm leading-6">\n <span className="inline-flex items-center gap-2 text-emerald-600 dark:text-emerald-400">\n <span aria-hidden="true" className="size-1.5 rounded-full bg-current" />\n Ready\n </span>\n <span aria-hidden="true" className="text-border">\n /\n </span>\n <span>Sign in to start a session</span>\n </p>\n <Button className="mt-3 w-full gap-2 text-sm" disabled={pending} onClick={signIn}>\n <svg aria-hidden="true" className="size-3 fill-current" viewBox="0 0 24 20">\n <path d="M12 0 24 20H0L12 0Z" />\n </svg>\n <span className="leading-5">{pending ? "Redirecting…" : "Continue with Vercel"}</span>\n </Button>\n {error ? (\n <p className="text-destructive text-sm" role="alert">\n {error}\n </p>\n ) : null}\n </section>\n </div>\n </main>\n );\n}\n\nfunction EveWordmark({ className }: { readonly className?: string }) {\n return (\n <svg\n aria-hidden="true"\n className={className}\n fill="none"\n viewBox="0 0 169 53"\n xmlns="http://www.w3.org/2000/svg"\n >\n <path\n d="M169 8.47h-51.39L81.73 53H70.36L113 0H169zM169 44.51v8.47h-45.87V44.5zM45.87 52.98H0V44.5h45.87zM38.66 30.55H0v-8.47h38.66z"\n fill="currentColor"\n />\n <path d="M169 30.55h-38.66v-8.47H169zM75.52 8.47H0V0h75.52z" fill="currentColor" />\n </svg>\n );\n}\n\nexport function AccountControl({\n email,\n image,\n name,\n}: {\n readonly email: string;\n readonly image?: string | null;\n readonly name: string;\n}) {\n const [imageFailed, setImageFailed] = useState(false);\n const [pending, setPending] = useState(false);\n const initials = getInitials(name, email);\n\n async function signOut() {\n setPending(true);\n try {\n await authClient.signOut({\n fetchOptions: {\n onError: () => setPending(false),\n onSuccess: () => window.location.assign("/"),\n },\n });\n } catch {\n setPending(false);\n }\n }\n\n return (\n <div className="fixed top-3 right-3 z-10">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n aria-label={`Open account menu for ${name}`}\n className="size-9 cursor-pointer overflow-hidden rounded-full p-0"\n size="icon"\n variant="outline"\n >\n {image && !imageFailed ? (\n <img\n alt=""\n className="size-full object-cover"\n onError={() => setImageFailed(true)}\n src={image}\n />\n ) : (\n <span aria-hidden="true" className="font-medium text-xs">\n {initials}\n </span>\n )}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align="end" className="w-64">\n <div className="min-w-0 px-2 py-1.5 text-sm">\n <span className="block truncate font-medium leading-5" title={name}>\n {name}\n </span>\n <span className="block truncate text-muted-foreground leading-5" title={email}>\n {email}\n </span>\n </div>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className="cursor-pointer justify-between"\n disabled={pending}\n onSelect={signOut}\n >\n {pending ? "Logging out…" : "Log out"}\n <LogOutIcon aria-hidden="true" />\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n\nfunction getInitials(name: string, email: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length >= 2) {\n return `${parts[0]?.[0] ?? ""}${parts.at(-1)?.[0] ?? ""}`.toUpperCase();\n }\n return (parts[0]?.[0] ?? email[0] ?? "?").toUpperCase();\n}\n';
47
+ readonly "app/_components/web-chat-auth.tsx": '"use client";\n\nimport { LogOutIcon } from "lucide-react";\nimport { useState } from "react";\nimport { Button } from "@/components/ui/button";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from "@/components/ui/dropdown-menu";\nimport { authClient } from "@/lib/auth-client";\n\nconst AGENT_NAME = "__EVE_INIT_APP_NAME__";\n\nexport function SignIn() {\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string>();\n\n async function signIn() {\n setPending(true);\n setError(undefined);\n try {\n const result = await authClient.signIn.social({\n callbackURL: "/",\n provider: "vercel",\n });\n if (!result.error) return;\n setPending(false);\n setError("Sign-in failed. Try again.");\n } catch {\n setPending(false);\n setError("Sign-in failed. Try again.");\n }\n }\n\n return (\n <main className="flex min-h-dvh items-center justify-center bg-background px-8 text-foreground">\n <div className="flex w-full max-w-[22rem] flex-col gap-5">\n <div className="text-foreground opacity-[0.08] dark:opacity-[0.12]">\n <EveWordmark className="h-auto w-[4.875rem]" />\n </div>\n <section aria-label="Sign in" className="flex flex-col gap-2">\n <h1 className="max-w-full break-words font-medium text-sm leading-6">{AGENT_NAME}</h1>\n <p className="flex flex-wrap items-center gap-2 text-muted-foreground text-sm leading-6">\n <span className="inline-flex items-center gap-2 text-emerald-600 dark:text-emerald-400">\n <span aria-hidden="true" className="size-1.5 rounded-full bg-current" />\n Ready\n </span>\n <span aria-hidden="true" className="text-border">\n /\n </span>\n <span>Sign in to start a session</span>\n </p>\n <Button className="mt-3 w-full gap-2 text-sm" disabled={pending} onClick={signIn}>\n <svg aria-hidden="true" className="size-3 fill-current" viewBox="0 0 24 20">\n <path d="M12 0 24 20H0L12 0Z" />\n </svg>\n <span className="leading-5">{pending ? "Redirecting…" : "Continue with Vercel"}</span>\n </Button>\n {error ? (\n <p className="text-destructive text-sm" role="alert">\n {error}\n </p>\n ) : null}\n </section>\n </div>\n </main>\n );\n}\n\nfunction EveWordmark({ className }: { readonly className?: string }) {\n return (\n <svg\n aria-hidden="true"\n className={className}\n fill="none"\n viewBox="0 0 169 53"\n xmlns="http://www.w3.org/2000/svg"\n >\n <path\n d="M169 8.47h-51.39L81.73 53H70.36L113 0H169zM169 44.51v8.47h-45.87V44.5zM45.87 52.98H0V44.5h45.87zM38.66 30.55H0v-8.47h38.66z"\n fill="currentColor"\n />\n <path d="M169 30.55h-38.66v-8.47H169zM75.52 8.47H0V0h75.52z" fill="currentColor" />\n </svg>\n );\n}\n\nexport function AccountControl({\n email,\n image,\n name,\n}: {\n readonly email: string;\n readonly image?: string | null;\n readonly name: string;\n}) {\n const [imageFailed, setImageFailed] = useState(false);\n const [pending, setPending] = useState(false);\n const initials = getInitials(name, email);\n\n async function signOut() {\n setPending(true);\n try {\n await authClient.signOut({\n fetchOptions: {\n onError: () => setPending(false),\n onSuccess: () => window.location.assign("/"),\n },\n });\n } catch {\n setPending(false);\n }\n }\n\n return (\n <div className="fixed top-3 left-4 z-30 flex h-8 items-center">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n aria-label={`Open account menu for ${name}`}\n className="relative size-7 cursor-pointer overflow-hidden rounded-full p-0"\n size="icon-sm"\n variant="ghost"\n >\n {image && !imageFailed ? (\n <img\n alt=""\n className="size-full object-cover"\n onError={() => setImageFailed(true)}\n src={image}\n />\n ) : (\n <span aria-hidden="true" className="font-medium text-xs">\n {initials}\n </span>\n )}\n <span\n aria-hidden="true"\n className="pointer-events-none absolute inset-0 rounded-full border border-black/20 dark:border-white/25"\n />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align="start" className="w-64">\n <div className="min-w-0 px-2 py-1.5 text-sm">\n <span className="block truncate font-medium leading-5" title={name}>\n {name}\n </span>\n <span className="block truncate text-muted-foreground leading-5" title={email}>\n {email}\n </span>\n </div>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className="cursor-pointer justify-between"\n disabled={pending}\n onSelect={signOut}\n >\n {pending ? "Logging out…" : "Log out"}\n <LogOutIcon aria-hidden="true" />\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n\nfunction getInitials(name: string, email: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length >= 2) {\n return `${parts[0]?.[0] ?? ""}${parts.at(-1)?.[0] ?? ""}`.toUpperCase();\n }\n return (parts[0]?.[0] ?? email[0] ?? "?").toUpperCase();\n}\n';
48
48
  readonly "app/api/auth/[...all]/route.ts": 'import { toNextJsHandler } from "better-auth/next-js";\nimport { auth } from "@/lib/auth";\n\nexport const { GET, POST } = toNextJsHandler(auth);\n';
49
49
  readonly "app/layout.tsx": 'import type { Metadata } from "next";\nimport { Geist, Geist_Mono } from "next/font/google";\nimport type { ReactNode } from "react";\nimport { TooltipProvider } from "@/components/ui/tooltip";\nimport { cn } from "@/lib/utils";\nimport "./globals.css";\n\nconst sans = Geist({\n variable: "--font-sans",\n subsets: ["latin"],\n weight: "variable",\n display: "swap",\n});\n\nconst mono = Geist_Mono({\n variable: "--font-mono",\n subsets: ["latin"],\n weight: "variable",\n display: "swap",\n});\n\nexport const metadata: Metadata = {\n title: "__EVE_INIT_APP_NAME__",\n description: "A Next.js starter for eve agents with AI Elements.",\n};\n\n// The page and Eve routes validate the generated app\'s Better Auth session.\nexport default function RootLayout({ children }: { readonly children: ReactNode }) {\n return (\n <html className={cn(sans.variable, mono.variable)} lang="en">\n <body>\n <TooltipProvider>{children}</TooltipProvider>\n </body>\n </html>\n );\n}\n';
50
50
  readonly "app/page.tsx": 'import { AuthenticatedAgentChat } from "./_components/authenticated-agent-chat";\n\nexport default function Page() {\n return <AuthenticatedAgentChat />;\n}\n';
@@ -5907,14 +5907,14 @@ export function AccountControl({
5907
5907
  }
5908
5908
 
5909
5909
  return (
5910
- <div className="fixed top-3 right-3 z-10">
5910
+ <div className="fixed top-3 left-4 z-30 flex h-8 items-center">
5911
5911
  <DropdownMenu>
5912
5912
  <DropdownMenuTrigger asChild>
5913
5913
  <Button
5914
5914
  aria-label={\`Open account menu for \${name}\`}
5915
- className="size-9 cursor-pointer overflow-hidden rounded-full p-0"
5916
- size="icon"
5917
- variant="outline"
5915
+ className="relative size-7 cursor-pointer overflow-hidden rounded-full p-0"
5916
+ size="icon-sm"
5917
+ variant="ghost"
5918
5918
  >
5919
5919
  {image && !imageFailed ? (
5920
5920
  <img
@@ -5928,9 +5928,13 @@ export function AccountControl({
5928
5928
  {initials}
5929
5929
  </span>
5930
5930
  )}
5931
+ <span
5932
+ aria-hidden="true"
5933
+ className="pointer-events-none absolute inset-0 rounded-full border border-black/20 dark:border-white/25"
5934
+ />
5931
5935
  </Button>
5932
5936
  </DropdownMenuTrigger>
5933
- <DropdownMenuContent align="end" className="w-64">
5937
+ <DropdownMenuContent align="start" className="w-64">
5934
5938
  <div className="min-w-0 px-2 py-1.5 text-sm">
5935
5939
  <span className="block truncate font-medium leading-5" title={name}>
5936
5940
  {name}
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-kmlFdOBB.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-DkUB0Ok4.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-kmlFdOBB.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-DkUB0Ok4.js";
2
2
 
3
3
  export { useEveAgent };
@@ -7,7 +7,5 @@ export declare function createAgentApprovalInstrumentation(input: {
7
7
  readonly actionContextFor: (sessionId: string, turnId: string, callId: string) => Promise<AgentActionContext | undefined>;
8
8
  readonly frameworkVersion: string;
9
9
  readonly idGenerator: AgentSpanIdGenerator;
10
- readonly recordInputs: boolean;
11
- readonly recordOutputs: boolean;
12
10
  readonly tracer: Tracer;
13
11
  }): Pick<NonNullable<InstrumentationProviderDefinition["events"]>, "input.requested" | "input.resolved">;
@@ -1 +1 @@
1
- import{normalizeChannelAudience}from"#shared/channel-audience.js";import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{contentAttribute}from"#tracing/agent-otel-content.js";function createAgentApprovalInstrumentation(n){return{"input.requested":async(t,r)=>{if(t.kind!==`tool-approval`||readState(r.state.get())!==void 0)return;let a=await n.actionContextFor(t.scope.sessionId,t.scope.turnId,t.action.callId);if(a===void 0)return;let o={actionCallId:t.action.callId,actionName:t.action.name,attemptIndex:t.scope.attemptIndex,channelAudience:normalizeChannelAudience(t.scope.channelAudience),parent:{spanId:a.spanContext.spanId,traceFlags:a.spanContext.traceFlags,traceId:a.spanContext.traceId},requestId:t.requestId,rootSessionId:t.scope.rootSessionId??t.scope.sessionId,sessionId:t.scope.sessionId,startTimeMs:Date.now(),stepIndex:t.scope.stepIndex,turnId:t.scope.turnId},s=n.recordInputs?contentAttribute(t.request,!1):void 0;s!==void 0&&(o.requestAttribute=s),r.state.set(o)},"input.resolved":(e,a)=>{let o=readState(a.state.get());if(o===void 0)return;let s=n.idGenerator.withSpanId(n.idGenerator.deriveSpanId(`approval:${e.idempotencyKey}`),()=>n.tracer.startSpan(`agent.approval`,{attributes:{"agent.action.call_id":o.actionCallId,"agent.action.name":o.actionName,"agent.approval.kind":`tool-approval`,"agent.approval.outcome":e.outcome,"agent.approval.request_id":o.requestId,"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.session.id":o.sessionId,"agent.step.attempt":o.attemptIndex,"agent.step.index":o.stepIndex,"agent.turn.id":o.turnId},startTime:o.startTimeMs},trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext({...o.parent,isRemote:!1}))));if(o.requestAttribute!==void 0&&s.setAttribute(`agent.approval.request`,o.requestAttribute),n.recordOutputs&&e.response!==void 0){let t=contentAttribute(e.response,!1);t!==void 0&&s.setAttribute(`agent.approval.response`,t)}e.outcome===`failed`&&recordError(s,e.error),s.end()}}}function readState(t){if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t,r=n.parent;if(typeof r!=`object`||!r||Array.isArray(r))return;let i=r;if(typeof n.actionCallId!=`string`||typeof n.actionName!=`string`||typeof n.attemptIndex!=`number`||typeof i.spanId!=`string`||typeof i.traceFlags!=`number`||typeof i.traceId!=`string`||typeof n.requestId!=`string`||typeof n.rootSessionId!=`string`||typeof n.sessionId!=`string`||typeof n.startTimeMs!=`number`||typeof n.stepIndex!=`number`||typeof n.turnId!=`string`)return;let a=n.requestAttribute;if(!(a!==void 0&&typeof a!=`string`))return{actionCallId:n.actionCallId,actionName:n.actionName,attemptIndex:n.attemptIndex,channelAudience:normalizeChannelAudience(n.channelAudience),parent:{isRemote:!1,spanId:i.spanId,traceFlags:i.traceFlags,traceId:i.traceId},requestAttribute:a,requestId:n.requestId,rootSessionId:n.rootSessionId,sessionId:n.sessionId,startTimeMs:n.startTimeMs,stepIndex:n.stepIndex,turnId:n.turnId}}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentApprovalInstrumentation};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{contentAttribute}from"#tracing/agent-otel-content.js";function createAgentApprovalInstrumentation(n){return{"input.requested":async(t,r)=>{if(t.kind!==`tool-approval`||readState(r.state.get())!==void 0)return;let a=await n.actionContextFor(t.scope.sessionId,t.scope.turnId,t.action.callId);if(a===void 0)return;let o={actionCallId:t.action.callId,actionName:t.action.name,attemptIndex:t.scope.attemptIndex,channelAudience:normalizeChannelAudience(t.scope.channelAudience),parent:{spanId:a.spanContext.spanId,traceFlags:a.spanContext.traceFlags,traceId:a.spanContext.traceId},requestId:t.requestId,rootSessionId:t.scope.rootSessionId??t.scope.sessionId,sessionId:t.scope.sessionId,startTimeMs:Date.now(),stepIndex:t.scope.stepIndex,turnId:t.scope.turnId},s=contentAttribute(t.request,!1);s!==void 0&&(o.requestAttribute=s),r.state.set(o)},"input.resolved":(e,a)=>{let o=readState(a.state.get());if(o===void 0)return;let s=n.idGenerator.withSpanId(n.idGenerator.deriveSpanId(`approval:${e.idempotencyKey}`),()=>n.tracer.startSpan(`agent.approval`,{attributes:{"agent.action.call_id":o.actionCallId,"agent.action.name":o.actionName,"agent.approval.kind":`tool-approval`,"agent.approval.outcome":e.outcome,"agent.approval.request_id":o.requestId,"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.session.id":o.sessionId,"agent.step.attempt":o.attemptIndex,"agent.step.index":o.stepIndex,"agent.turn.id":o.turnId},startTime:o.startTimeMs},trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext({...o.parent,isRemote:!1}))));if(o.requestAttribute!==void 0&&s.setAttribute(`agent.approval.request`,o.requestAttribute),e.response!==void 0){let t=contentAttribute(e.response,!1);t!==void 0&&s.setAttribute(`agent.approval.response`,t)}e.outcome===`failed`&&recordError(s,e.error),s.end()}}}function readState(t){if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t,r=n.parent;if(typeof r!=`object`||!r||Array.isArray(r))return;let i=r;if(typeof n.actionCallId!=`string`||typeof n.actionName!=`string`||typeof n.attemptIndex!=`number`||typeof i.spanId!=`string`||typeof i.traceFlags!=`number`||typeof i.traceId!=`string`||typeof n.requestId!=`string`||typeof n.rootSessionId!=`string`||typeof n.sessionId!=`string`||typeof n.startTimeMs!=`number`||typeof n.stepIndex!=`number`||typeof n.turnId!=`string`)return;let a=n.requestAttribute;if(!(a!==void 0&&typeof a!=`string`))return{actionCallId:n.actionCallId,actionName:n.actionName,attemptIndex:n.attemptIndex,channelAudience:normalizeChannelAudience(n.channelAudience),parent:{isRemote:!1,spanId:i.spanId,traceFlags:i.traceFlags,traceId:i.traceId},requestAttribute:a,requestId:n.requestId,rootSessionId:n.rootSessionId,sessionId:n.sessionId,startTimeMs:n.startTimeMs,stepIndex:n.stepIndex,turnId:n.turnId}}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentApprovalInstrumentation};
@@ -2,7 +2,7 @@ import { type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
2
  import type { AgentTraceStateStore } from "#tracing/agent-trace-state.js";
3
3
  import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
4
4
  import type { TraceCapturePolicy } from "#tracing/otel-declaration.js";
5
- import type { InstrumentationContextRunner, InstrumentationProviderDefinition, InstrumentationSessionStartedEvent, InstrumentationTraceContext, InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.js";
5
+ import type { InstrumentationContextRunner, InstrumentationProviderDefinition, InstrumentationSessionStartedEvent, InstrumentationTraceSeed, InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.js";
6
6
  export interface AgentOtelInstrumentationInput {
7
7
  /**
8
8
  * Whether to write model prompts and tool call inputs onto spans at all.
@@ -21,8 +21,8 @@ export interface AgentOtelInstrumentationInput {
21
21
  /** OTel event definition and its trusted framework context runner. */
22
22
  export interface AgentOtelInstrumentation {
23
23
  readonly hook: InstrumentationProviderDefinition;
24
- readonly prepareSessionTrace: (event: InstrumentationSessionStartedEvent) => Promise<InstrumentationTraceContext>;
25
- readonly prepareTurnTrace: (event: InstrumentationTurnStartedEvent) => Promise<InstrumentationTraceContext>;
24
+ readonly prepareSessionTrace: (event: InstrumentationSessionStartedEvent) => Promise<InstrumentationTraceSeed>;
25
+ readonly prepareTurnTrace: (event: InstrumentationTurnStartedEvent) => Promise<InstrumentationTraceSeed>;
26
26
  readonly runInContext: InstrumentationContextRunner;
27
27
  }
28
28
  /** Creates OTel instrumentation for eve's structural `agent.*` convention. */
@@ -1,2 +1,2 @@
1
- import{isSampledTrace}from"#tracing/sampled-trace.js";import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{attemptIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";import{createAgentActionInstrumentation}from"#tracing/agent-action-instrumentation.js";import{createAgentApprovalInstrumentation}from"#tracing/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/agent-channel-delivery-instrumentation.js";import{createAgentToolInstrumentation}from"#tracing/agent-tool-instrumentation.js";import{createAgentOtelSessionContext}from"#tracing/agent-otel-session-context.js";import{suppressTracing}from"#tracing/suppress-tracing.js";function createAgentOtelInstrumentation(t){let n=t.recordInputs??!1,p=t.recordOutputs??!1,m=new WeakMap,h=new Map,g=new WeakMap,_=new WeakMap,v=createAgentActionInstrumentation({frameworkVersion:t.frameworkVersion,idGenerator:t.idGenerator,recordInputs:n,recordOutputs:p,resolveTraceContext:async e=>(await t.stateStore.getTurn(e.scope.sessionId,e.scope.turnId))?.context,stateStore:t.stateStore,tracer:t.tracer}),y=createAgentApprovalInstrumentation({actionContextFor:v.contextFor,frameworkVersion:t.frameworkVersion,idGenerator:t.idGenerator,recordInputs:n,recordOutputs:p,tracer:t.tracer}),b=createAgentToolInstrumentation({actionContextFor:v.contextFor,idGenerator:t.idGenerator,recordInputs:n,recordOutputs:p,resolveFallback:e=>{let t=h.get(e.scope.attemptId)??e.scope,n=g.get(t)?.step;return n===void 0?void 0:{context:n.context,spanContext:n.span.spanContext()}},tracer:t.tracer}),{ensureSessionContext:x,prepareSessionTrace:S,prepareTurnTrace:C}=createAgentOtelSessionContext(t),onSessionStarted=async e=>{await S(e)},onTurnStarted=async e=>{await C(e)},onStepStarted=async n=>{let o=await t.stateStore.getTurn(n.scope.sessionId,n.scope.turnId);if(o===void 0||!isSampledTrace(o.context))return;let s=withChannelAudience(contextFromSpanContext(o.context),n.scope.channelAudience),c=trace.getSpan(context.active())?.spanContext(),l=t.idGenerator.withSpanId(t.idGenerator.deriveSpanId(attemptIdempotencyKey(n.scope)),()=>t.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":n.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":t.frameworkVersion,"agent.step.attempt":n.scope.attemptIndex,"agent.step.index":n.scope.stepIndex,"agent.turn.id":n.scope.turnId,"agent.name":n.scope.functionId,...runtimeContextAttributes(n.runtimeContext)},links:c===void 0||c.traceId===o.context.traceId?void 0:[{attributes:{"eve.link.type":`workflow.delivery`},context:c}]},s));l.addEvent(`step.started`);let u=trace.setSpan(s,l),d=n.operation.operationId,f=t.tracer.startSpan(d,{attributes:{"ai.operation.name":d,"ai.provider.name":n.operation.provider,"ai.request.model":n.operation.modelId,...runtimeContextAttributes(n.runtimeContext)}},u);g.set(n.scope,{operation:{context:trace.setSpan(u,f),name:d,span:f},step:{context:u,span:l}}),h.set(n.scope.attemptId,n.scope)},onStepTerminal=async e=>{let t=h.get(e.scope.attemptId)??e.scope;m.delete(t),drainOpenSpans({...e,scope:t}),b.drain(e.scope.attemptId,e.type===`step.attempt.failed`?{error:e.error}:void 0),e.type===`step.attempt.failed`&&await v.failForAttempt(t,e.error),h.delete(e.scope.attemptId);let n=g.get(t);n!==void 0&&(n.step.span.addEvent(e.type===`step.attempt.completed`?`step.completed`:`step.failed`),e.type===`step.attempt.failed`&&(recordError(n.operation.span,e.error),recordError(n.step.span,e.error)),n.operation.span.end(),n.step.span.end(),g.delete(t))},onTurnTerminal=async e=>{(e.type===`turn.cancelled`||e.type===`turn.failed`)&&await v.deleteForTurn(e.sessionId,e.turnId);let n=await t.stateStore.getTurn(e.sessionId,e.turnId);n!==void 0&&await t.stateStore.setTurn(e.sessionId,e.turnId,{...n,terminal:e.type===`turn.failed`?{error:e.error,type:e.type}:{type:e.type}})},onSessionTransition=async n=>{if(n.turnId!==void 0){let r=await t.stateStore.getTurn(n.sessionId,n.turnId);if(r!==void 0){let i=await t.stateStore.getSession(n.sessionId);if(isSampledTrace(r.context)){let e=t.idGenerator.withSpanId(r.context.spanId,()=>t.tracer.startSpan(`agent.turn`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":t.frameworkVersion,"agent.name":i?.agentName,"agent.session.id":n.sessionId,"agent.subagent.name":r.subagentName,"agent.turn.id":n.turnId,"agent.turn.sequence":r.sequence},startTime:r.startTimeMs},contextFromSpanContext({isRemote:r.parentIsRemote??!1,spanId:r.parentSpanId,traceFlags:r.context.traceFlags,traceId:r.context.traceId})));e.addEvent(`turn.started`,void 0,r.startTimeMs),r.terminal!==void 0&&(e.addEvent(r.terminal.type),r.terminal.type===`turn.failed`&&recordError(e,r.terminal.error)),e.end()}await t.stateStore.deleteTurn(n.sessionId,n.turnId)}}(n.type===`session.completed`||n.type===`session.failed`)&&(await v.deleteForSession(n.sessionId),await t.stateStore.deleteSession(n.sessionId))},onModelCallStarted=e=>{let r=g.get(e.scope);if(r===void 0)return;r.step.span.setAttribute(`agent.model.id`,e.model.modelId),r.step.span.setAttribute(`agent.model.provider`,e.model.provider);let a=t.tracer.startSpan(modelSpanName(e.model.modelId),{attributes:{"gen_ai.agent.name":e.scope.functionId,"gen_ai.operation.name":`chat`,"gen_ai.provider.name":e.model.provider,"gen_ai.request.model":e.model.modelId,...runtimeContextAttributes(e.runtimeContext)}},r.operation.context);if(n&&e.input!==void 0){let t=messagesContentAttribute(e.input.messages);t!==void 0&&a.setAttribute(`ai.prompt.messages`,t);let n=genAiInputMessagesAttribute(e.input.messages);n!==void 0&&a.setAttribute(`gen_ai.input.messages`,n);let r=systemPromptAttribute(e.input.instructions);r!==void 0&&a.setAttribute(`ai.prompt.system`,r);let i=genAiSystemInstructionsAttribute(e.input.instructions);i!==void 0&&a.setAttribute(`gen_ai.system_instructions`,i)}let o={context:trace.setSpan(r.operation.context,a),span:a};getExecutionContexts(e.scope).set(e.idempotencyKey,o.context),getSpanStates(_,e.scope).set(e.idempotencyKey,o)},onModelCallTerminal=e=>{m.get(e.scope)?.delete(e.idempotencyKey);let t=takeSpanState(_,e.scope,e.idempotencyKey);if(t!==void 0){if(e.type===`model.call.failed`)recordError(t.span,e.error);else{setAgentUsage(t.span,e.usage),t.span.setAttribute(`gen_ai.response.finish_reasons`,[e.finishReason]);let n=g.get(e.scope);if(n!==void 0&&setAgentUsage(n.step.span,e.usage),p){t.span.setAttribute(`ai.response.finish_reason`,e.finishReason);let n=e.content??[],r=genAiOutputMessagesAttribute(n,e.finishReason);r!==void 0&&t.span.setAttribute(`gen_ai.output.messages`,r);let i=textContentAttribute(n.filter(e=>e.type===`reasoning`).map(e=>e.text).filter(e=>e.trim().length>0).join(`
2
- `));i!==void 0&&t.span.setAttribute(`ai.response.reasoning`,i);let a=textContentAttribute(n.filter(e=>e.type===`text`).map(e=>e.text).join(``));a!==void 0&&t.span.setAttribute(`ai.response.text`,a);let s=n.filter(e=>e.type===`tool-call`).map(e=>({callId:e.callId,input:e.input,toolName:e.toolName}));if(s.length>0){let e=contentAttribute(s,!1);e!==void 0&&t.span.setAttribute(`ai.response.tool_calls`,e)}let l=n.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{callId:e.callId,input:e.input,output:e.output,toolName:e.toolName}:{callId:e.callId,error:errorText(e.error),input:e.input,toolName:e.toolName});if(l.length>0){let e=toolResultsContentAttribute(l);e!==void 0&&t.span.setAttribute(`ai.response.tool_results`,e)}}}t.span.end()}},w=createAgentChannelDeliveryInstrumentation({ensureSessionContext:x,frameworkVersion:t.frameworkVersion,idGenerator:t.idGenerator,recordInputs:n,stateStore:t.stateStore,tracer:t.tracer}),onStepMetadata=e=>{let t=g.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.step.span.setAttribute(e,r)};return{hook:{capture:n||p?`content`:`metadata`,events:{...w,"action.completed":v.events[`action.completed`],"action.failed":v.events[`action.failed`],async"action.started"(e,t){await v.events[`action.started`](e,t),await b.actionStarted(e)},...y,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...b.events,"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted},name:`eve.otel`},prepareSessionTrace:S,prepareTurnTrace:C,async runInContext(n,i){let a=h.get(n.scope.attemptId)??n.scope,o=m.get(a),s=n.type===`model.call`?o?.get(n.idempotencyKey):b.contextFor(n.scope.attemptId,n.idempotencyKey);if(s===void 0){let r=await t.stateStore.getTurn(n.scope.sessionId,n.scope.turnId);r!==void 0&&(s=withChannelAudience(contextFromSpanContext(r.context),n.scope.channelAudience),isSampledTrace(r.context)||(s=suppressTracing(s)))}return s===void 0?i():context.with(s,i)}};function getExecutionContexts(e){let t=m.get(e);return t===void 0&&(t=new Map,m.set(e,t)),t}function drainOpenSpans(e){for(let t of _.get(e.scope)?.values()??[])e.type===`step.attempt.failed`&&recordError(t.span,e.error),t.span.end();_.delete(e.scope)}}function getSpanStates(e,t){let n=e.get(t);return n===void 0&&(n=new Map,e.set(t,n)),n}function takeSpanState(e,t,n){let r=e.get(t),i=r?.get(n);if(r!==void 0)return r.delete(n),r.size===0&&e.delete(t),i}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function readGatewayCost(e){let t=e.gateway;if(!isRecord(t))return;let n={},r=readUsd(t.cost);r!==void 0&&(n[`gen_ai.usage.cost`]=r);let i=readUsd(t.gatewayCost);i!==void 0&&(n[`gen_ai.usage.gateway_cost`]=i);let a=readUsd(t.inputInferenceCost);a!==void 0&&(n[`gen_ai.usage.input_cost`]=a);let o=readUsd(t.outputInferenceCost);return o!==void 0&&(n[`gen_ai.usage.output_cost`]=o),typeof t.generationId==`string`&&t.generationId.length>0&&(n[`gen_ai.generation.id`]=t.generationId),Object.keys(n).length===0?void 0:n}function readUsd(e){if(typeof e!=`string`)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function modelSpanName(e){return`chat ${e}`}function runtimeContextAttributes(e){let t={};if(e===void 0)return t;for(let[n,r]of Object.entries(e))flattenContextAttribute(t,`ai.settings.context.${n}`,r);return t}function flattenContextAttribute(e,t,n){if(n!=null){if(typeof n==`string`||typeof n==`number`||typeof n==`boolean`){e[t]=n;return}if(Array.isArray(n)){let r=n.filter(e=>typeof e==`string`||typeof e==`number`||typeof e==`boolean`);if(r.length!==n.length||new Set(r.map(e=>typeof e)).size!==1)return;e[t]=r;return}if(typeof n==`object`)for(let[r,i]of Object.entries(n))flattenContextAttribute(e,`${t}.${r}`,i)}}function errorText(e){return e instanceof Error?e.message:e}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentOtelInstrumentation};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{isSampledTrace,resolveTracePolicyDecision}from"#tracing/sampled-trace.js";import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{attemptIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{withoutInstrumentationContent}from"#harness/instrumentation/content.js";import{contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";import{instrumentationEventForTraceDecision}from"#harness/instrumentation/content-policy.js";import{createAgentActionInstrumentation}from"#tracing/agent-action-instrumentation.js";import{createAgentApprovalInstrumentation}from"#tracing/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/agent-channel-delivery-instrumentation.js";import{createAgentToolInstrumentation}from"#tracing/agent-tool-instrumentation.js";import{createAgentOtelSessionContext}from"#tracing/agent-otel-session-context.js";import{suppressTracing}from"#tracing/suppress-tracing.js";function createAgentOtelInstrumentation(e){let a=e.recordInputs??!1,o=e.recordOutputs??!1,m=new WeakMap,h=new Map,g=new WeakMap,_=new WeakMap,v=createAgentActionInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:a,recordOutputs:o,resolveTraceContext:async t=>(await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId))?.context,stateStore:e.stateStore,tracer:e.tracer}),y=createAgentApprovalInstrumentation({actionContextFor:v.contextFor,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,tracer:e.tracer}),b=createAgentToolInstrumentation({actionContextFor:v.contextFor,idGenerator:e.idGenerator,recordInputs:a,recordOutputs:o,resolveFallback:e=>{let t=h.get(e.scope.attemptId)??e.scope,n=g.get(t)?.step;return n===void 0?void 0:{context:n.context,spanContext:n.span.spanContext()}},tracer:e.tracer}),{ensureSessionContext:x,prepareSessionTrace:S,prepareTurnTrace:C}=createAgentOtelSessionContext(e),projectEvent=async s=>{let c=await e.stateStore.getSession(sessionIdForEvent(s)),l=audienceForEvent(s,c?.channelAudience),d=`traceSeed`in s?s.traceSeed:void 0,f=contextStorage.getStore()?.get(SessionTraceSeedKey),p=d?.decision??f?.decision??c?.decision??(d===void 0?f===void 0?c===void 0?void 0:resolveTracePolicyDecision(isSampledTrace(c.context),l):resolveTracePolicyDecision(isSampledTrace(f),l):resolveTracePolicyDecision(isSampledTrace(d),l));return p===void 0?withoutInstrumentationContent(s):instrumentationEventForTraceDecision(s,p.action===`drop`?p:{action:`record`,recordInputs:a&&p.recordInputs,recordOutputs:o&&p.recordOutputs},l)},onSessionStarted=async e=>{await S(e)},onTurnStarted=async e=>{await C(e)},onStepStarted=async t=>{let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(n===void 0||!isSampledTrace(n.context))return;let i=withChannelAudience(contextFromSpanContext(n.context),t.scope.channelAudience),a=trace.getSpan(context.active())?.spanContext(),o=e.idGenerator.withSpanId(e.idGenerator.deriveSpanId(attemptIdempotencyKey(t.scope)),()=>e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId,...runtimeContextAttributes(t.runtimeContext)},links:a===void 0||a.traceId===n.context.traceId?void 0:[{attributes:{"eve.link.type":`workflow.delivery`},context:a}]},i));o.addEvent(`step.started`);let u=trace.setSpan(i,o),d=t.operation.operationId,f=e.tracer.startSpan(d,{attributes:{"ai.operation.name":d,"ai.provider.name":t.operation.provider,"ai.request.model":t.operation.modelId,...runtimeContextAttributes(t.runtimeContext)}},u);g.set(t.scope,{operation:{context:trace.setSpan(u,f),name:d,span:f},step:{context:u,span:o}}),h.set(t.scope.attemptId,t.scope)},onStepTerminal=async e=>{let t=h.get(e.scope.attemptId)??e.scope;m.delete(t),drainOpenSpans({...e,scope:t}),b.drain(e.scope.attemptId,e.type===`step.attempt.failed`?{error:e.error}:void 0),e.type===`step.attempt.failed`&&await v.failForAttempt(t,e.error),h.delete(e.scope.attemptId);let n=g.get(t);n!==void 0&&(n.step.span.addEvent(e.type===`step.attempt.completed`?`step.completed`:`step.failed`),e.type===`step.attempt.failed`&&(recordError(n.operation.span,e.error),recordError(n.step.span,e.error)),n.operation.span.end(),n.step.span.end(),g.delete(t))},onTurnTerminal=async t=>{(t.type===`turn.cancelled`||t.type===`turn.failed`)&&await v.deleteForTurn(t.sessionId,t.turnId);let n=await e.stateStore.getTurn(t.sessionId,t.turnId);n!==void 0&&await e.stateStore.setTurn(t.sessionId,t.turnId,{...n,terminal:t.type===`turn.failed`?{error:t.error,type:t.type}:{type:t.type}})},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let i=await e.stateStore.getSession(t.sessionId);if(isSampledTrace(n.context)){let r=e.idGenerator.withSpanId(n.context.spanId,()=>e.tracer.startSpan(`agent.turn`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":i?.agentName,"agent.session.id":t.sessionId,"agent.subagent.name":n.subagentName,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence},startTime:n.startTimeMs},contextFromSpanContext({isRemote:n.parentIsRemote??!1,spanId:n.parentSpanId,traceFlags:n.context.traceFlags,traceId:n.context.traceId})));r.addEvent(`turn.started`,void 0,n.startTimeMs),n.terminal!==void 0&&(r.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(r,n.terminal.error)),r.end()}await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&(await v.deleteForSession(t.sessionId),await e.stateStore.deleteSession(t.sessionId))},onModelCallStarted=t=>{let n=g.get(t.scope);if(n===void 0)return;n.step.span.setAttribute(`agent.model.id`,t.model.modelId),n.step.span.setAttribute(`agent.model.provider`,t.model.provider);let r=e.tracer.startSpan(modelSpanName(t.model.modelId),{attributes:{"gen_ai.agent.name":t.scope.functionId,"gen_ai.operation.name":`chat`,"gen_ai.provider.name":t.model.provider,"gen_ai.request.model":t.model.modelId,...runtimeContextAttributes(t.runtimeContext)}},n.operation.context);if(a&&t.input!==void 0){let e=messagesContentAttribute(t.input.messages);e!==void 0&&r.setAttribute(`ai.prompt.messages`,e);let n=genAiInputMessagesAttribute(t.input.messages);n!==void 0&&r.setAttribute(`gen_ai.input.messages`,n);let i=systemPromptAttribute(t.input.instructions);i!==void 0&&r.setAttribute(`ai.prompt.system`,i);let a=genAiSystemInstructionsAttribute(t.input.instructions);a!==void 0&&r.setAttribute(`gen_ai.system_instructions`,a)}let i={context:trace.setSpan(n.operation.context,r),span:r};getExecutionContexts(t.scope).set(t.idempotencyKey,i.context),getSpanStates(_,t.scope).set(t.idempotencyKey,i)},onModelCallTerminal=e=>{m.get(e.scope)?.delete(e.idempotencyKey);let t=takeSpanState(_,e.scope,e.idempotencyKey);if(t!==void 0){if(e.type===`model.call.failed`)recordError(t.span,e.error);else{setAgentUsage(t.span,e.usage),t.span.setAttribute(`gen_ai.response.finish_reasons`,[e.finishReason]);let n=g.get(e.scope);if(n!==void 0&&setAgentUsage(n.step.span,e.usage),o){t.span.setAttribute(`ai.response.finish_reason`,e.finishReason);let n=e.content;if(n===void 0){t.span.end();return}let r=genAiOutputMessagesAttribute(n,e.finishReason);r!==void 0&&t.span.setAttribute(`gen_ai.output.messages`,r);let i=textContentAttribute(n.filter(e=>e.type===`reasoning`).map(e=>e.text).filter(e=>e.trim().length>0).join(`
2
+ `));i!==void 0&&t.span.setAttribute(`ai.response.reasoning`,i);let a=textContentAttribute(n.filter(e=>e.type===`text`).map(e=>e.text).join(``));a!==void 0&&t.span.setAttribute(`ai.response.text`,a);let o=n.filter(e=>e.type===`tool-call`).map(e=>({callId:e.callId,input:e.input,toolName:e.toolName}));if(o.length>0){let e=contentAttribute(o,!1);e!==void 0&&t.span.setAttribute(`ai.response.tool_calls`,e)}let s=n.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{callId:e.callId,input:e.input,output:e.output,toolName:e.toolName}:{callId:e.callId,error:errorText(e.error),input:e.input,toolName:e.toolName});if(s.length>0){let e=toolResultsContentAttribute(s);e!==void 0&&t.span.setAttribute(`ai.response.tool_results`,e)}}}t.span.end()}},w=createAgentChannelDeliveryInstrumentation({ensureSessionContext:x,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:a,stateStore:e.stateStore,tracer:e.tracer}),onStepMetadata=e=>{let t=g.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.step.span.setAttribute(e,r)};return{hook:{capture:a||o?`content`:`metadata`,events:{...w,"action.completed":v.events[`action.completed`],"action.failed":v.events[`action.failed`],async"action.started"(e,t){await v.events[`action.started`](e,t),await b.actionStarted(e)},...y,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...b.events,"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted},name:`eve.otel`,projectEvent},prepareSessionTrace:S,prepareTurnTrace:C,async runInContext(t,n){let i=h.get(t.scope.attemptId)??t.scope,a=m.get(i),o=t.type===`model.call`?a?.get(t.idempotencyKey):b.contextFor(t.scope.attemptId,t.idempotencyKey);if(o===void 0){let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);n!==void 0&&(o=withChannelAudience(contextFromSpanContext(n.context),t.scope.channelAudience),isSampledTrace(n.context)||(o=suppressTracing(o)))}return o===void 0?n():context.with(o,n)}};function getExecutionContexts(e){let t=m.get(e);return t===void 0&&(t=new Map,m.set(e,t)),t}function drainOpenSpans(e){for(let t of _.get(e.scope)?.values()??[])e.type===`step.attempt.failed`&&recordError(t.span,e.error),t.span.end();_.delete(e.scope)}}function sessionIdForEvent(e){return`scope`in e?e.scope.sessionId:e.sessionId}function audienceForEvent(t,n){return`delivery`in t?normalizeChannelAudience(t.delivery.channelAudience):`scope`in t&&t.scope.channelAudience!==void 0?normalizeChannelAudience(t.scope.channelAudience):t.type===`session.started`?normalizeChannelAudience(t.channelAudience):normalizeChannelAudience(n)}function getSpanStates(e,t){let n=e.get(t);return n===void 0&&(n=new Map,e.set(t,n)),n}function takeSpanState(e,t,n){let r=e.get(t),i=r?.get(n);if(r!==void 0)return r.delete(n),r.size===0&&e.delete(t),i}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function readGatewayCost(e){let t=e.gateway;if(!isRecord(t))return;let n={},r=readUsd(t.cost);r!==void 0&&(n[`gen_ai.usage.cost`]=r);let i=readUsd(t.gatewayCost);i!==void 0&&(n[`gen_ai.usage.gateway_cost`]=i);let a=readUsd(t.inputInferenceCost);a!==void 0&&(n[`gen_ai.usage.input_cost`]=a);let o=readUsd(t.outputInferenceCost);return o!==void 0&&(n[`gen_ai.usage.output_cost`]=o),typeof t.generationId==`string`&&t.generationId.length>0&&(n[`gen_ai.generation.id`]=t.generationId),Object.keys(n).length===0?void 0:n}function readUsd(e){if(typeof e!=`string`)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function modelSpanName(e){return`chat ${e}`}function runtimeContextAttributes(e){let t={};if(e===void 0)return t;for(let[n,r]of Object.entries(e))flattenContextAttribute(t,`ai.settings.context.${n}`,r);return t}function flattenContextAttribute(e,t,n){if(n!=null){if(typeof n==`string`||typeof n==`number`||typeof n==`boolean`){e[t]=n;return}if(Array.isArray(n)){let r=n.filter(e=>typeof e==`string`||typeof e==`number`||typeof e==`boolean`);if(r.length!==n.length||new Set(r.map(e=>typeof e)).size!==1)return;e[t]=r;return}if(typeof n==`object`)for(let[r,i]of Object.entries(n))flattenContextAttribute(e,`${t}.${r}`,i)}}function errorText(e){return e instanceof Error?e.message:e}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentOtelInstrumentation};
@@ -1,5 +1,5 @@
1
1
  import type { Tracer } from "#compiled/@opentelemetry/api/index.js";
2
- import { type InstrumentationSessionStartedEvent, type InstrumentationTraceContext, type InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.js";
2
+ import { type InstrumentationSessionStartedEvent, type InstrumentationTraceSeed, type InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.js";
3
3
  import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
4
4
  import type { TraceCapturePolicy } from "#tracing/otel-declaration.js";
5
5
  import type { AgentSessionTraceState, AgentTraceStateStore } from "#tracing/agent-trace-state.js";
@@ -12,8 +12,8 @@ interface AgentOtelSessionContextInput {
12
12
  }
13
13
  interface AgentOtelSessionContext {
14
14
  readonly ensureSessionContext: (event: InstrumentationSessionStartedEvent) => Promise<AgentSessionTraceState>;
15
- readonly prepareSessionTrace: (event: InstrumentationSessionStartedEvent) => Promise<InstrumentationTraceContext>;
16
- readonly prepareTurnTrace: (event: InstrumentationTurnStartedEvent) => Promise<InstrumentationTraceContext>;
15
+ readonly prepareSessionTrace: (event: InstrumentationSessionStartedEvent) => Promise<InstrumentationTraceSeed>;
16
+ readonly prepareTurnTrace: (event: InstrumentationTurnStartedEvent) => Promise<InstrumentationTraceSeed>;
17
17
  }
18
18
  export declare function createAgentOtelSessionContext(input: AgentOtelSessionContextInput): AgentOtelSessionContext;
19
19
  export {};
@@ -1 +1 @@
1
- import{normalizeChannelAudience}from"#shared/channel-audience.js";import{evaluateTracePolicy,isSampledTrace}from"#tracing/sampled-trace.js";import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";function createAgentOtelSessionContext(i){let openSessionTrace=e=>{if(e.traceSeed!==void 0){if(!isSampledTrace(e.traceSeed))return{isRemote:!1,spanId:e.traceSeed.spanId,traceFlags:0,traceId:e.traceSeed.traceId};let startSpan=()=>i.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":i.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":2},root:!0}),t=i.idGenerator.withSpanId(e.traceSeed.spanId,()=>i.idGenerator.withTraceId(e.traceSeed.traceId,startSpan));return t.addEvent(`session.started`),t.end(),t.spanContext()}if(!evaluateTracePolicy(i.tracePolicy,{agentName:e.agentName,audience:e.channelAudience,channelType:e.channelType}))return{isRemote:!1,spanId:i.idGenerator.deriveSpanId(`session:${e.sessionId}`),traceFlags:0,traceId:i.idGenerator.generateTraceId()};let r=i.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":i.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":2},root:!0});return r.addEvent(`session.started`),r.end(),r.spanContext()},ensureSessionContext=async t=>{let n=await i.stateStore.getSession(t.sessionId);return n===void 0&&(n={agentName:t.agentName,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:t.channelKind,context:t.parentTraceContext===void 0?openSessionTrace({agentName:t.agentName,channelAudience:normalizeChannelAudience(t.channelAudience),channelType:t.channelType,rootSessionId:t.rootSessionId,sessionId:t.sessionId,traceSeed:t.traceSeed}):adoptedSpanContext(t.parentTraceContext),rootSessionId:t.rootSessionId},await i.stateStore.setSession(t.sessionId,n)),n};return{ensureSessionContext,prepareSessionTrace:async e=>portableSpanContext((await ensureSessionContext(e)).context),prepareTurnTrace:async e=>{let t=await i.stateStore.getTurn(e.sessionId,e.turnId);if(t!==void 0)return{spanId:t.parentSpanId,traceFlags:t.context.traceFlags,traceId:t.context.traceId};let n=await ensureSessionContext({agentName:void 0,channelAudience:`unknown`,channelKind:void 0,idempotencyKey:sessionIdempotencyKey(e.sessionId),parentTraceContext:e.parentTraceContext,rootSessionId:e.rootSessionId,sessionId:e.sessionId,type:`session.started`}),a={isRemote:!1,spanId:i.idGenerator.deriveSpanId(`turn:${e.idempotencyKey}`),traceFlags:n.context.traceFlags,traceId:n.context.traceId};return await i.stateStore.setTurn(e.sessionId,e.turnId,{context:a,parentIsRemote:n.context.isRemote,parentSpanId:n.context.spanId,rootSessionId:e.rootSessionId,sequence:e.sequence,startTimeMs:Date.now(),subagentName:e.parentLineage?.subagentName}),portableSpanContext(n.context)}}}function portableSpanContext(e){return{spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function adoptedSpanContext(e){return{isRemote:`isRemote`in e&&e.isRemote===!0,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}export{createAgentOtelSessionContext};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{isSampledTrace,resolveTracePolicy,resolveTracePolicyDecision}from"#tracing/sampled-trace.js";import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";function createAgentOtelSessionContext(n){let openSessionTrace=e=>{if(e.traceSeed!==void 0){if(!isSampledTrace(e.traceSeed))return{isRemote:!1,spanId:e.traceSeed.spanId,traceFlags:0,traceId:e.traceSeed.traceId};let startSpan=()=>n.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":2},root:!0}),r=n.idGenerator.withSpanId(e.traceSeed.spanId,()=>n.idGenerator.withTraceId(e.traceSeed.traceId,startSpan));return r.addEvent(`session.started`),r.end(),r.spanContext()}if(e.traceDecision.action===`drop`)return{isRemote:!1,spanId:n.idGenerator.deriveSpanId(`session:${e.sessionId}`),traceFlags:0,traceId:n.idGenerator.generateTraceId()};let r=n.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.session.id":e.sessionId,"agent.trace.schema.version":2},root:!0});return r.addEvent(`session.started`),r.end(),r.spanContext()},ensureSessionContext=async t=>{let r=await n.stateStore.getSession(t.sessionId);if(r===void 0){let i=normalizeChannelAudience(t.channelAudience),a=resolveSessionTraceDecision(t,i,n.tracePolicy);r={agentName:t.agentName,channelAudience:i,channelKind:t.channelKind,decision:a,context:t.parentTraceContext===void 0?openSessionTrace({agentName:t.agentName,channelAudience:i,channelType:t.channelType,rootSessionId:t.rootSessionId,sessionId:t.sessionId,traceDecision:a,traceSeed:t.traceSeed}):adoptedSpanContext(t.parentTraceContext),rootSessionId:t.rootSessionId},await n.stateStore.setSession(t.sessionId,r)}return r};return{ensureSessionContext,prepareSessionTrace:async e=>{let t=await ensureSessionContext(e);return portableSpanContext(t.context,t.decision)},prepareTurnTrace:async e=>{let t=await n.stateStore.getTurn(e.sessionId,e.turnId);if(t!==void 0)return{decision:(await n.stateStore.getSession(e.sessionId))?.decision,spanId:t.parentSpanId,traceFlags:t.context.traceFlags,traceId:t.context.traceId};let r=await ensureSessionContext({agentName:void 0,channelAudience:`unknown`,channelKind:void 0,idempotencyKey:sessionIdempotencyKey(e.sessionId),parentTraceContext:e.parentTraceContext,rootSessionId:e.rootSessionId,sessionId:e.sessionId,type:`session.started`}),a={isRemote:!1,spanId:n.idGenerator.deriveSpanId(`turn:${e.idempotencyKey}`),traceFlags:r.context.traceFlags,traceId:r.context.traceId};return await n.stateStore.setTurn(e.sessionId,e.turnId,{context:a,parentIsRemote:r.context.isRemote,parentSpanId:r.context.spanId,rootSessionId:e.rootSessionId,sequence:e.sequence,startTimeMs:Date.now(),subagentName:e.parentLineage?.subagentName}),portableSpanContext(r.context,r.decision)}}}function portableSpanContext(e,t){return{decision:t,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function adoptedSpanContext(e){return{isRemote:`isRemote`in e&&e.isRemote===!0,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function resolveSessionTraceDecision(e,i,a){return e.traceSeed?.decision===void 0?e.traceSeed===void 0?e.parentTraceContext===void 0?resolveTracePolicy(a,{agentName:e.agentName,audience:i,channelType:e.channelType}):resolveTracePolicyDecision(isSampledTrace(e.parentTraceContext),i):resolveTracePolicyDecision(isSampledTrace(e.traceSeed),i):e.traceSeed.decision}export{createAgentOtelSessionContext};
@@ -1,5 +1,8 @@
1
1
  import type { SessionTraceContext } from "#channel/types.js";
2
2
  import type { AgentActionTraceState, AgentSessionTraceState, AgentTraceStateStore, AgentTurnTraceState } from "#tracing/agent-trace-state.js";
3
+ import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
4
+ /** Reads the decision already bound to a session in the current worker context. */
5
+ export declare function readCurrentSessionTraceDecision(sessionId: string): InstrumentationDecision | undefined;
3
6
  /** Keeps only framework trace state from an interrupted step's context changes. */
4
7
  export declare function preserveSerializedAgentTraceState(original: Record<string, unknown>, interrupted: Record<string, unknown>): Record<string, unknown>;
5
8
  /**
@@ -1 +1 @@
1
- import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage,loadContext}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{ContextKey}from"#context/key.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n===void 0)return;let r=deserializeState(n).sessions[t]?.context;return r===void 0?void 0:withTraceDecision(e,r)}function readActionTraceContext(e,t,n,r){let i=e[AgentTraceContextKey.name];if(i===void 0)return;let a=Object.values(deserializeState(i).actions).find(e=>e.sessionId===t&&e.turnId===n&&e.callId===r);if(a!==void 0)return withTraceDecision(e,{isRemote:!1,spanId:a.spanId,traceFlags:a.parent.traceFlags,traceId:a.parent.traceId})}function withTraceDecision(e,t){let n=e[SessionTraceSeedKey.name];return n?.decision===void 0?t:{...t,decision:n.decision}}var ContextAgentTraceStateStore=class{deleteAction(e){updateState(t=>{let n={...t.actions};return delete n[e],{...t,actions:n}})}deleteActions(e,t){updateState(n=>{let r={...n.actions};for(let[n,i]of Object.entries(r))i.sessionId===e&&(t===void 0||i.turnId===t)&&delete r[n];return{...n,actions:r}})}deleteSession(e){updateState(t=>{let n={...t.sessions};return delete n[e],{...t,sessions:n}})}deleteTurn(e,t){updateState(n=>{let r={...n.turns};return delete r[turnKey(e,t)],{...n,turns:r}})}findAction(e,n){return Object.values(contextStorage.getStore()?.get(AgentTraceContextKey)?.actions??{}).find(t=>t.sessionId===e&&t.callId===n)}getAction(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.actions[e]}getSession(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[e]}getTurn(e,n){return contextStorage.getStore()?.get(AgentTraceContextKey)?.turns[turnKey(e,n)]}setAction(e,t){updateState(n=>({...n,actions:{...n.actions,[e]:t}}))}setSession(e,t){updateState(n=>({...n,sessions:{...n.sessions,[e]:t}}))}setTurn(e,t,n){updateState(r=>({...r,turns:{...r.turns,[turnKey(e,t)]:n}}))}};function updateState(e){loadContext().set(AgentTraceContextKey,t=>e(t??{actions:{},sessions:{},turns:{}}))}function turnKey(e,t){return`${e}\0${t}`}function serializeState(e){return{actions:e.actions,sessions:Object.fromEntries(Object.entries(e.sessions).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context)}])),turns:Object.fromEntries(Object.entries(e.turns).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context),terminal:t.terminal===void 0?void 0:t.terminal.type===`turn.failed`?{error:serializeError(t.terminal.error),type:t.terminal.type}:{type:t.terminal.type}}]))}}function deserializeState(t){return isRecord(t)?{actions:deserializeRecord(t.actions,deserializeAction),sessions:deserializeRecord(t.sessions,t=>{if(!(!isRecord(t)||!isSpanContext(t.context)))return{agentName:typeof t.agentName==`string`?t.agentName:void 0,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:typeof t.channelKind==`string`?t.channelKind:void 0,context:t.context,rootSessionId:typeof t.rootSessionId==`string`?t.rootSessionId:``}}),turns:deserializeRecord(t.turns,e=>{if(!(!isRecord(e)||!isSpanContext(e.context))&&!(typeof e.parentSpanId!=`string`||typeof e.startTimeMs!=`number`))return{context:e.context,parentIsRemote:typeof e.parentIsRemote==`boolean`?e.parentIsRemote:void 0,parentSpanId:e.parentSpanId,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,terminal:deserializeTerminal(e.terminal)}})}:{actions:{},sessions:{},turns:{}}}function deserializeAction(t){if(!(!isRecord(t)||typeof t.attemptIndex!=`number`||typeof t.callId!=`string`||!isActionKind(t.kind)||typeof t.name!=`string`||!isSpanContext(t.parent)||typeof t.rootSessionId!=`string`||typeof t.sessionId!=`string`||typeof t.spanId!=`string`||typeof t.startTimeMs!=`number`||typeof t.stepIndex!=`number`||typeof t.turnId!=`string`))return{attemptIndex:t.attemptIndex,callId:t.callId,channelAudience:normalizeChannelAudience(t.channelAudience),inputAttribute:typeof t.inputAttribute==`string`?t.inputAttribute:void 0,kind:t.kind,name:t.name,parent:t.parent,rootSessionId:t.rootSessionId,sessionId:t.sessionId,spanId:t.spanId,startTimeMs:t.startTimeMs,stepIndex:t.stepIndex,turnId:t.turnId}}function isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function deserializeRecord(e,t){if(!isRecord(e))return{};let n={};for(let[r,i]of Object.entries(e)){let e=t(i);e!==void 0&&(n[r]=e)}return n}function deserializeTerminal(e){if(!isRecord(e)||typeof e.type!=`string`)return;let t=e.type;if(isTurnTerminalType(t))return t===`turn.failed`?{error:deserializeError(e.error),type:t}:{type:t}}function serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function serializeError(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:void 0}function deserializeError(e){if(!isRecord(e)||typeof e.message!=`string`)return;let t=Error(e.message);return typeof e.name==`string`&&(t.name=e.name),typeof e.stack==`string`&&(t.stack=e.stack),t}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{ContextAgentTraceStateStore,preserveSerializedAgentTraceState,readActionTraceContext,readSessionTraceContext};
1
+ import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage,loadContext}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{ContextKey}from"#context/key.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function readCurrentSessionTraceDecision(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[e]?.decision}function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n===void 0)return;let r=deserializeState(n).sessions[t];return r===void 0?void 0:withTraceDecision(e,r.context,r.decision)}function readActionTraceContext(e,t,n,r){let i=e[AgentTraceContextKey.name];if(i===void 0)return;let o=deserializeState(i),s=Object.values(o.actions).find(e=>e.sessionId===t&&e.turnId===n&&e.callId===r);if(s!==void 0)return withTraceDecision(e,{isRemote:!1,spanId:s.spanId,traceFlags:s.parent.traceFlags,traceId:s.parent.traceId},o.sessions[s.sessionId]?.decision)}function withTraceDecision(e,t,n){let i=e[SessionTraceSeedKey.name],a=n??i?.decision;return a===void 0?t:{...t,decision:a}}var ContextAgentTraceStateStore=class{deleteAction(e){updateState(t=>{let n={...t.actions};return delete n[e],{...t,actions:n}})}deleteActions(e,t){updateState(n=>{let r={...n.actions};for(let[n,i]of Object.entries(r))i.sessionId===e&&(t===void 0||i.turnId===t)&&delete r[n];return{...n,actions:r}})}deleteSession(e){updateState(t=>{let n={...t.sessions};return delete n[e],{...t,sessions:n}})}deleteTurn(e,t){updateState(n=>{let r={...n.turns};return delete r[turnKey(e,t)],{...n,turns:r}})}findAction(e,n){return Object.values(contextStorage.getStore()?.get(AgentTraceContextKey)?.actions??{}).find(t=>t.sessionId===e&&t.callId===n)}getAction(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.actions[e]}getSession(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[e]}getTurn(e,n){return contextStorage.getStore()?.get(AgentTraceContextKey)?.turns[turnKey(e,n)]}setAction(e,t){updateState(n=>({...n,actions:{...n.actions,[e]:t}}))}setSession(e,t){updateState(n=>({...n,sessions:{...n.sessions,[e]:t}}))}setTurn(e,t,n){updateState(r=>({...r,turns:{...r.turns,[turnKey(e,t)]:n}}))}};function updateState(e){loadContext().set(AgentTraceContextKey,t=>e(t??{actions:{},sessions:{},turns:{}}))}function turnKey(e,t){return`${e}\0${t}`}function serializeState(e){return{actions:e.actions,sessions:Object.fromEntries(Object.entries(e.sessions).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context)}])),turns:Object.fromEntries(Object.entries(e.turns).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context),terminal:t.terminal===void 0?void 0:t.terminal.type===`turn.failed`?{error:serializeError(t.terminal.error),type:t.terminal.type}:{type:t.terminal.type}}]))}}function deserializeState(t){return isRecord(t)?{actions:deserializeRecord(t.actions,deserializeAction),sessions:deserializeRecord(t.sessions,t=>{if(!(!isRecord(t)||!isSpanContext(t.context)))return{agentName:typeof t.agentName==`string`?t.agentName:void 0,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:typeof t.channelKind==`string`?t.channelKind:void 0,context:t.context,decision:deserializeInstrumentationDecision(t.decision),rootSessionId:typeof t.rootSessionId==`string`?t.rootSessionId:``}}),turns:deserializeRecord(t.turns,e=>{if(!(!isRecord(e)||!isSpanContext(e.context))&&!(typeof e.parentSpanId!=`string`||typeof e.startTimeMs!=`number`))return{context:e.context,parentIsRemote:typeof e.parentIsRemote==`boolean`?e.parentIsRemote:void 0,parentSpanId:e.parentSpanId,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,terminal:deserializeTerminal(e.terminal)}})}:{actions:{},sessions:{},turns:{}}}function deserializeAction(t){if(!(!isRecord(t)||typeof t.attemptIndex!=`number`||typeof t.callId!=`string`||!isActionKind(t.kind)||typeof t.name!=`string`||!isSpanContext(t.parent)||typeof t.rootSessionId!=`string`||typeof t.sessionId!=`string`||typeof t.spanId!=`string`||typeof t.startTimeMs!=`number`||typeof t.stepIndex!=`number`||typeof t.turnId!=`string`))return{attemptIndex:t.attemptIndex,callId:t.callId,channelAudience:normalizeChannelAudience(t.channelAudience),inputAttribute:typeof t.inputAttribute==`string`?t.inputAttribute:void 0,kind:t.kind,name:t.name,parent:t.parent,rootSessionId:t.rootSessionId,sessionId:t.sessionId,spanId:t.spanId,startTimeMs:t.startTimeMs,stepIndex:t.stepIndex,turnId:t.turnId}}function isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function deserializeRecord(e,t){if(!isRecord(e))return{};let n={};for(let[r,i]of Object.entries(e)){let e=t(i);e!==void 0&&(n[r]=e)}return n}function deserializeTerminal(e){if(!isRecord(e)||typeof e.type!=`string`)return;let t=e.type;if(isTurnTerminalType(t))return t===`turn.failed`?{error:deserializeError(e.error),type:t}:{type:t}}function serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function serializeError(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:void 0}function deserializeError(e){if(!isRecord(e)||typeof e.message!=`string`)return;let t=Error(e.message);return typeof e.name==`string`&&(t.name=e.name),typeof e.stack==`string`&&(t.stack=e.stack),t}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function deserializeInstrumentationDecision(e){if(isRecord(e))return e.action===`drop`?{action:`drop`}:e.action===`record`&&typeof e.recordInputs==`boolean`&&typeof e.recordOutputs==`boolean`?{action:`record`,recordInputs:e.recordInputs,recordOutputs:e.recordOutputs}:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{ContextAgentTraceStateStore,preserveSerializedAgentTraceState,readActionTraceContext,readCurrentSessionTraceDecision,readSessionTraceContext};
@@ -1,11 +1,13 @@
1
1
  import type { SpanContext } from "#compiled/@opentelemetry/api/index.js";
2
2
  import type { InstrumentationActionKind, InstrumentationTraceContext, InstrumentationTurnFailedEvent, InstrumentationTurnSettledEvent } from "#harness/instrumentation/lifecycle.js";
3
3
  import type { ChannelAudience } from "#shared/channel-audience.js";
4
+ import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
4
5
  export interface AgentSessionTraceState {
5
6
  readonly channelAudience?: ChannelAudience;
6
7
  readonly agentName?: string;
7
8
  readonly channelKind?: string;
8
9
  readonly context: SpanContext;
10
+ readonly decision?: InstrumentationDecision;
9
11
  readonly rootSessionId: string;
10
12
  }
11
13
  export interface AgentTurnTraceState {
@@ -36,9 +36,13 @@ export interface OtelOptions {
36
36
  * Process-wide trace and content decision. Boolean returns preserve the
37
37
  * existing audience-aware behavior; explicit decisions can disable emission
38
38
  * or select input and output capture independently. Defaults to emitting
39
- * every audience, with content only for public conversations. The result is a capture ceiling:
40
- * per-delivery audience and destination settings can only narrow it. A thrown
41
- * error rejects trace production without silencing lifecycle providers.
39
+ * every audience, with content only for public conversations. The result is
40
+ * an OpenTelemetry capture ceiling: per-delivery audience and destination
41
+ * settings can only narrow it. It never changes what authored instrumentation
42
+ * providers receive. A thrown error rejects trace production without
43
+ * silencing lifecycle providers. The policy may be invoked more than once
44
+ * while a new session is being prepared, so it must be deterministic for
45
+ * consistent results.
42
46
  */
43
47
  readonly tracePolicy?: TraceCapturePolicy;
44
48
  /**
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-CacMaX4P.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-DjYwFJF7.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-CacMaX4P.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-DjYwFJF7.js";
2
2
 
3
3
  export { useEveAgent };
@@ -52,11 +52,11 @@ Coding-agent launches and non-interactive terminals cannot answer the location p
52
52
 
53
53
  After scaffolding, a human terminal usually continues into `eve dev`. If a coding-agent REPL is on `PATH`, the handoff menu can open it instead or exit without starting either process. Coding-agent launches print the next steps instead of opening the TUI, so the session does not get stuck. Fresh projects use the parent workspace's package manager when there is one; otherwise they use the manager that launched `eve init`.
54
54
 
55
- | Flag | Type | Default | Description |
56
- | ---------------------- | ------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
55
+ | Flag | Type | Default | Description |
56
+ | ---------------------- | ------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
57
57
  | `--model <model>` | string | `openai/gpt-5.6-luna-fast` | Set the root agent's AI Gateway model ID. |
58
- | `--reasoning <effort>` | enum | provider default | Set reasoning to `none`, `minimal`, `low`, `medium`, `high`, or `xhigh`. `provider-default` leaves the field unauthored. |
59
- | `--channel-web-nextjs` | flag | off | Add the Web Chat app (Next.js). Not for existing projects — run `eve add channel/web` there instead. |
58
+ | `--reasoning <effort>` | enum | provider default | Set reasoning to `none`, `minimal`, `low`, `medium`, `high`, or `xhigh`. `provider-default` leaves the field unauthored. |
59
+ | `--channel-web-nextjs` | flag | off | Add the Web Chat app (Next.js). Not for existing projects — run `eve add channel/web` there instead. |
60
60
 
61
61
  ## `eve extension`
62
62
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.47.2",
3
+ "version": "0.47.3",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [