eve 0.42.0 → 0.44.0

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 (211) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/src/channel/adapter.d.ts +2 -1
  3. package/dist/src/channel/forwarded-principal.d.ts +4 -4
  4. package/dist/src/channel/instrumentation.js +1 -1
  5. package/dist/src/cli/commands/registry-project.d.ts +3 -0
  6. package/dist/src/cli/commands/registry-project.js +2 -1
  7. package/dist/src/cli/commands/registry.d.ts +2 -0
  8. package/dist/src/cli/commands/registry.js +1 -1
  9. package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
  10. package/dist/src/compiled/.vendor-stamp.json +1 -1
  11. package/dist/src/compiled/jsonc-parser/index.d.ts +19 -0
  12. package/dist/src/compiler/extension-compatibility.d.ts +7 -5
  13. package/dist/src/compiler/extension-compatibility.js +1 -1
  14. package/dist/src/compiler/manifest.d.ts +3 -0
  15. package/dist/src/compiler/manifest.js +1 -1
  16. package/dist/src/compiler/normalize-manifest.js +1 -1
  17. package/dist/src/compiler/normalize-tool.js +1 -1
  18. package/dist/src/context/build-dynamic-tools.d.ts +5 -5
  19. package/dist/src/context/build-dynamic-tools.js +1 -1
  20. package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
  21. package/dist/src/context/dynamic-tool-lifecycle.d.ts +8 -27
  22. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  23. package/dist/src/context/keys.d.ts +10 -14
  24. package/dist/src/context/keys.js +1 -1
  25. package/dist/src/context/provider.d.ts +5 -1
  26. package/dist/src/context/run-step.d.ts +3 -2
  27. package/dist/src/context/run-step.js +1 -1
  28. package/dist/src/execution/agent-handle-dispatch.d.ts +3 -0
  29. package/dist/src/execution/agent-handle-dispatch.js +1 -1
  30. package/dist/src/execution/delegation-tool.d.ts +9 -1
  31. package/dist/src/execution/delegation-tool.js +1 -1
  32. package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +14 -1
  33. package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -1
  34. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  35. package/dist/src/execution/history-view.d.ts +9 -0
  36. package/dist/src/execution/history-view.js +1 -0
  37. package/dist/src/execution/next-driver-action.d.ts +33 -1
  38. package/dist/src/execution/node-step.d.ts +5 -2
  39. package/dist/src/execution/node-step.js +1 -1
  40. package/dist/src/execution/remote-agent-dispatch.d.ts +2 -0
  41. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  42. package/dist/src/execution/session-callback-step.d.ts +2 -2
  43. package/dist/src/execution/session-callback-step.js +1 -1
  44. package/dist/src/execution/tasks/child/steps.js +1 -1
  45. package/dist/src/execution/tasks/child/update.d.ts +2 -2
  46. package/dist/src/execution/tasks/child/update.js +1 -1
  47. package/dist/src/execution/tasks/child/workflow.js +1 -1
  48. package/dist/src/execution/tasks/parent/agent-views.d.ts +2 -1
  49. package/dist/src/execution/tasks/parent/agent-views.js +1 -1
  50. package/dist/src/execution/tasks/parent/continuation-dispatch.d.ts +6 -0
  51. package/dist/src/execution/tasks/parent/continuation-dispatch.js +1 -1
  52. package/dist/src/execution/tasks/parent/control-shared.d.ts +1 -1
  53. package/dist/src/execution/tasks/parent/control-shared.js +1 -1
  54. package/dist/src/execution/tasks/parent/delegate.d.ts +20 -6
  55. package/dist/src/execution/tasks/parent/delegate.js +1 -1
  56. package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -1
  57. package/dist/src/execution/tasks/parent/dispatch.d.ts +13 -1
  58. package/dist/src/execution/tasks/parent/dispatch.js +1 -1
  59. package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
  60. package/dist/src/execution/tasks/parent/tool-execution.d.ts +46 -0
  61. package/dist/src/execution/tasks/parent/tool-execution.js +1 -0
  62. package/dist/src/execution/tool-auth.d.ts +12 -3
  63. package/dist/src/execution/tool-auth.js +1 -1
  64. package/dist/src/execution/turn-cancellation-control.js +1 -1
  65. package/dist/src/execution/turn-workflow.js +1 -1
  66. package/dist/src/execution/wire/session-inbox-wire.v1.js +1 -1
  67. package/dist/src/execution/workflow-steps.d.ts +1 -54
  68. package/dist/src/execution/workflow-steps.js +1 -1
  69. package/dist/src/execution/workflow-trace-context.js +1 -1
  70. package/dist/src/harness/advertised-tools.js +1 -1
  71. package/dist/src/harness/background-tools.d.ts +37 -0
  72. package/dist/src/harness/background-tools.js +1 -0
  73. package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
  74. package/dist/src/harness/execute-tool.d.ts +10 -1
  75. package/dist/src/harness/handles/transitions.d.ts +36 -0
  76. package/dist/src/harness/handles/transitions.js +1 -1
  77. package/dist/src/harness/instrumentation/lifecycle.d.ts +4 -0
  78. package/dist/src/harness/instrumentation/native-events.d.ts +2 -0
  79. package/dist/src/harness/instrumentation/native-events.js +1 -1
  80. package/dist/src/harness/messages.d.ts +2 -0
  81. package/dist/src/harness/messages.js +1 -1
  82. package/dist/src/harness/prepare-trace-context.d.ts +2 -0
  83. package/dist/src/harness/prepare-trace-context.js +1 -1
  84. package/dist/src/harness/tool-loop.js +2 -2
  85. package/dist/src/harness/tools.d.ts +5 -1
  86. package/dist/src/harness/tools.js +1 -1
  87. package/dist/src/harness/types.d.ts +13 -0
  88. package/dist/src/internal/application/package.js +1 -1
  89. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  90. package/dist/src/internal/authored-module-loader.js +1 -1
  91. package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.js +1 -1
  92. package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.d.ts +13 -0
  93. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +7 -31
  94. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +4 -4
  95. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  96. package/dist/src/public/channels/chat-sdk/audience.d.ts +2 -0
  97. package/dist/src/public/channels/chat-sdk/audience.js +1 -0
  98. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +2 -0
  99. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  100. package/dist/src/public/channels/discord/audience.d.ts +5 -0
  101. package/dist/src/public/channels/discord/audience.js +1 -0
  102. package/dist/src/public/channels/discord/discordChannel.d.ts +2 -0
  103. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  104. package/dist/src/public/channels/discord/inbound.d.ts +1 -0
  105. package/dist/src/public/channels/discord/inbound.js +1 -1
  106. package/dist/src/public/channels/discord/index.d.ts +1 -0
  107. package/dist/src/public/channels/eve.d.ts +7 -7
  108. package/dist/src/public/channels/eve.js +1 -1
  109. package/dist/src/public/channels/index.d.ts +3 -2
  110. package/dist/src/public/channels/slack/slackChannel.d.ts +4 -0
  111. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  112. package/dist/src/public/channels/teams/index.d.ts +1 -0
  113. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  114. package/dist/src/public/channels/telegram/audience.d.ts +3 -0
  115. package/dist/src/public/channels/telegram/audience.js +1 -0
  116. package/dist/src/public/channels/telegram/index.d.ts +1 -0
  117. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  118. package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -0
  119. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  120. package/dist/src/public/definitions/channel.d.ts +1 -0
  121. package/dist/src/public/definitions/remote-agent.d.ts +7 -5
  122. package/dist/src/public/definitions/tool.d.ts +23 -0
  123. package/dist/src/public/definitions/tool.js +1 -1
  124. package/dist/src/public/instrumentation/otel.d.ts +6 -10
  125. package/dist/src/public/instrumentation/otel.js +1 -1
  126. package/dist/src/public/tools/approval/approval-helpers.js +1 -1
  127. package/dist/src/public/tools/index.d.ts +1 -1
  128. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -2
  129. package/dist/src/runtime/framework-tools/subagent/local.d.ts +41 -0
  130. package/dist/src/runtime/framework-tools/subagent/local.js +1 -0
  131. package/dist/src/runtime/framework-tools/subagent/remote.d.ts +23 -0
  132. package/dist/src/runtime/framework-tools/subagent/remote.js +1 -0
  133. package/dist/src/runtime/framework-tools/tasks.d.ts +11 -2
  134. package/dist/src/runtime/framework-tools/tasks.js +1 -1
  135. package/dist/src/runtime/resolve-tool.js +1 -1
  136. package/dist/src/runtime/session-callback-route.js +1 -1
  137. package/dist/src/setup/integrations/linq/management.d.ts +5 -0
  138. package/dist/src/setup/integrations/linq/management.js +1 -0
  139. package/dist/src/setup/integrations/linq/setup.d.ts +5 -1
  140. package/dist/src/setup/integrations/linq/setup.js +3 -3
  141. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  142. package/dist/src/setup/scaffold/create/project.js +4 -10
  143. package/dist/src/setup/scaffold/create/web-template.d.ts +2 -2
  144. package/dist/src/setup/scaffold/create/web-template.js +374 -2
  145. package/dist/src/setup/scaffold/update/channels.d.ts +1 -1
  146. package/dist/src/setup/scaffold/update/channels.js +2 -2
  147. package/dist/src/setup/scaffold/update/package-json.d.ts +0 -2
  148. package/dist/src/setup/scaffold/update/package-json.js +1 -1
  149. package/dist/src/setup/scaffold/workspace-root.d.ts +0 -1
  150. package/dist/src/setup/scaffold/workspace-root.js +1 -1
  151. package/dist/src/shared/channel-audience.d.ts +7 -0
  152. package/dist/src/shared/channel-audience.js +1 -0
  153. package/dist/src/shared/channel-definition.d.ts +2 -1
  154. package/dist/src/shared/durable-dynamic-tool-callbacks.d.ts +34 -0
  155. package/dist/src/shared/durable-dynamic-tool-callbacks.js +1 -0
  156. package/dist/src/shared/dynamic-tool-definition.d.ts +2 -4
  157. package/dist/src/shared/empty-delivery.js +1 -1
  158. package/dist/src/shared/history-view.d.ts +22 -0
  159. package/dist/src/shared/history-view.js +1 -0
  160. package/dist/src/shared/json.d.ts +2 -0
  161. package/dist/src/shared/json.js +1 -1
  162. package/dist/src/shared/tool-definition.d.ts +4 -1
  163. package/dist/src/shared/tool-task.d.ts +107 -0
  164. package/dist/src/shared/tool-task.js +1 -0
  165. package/dist/src/tasks/delivery-context.d.ts +12 -0
  166. package/dist/src/tasks/delivery-context.js +17 -0
  167. package/dist/src/tasks/json.d.ts +25 -10
  168. package/dist/src/tasks/json.js +1 -1
  169. package/dist/src/tasks/session-index.d.ts +5 -3
  170. package/dist/src/tasks/session-index.js +1 -1
  171. package/dist/src/tasks/transitions.d.ts +40 -5
  172. package/dist/src/tasks/transitions.js +1 -1
  173. package/dist/src/tasks/types.d.ts +46 -4
  174. package/dist/src/tasks/types.js +1 -1
  175. package/dist/src/tracing/agent-action-instrumentation.js +1 -1
  176. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  177. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -1
  178. package/dist/src/tracing/agent-otel-provider.d.ts +2 -0
  179. package/dist/src/tracing/agent-otel-provider.js +2 -2
  180. package/dist/src/tracing/agent-otel-session-context.d.ts +2 -0
  181. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  182. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  183. package/dist/src/tracing/agent-trace-state.d.ts +3 -0
  184. package/dist/src/tracing/channel-audience-context.d.ts +4 -0
  185. package/dist/src/tracing/channel-audience-context.js +1 -0
  186. package/dist/src/tracing/content-attributes.js +1 -1
  187. package/dist/src/tracing/content-span-processor.d.ts +7 -7
  188. package/dist/src/tracing/content-span-processor.js +1 -1
  189. package/dist/src/tracing/install-instrumentation-runtime.js +1 -1
  190. package/dist/src/tracing/local-instrumentation-runtime.d.ts +3 -0
  191. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  192. package/dist/src/tracing/local-traces.d.ts +1 -10
  193. package/dist/src/tracing/local-traces.js +1 -1
  194. package/dist/src/tracing/otel-declaration.d.ts +34 -27
  195. package/dist/src/tracing/otel-declaration.js +1 -1
  196. package/dist/src/tracing/sampled-trace.d.ts +2 -0
  197. package/dist/src/tracing/sampled-trace.js +1 -0
  198. package/dist/src/tracing/span-export-policy.d.ts +41 -0
  199. package/dist/src/tracing/span-export-policy.js +1 -0
  200. package/dist/src/tracing/suppress-tracing.d.ts +2 -0
  201. package/dist/src/tracing/suppress-tracing.js +1 -0
  202. package/docs/channels/custom.mdx +2 -0
  203. package/docs/channels/linq.mdx +1 -1
  204. package/docs/getting-started.mdx +36 -36
  205. package/docs/guides/auth-and-route-protection.md +6 -2
  206. package/docs/guides/dynamic-capabilities.md +12 -10
  207. package/docs/guides/instrumentation.md +2 -0
  208. package/docs/guides/remote-agents.md +10 -2
  209. package/docs/tools/overview.mdx +19 -0
  210. package/docs/tutorial/ship-it.mdx +1 -1
  211. package/package.json +1 -1
@@ -0,0 +1,3 @@
1
+ import type { TelegramInstrumentationMetadata } from "#public/channels/telegram/index.js";
2
+ import type { TelegramChannelState } from "#public/channels/telegram/telegramChannel.js";
3
+ export declare function telegramInstrumentationMetadata(state: TelegramChannelState): TelegramInstrumentationMetadata;
@@ -0,0 +1 @@
1
+ function telegramInstrumentationMetadata(e){return{audience:telegramAudience(e.chatType),chatId:e.chatId,chatType:e.chatType,triggeringUserId:e.triggeringUserId??null}}function telegramAudience(e){return e===`private`||e===`group`||e===`supergroup`||e===`channel`?`private`:`unknown`}export{telegramInstrumentationMetadata};
@@ -6,6 +6,7 @@ export type { ModelMessage } from "ai";
6
6
  * inbound update populates it.
7
7
  */
8
8
  export interface TelegramInstrumentationMetadata extends Record<string, unknown> {
9
+ readonly audience: import("#shared/channel-audience.js").ChannelAudience;
9
10
  readonly chatId: string | null;
10
11
  readonly chatType: import("#public/channels/telegram/inbound.js").TelegramChatType | null;
11
12
  readonly triggeringUserId: string | null;
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{isCompiledChannel}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{formatTelegramContextBlock,parseTelegramUpdate}from"#public/channels/telegram/inbound.js";import{answerTelegramCallbackQuery,callTelegramApi,editTelegramMessageReplyMarkup,sendTelegramChatAction,sendTelegramMessage,splitTelegramMessageText,telegramContinuationToken}from"#public/channels/telegram/api.js";import{TELEGRAM_HITL_CALLBACK_PREFIX,isTelegramSyntheticResponse,resolveTelegramInputResponses,telegramCallbackInputResponse,telegramReplyInputResponse}from"#public/channels/telegram/hitl.js";import{buildTelegramTurnMessage,collectTelegramFileParts,createTelegramFetchFile}from"#public/channels/telegram/attachments.js";import{defaultEvents,defaultOnMessage}from"#public/channels/telegram/defaults.js";import{verifyTelegramRequest}from"#public/channels/telegram/verify.js";const log=createLogger(`telegram.channel`);function telegramChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=e.onMessage??defaultOnMessage,r={...defaultEvents,...e.events},c=defineChannel({kindHint:`telegram`,turnPolicy:e.turnPolicy,state:initialTelegramState(e.botUsername),metadata:e=>({chatId:e.chatId,chatType:e.chatType,triggeringUserId:e.triggeringUserId??null}),fetchFile:createTelegramFetchFile({api:e.api,credentials:e.credentials,policy:t}),context(t,n){return rebuildTelegramContext(t,n,e)},routes:[POST(e.route??`/eve/v1/telegram`,async(r,{from:a,waitUntil:o})=>{let s=await verifyInbound(r,e.credentials);if(s===null)return new Response(`unauthorized`,{status:401});let c;try{c=parseJsonObject(JSON.parse(s))}catch(e){return log.warn(`inbound Telegram body is not valid JSON`,{error:e}),new Response(`ok`)}let u=parseTelegramUpdate(c);return u===null?new Response(`ok`):u.kind===`message`?(o(dispatchMessage({config:e,message:u.message,onMessage:n,uploadPolicy:t,from:a})),new Response(`ok`)):(o(dispatchCallbackQuery({config:e,query:u.callbackQuery,from:a})),new Response(`ok`))})],async receive(t,{from:n}){let r=t.target,i=readChatId(r.chatId);if(i===void 0)throw Error(`telegramChannel().receive requires target.chatId.`);let a=typeof r.messageThreadId==`number`?r.messageThreadId:void 0,o=readOptionalString(r.conversationId),s=r.initialMessage;if(s!==void 0&&o!==void 0)throw Error("telegramChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let c={...initialTelegramState(e.botUsername),chatId:i,conversationId:o??null,messageThreadId:a??null};return s!==void 0&&await buildTelegramHandle({config:e,state:c}).sendMessage(s),n(continuationTokenFromState(c)).send(t.message,{auth:t.auth,state:c})},events:r});return attachTelegramDeliver(c),c}function rebuildTelegramContext(e,t,n){return{state:e,telegram:buildTelegramHandle({config:n,session:t,state:e})}}function buildTelegramHandle(e){let n=e.config.api,r=e.state,i=e.config.credentials;function anchor(t){let n=r.chatType??t.chatType??null;r.chatType===null&&t.chatType!==void 0&&(r.chatType=t.chatType),!(!t.id||!shouldAnchorTelegramConversation(n))&&(r.conversationId=t.id,r.chatId&&e.session?.continuation?.rekey(telegramContinuationToken({chatId:r.chatId,conversationId:t.id,messageThreadId:r.messageThreadId??void 0})))}async function sendOne(e){let t=r.chatId??``;if(!t)throw Error(`telegramChannel: missing chat id for outbound message.`);let a=await sendTelegramMessage({apiBaseUrl:n?.apiBaseUrl,body:{...e,message_thread_id:e.message_thread_id??r.messageThreadId??void 0},credentials:i,fetch:n?.fetch,fileBaseUrl:n?.fileBaseUrl,chatId:t});return anchor(a),a}return{botUsername:r.botUsername??e.config.botUsername,chatId:r.chatId??``,chatType:r.chatType??void 0,conversationId:r.conversationId??void 0,messageThreadId:r.messageThreadId??void 0,answerCallbackQuery(e){return answerTelegramCallbackQuery({apiBaseUrl:n?.apiBaseUrl,callbackQueryId:e.callbackQueryId,credentials:i,fetch:n?.fetch,showAlert:e.showAlert,text:e.text})},editMessageReplyMarkup(e){let t=r.chatId??``;if(!t)throw Error(`telegramChannel: missing chat id for reply-markup edit.`);return editTelegramMessageReplyMarkup({apiBaseUrl:n?.apiBaseUrl,chatId:t,credentials:i,fetch:n?.fetch,messageId:e.messageId,replyMarkup:e.replyMarkup})},post(e){return postTelegramMessage(e,sendOne)},request(e,t){return callTelegramApi({apiBaseUrl:n?.apiBaseUrl,body:t,botToken:i?.botToken,fetch:n?.fetch,method:e})},sendMessage(e){return postTelegramMessage(e,sendOne)},async startTyping(e=`typing`){let a=r.chatId??``;if(a)try{await sendTelegramChatAction({action:e,apiBaseUrl:n?.apiBaseUrl,chatId:a,credentials:i,fetch:n?.fetch,messageThreadId:r.messageThreadId??void 0})}catch(e){logError(log,`Telegram typing indicator failed — swallowed`,e,{chatId:a})}}}}function shouldAnchorTelegramConversation(e){return e===`group`||e===`supergroup`}async function postTelegramMessage(e,t){let n=typeof e==`string`?{text:e}:e,r=splitTelegramMessageText(n.text),i;for(let[e,a]of r.entries()){let r=await t(e===0?{...n,text:a}:{text:a});i===void 0&&(i=r)}return i??{id:``,raw:null}}async function verifyInbound(e,t){try{return await verifyTelegramRequest(e,{secretToken:t?.webhookVerifier?void 0:t?.webhookSecretToken,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`telegram inbound verification failed`,{error:e}),null}}async function dispatchMessage(e){if(e.message.from?.isBot===!0)return;let t=stateFromMessage(e.message,e.config),n={telegram:buildTelegramHandle({config:e.config,state:t})},r;try{r=await e.onMessage(n,e.message)}catch(e){log.error(`message handler failed`,{error:e});return}if(r==null)return;let i=collectTelegramFileParts(e.message.attachments,e.uploadPolicy),a=buildTelegramTurnMessage(e.message,i),o=formatTelegramContextBlock({botUsername:e.config.botUsername,chatId:e.message.chat.id,chatTitle:e.message.chat.title,chatType:e.message.chat.type,messageId:e.message.messageId,messageThreadId:e.message.messageThreadId,userId:e.message.from?.id,username:e.message.from?.username}),s=r.context??[],l=e.message.text||e.message.caption,u=e.message.replyToMessage?.from?.isBot===!0&&l.trim().length>0?[telegramReplyInputResponse({messageId:e.message.replyToMessage.messageId,text:l})]:void 0;try{let n=e.from(continuationTokenFromState(t));u===void 0?await n.send(a,{auth:r.auth,context:[o,...s],state:t,title:r.title}):await n.respond(u,{auth:r.auth,context:[o,...s]})}catch(e){log.error(`message delivery failed`,{error:e})}}async function dispatchCallbackQuery(e){let t=stateFromCallbackQuery(e.query,e.config),n={telegram:buildTelegramHandle({config:e.config,state:t})};if(e.query.data?.startsWith(TELEGRAM_HITL_CALLBACK_PREFIX)===!0){try{await n.telegram.answerCallbackQuery({callbackQueryId:e.query.id,text:`Answer received.`})}catch(e){log.warn(`Telegram callback-query acknowledgement failed`,{error:e})}if(!e.query.message||!t.chatId)return;try{await e.from(continuationTokenFromState(t)).respond([telegramCallbackInputResponse(e.query.data)],{auth:null})}catch(e){log.error(`callback query delivery failed`,{error:e})}return}if(e.config.onCallbackQuery!==void 0){try{await e.config.onCallbackQuery(n,e.query)}catch(e){log.error(`custom callback-query handler failed`,{error:e})}return}try{await n.telegram.answerCallbackQuery({callbackQueryId:e.query.id,text:`Unsupported action.`})}catch(e){log.warn(`Telegram unsupported callback-query acknowledgement failed`,{error:e})}}function attachTelegramDeliver(e){if(!isCompiledChannel(e))return;let t=e.adapter;t.deliver=(e,t)=>{let n=e.inputResponses??[];if(n.some(isTelegramSyntheticResponse)){let r=resolveTelegramInputResponses(t.state,n);return r.length>0?{inputResponses:r,context:e.context}:e.message===void 0?void 0:{message:e.message,context:e.context}}return defaultDeliverResult(e)}}function stateFromMessage(e,t){let n=e.chat.type===`private`;return{...initialTelegramState(t.botUsername),chatId:e.chat.id,chatType:e.chat.type,conversationId:n?null:conversationIdForMessage(e),messageThreadId:e.messageThreadId??null,triggeringUserId:e.from?.id??null}}function stateFromCallbackQuery(e,t){let n=e.message;if(!n)return{...initialTelegramState(t.botUsername),triggeringUserId:e.from.id};let r=n.chat.type===`private`;return{...initialTelegramState(t.botUsername),chatId:n.chat.id,chatType:n.chat.type,conversationId:r?null:n.messageId,messageThreadId:n.messageThreadId??null,triggeringUserId:e.from.id}}function conversationIdForMessage(e){return e.replyToMessage?.from?.isBot===!0?e.replyToMessage.messageId:e.messageId}function continuationTokenFromState(e){return telegramContinuationToken({chatId:e.chatId??``,conversationId:e.chatType===`private`?void 0:e.conversationId??void 0,messageThreadId:e.messageThreadId??void 0})}function initialTelegramState(e){return{botUsername:e??null,chatId:null,chatType:null,conversationId:null,hitlCallbacks:{},messageThreadId:null,nextHitlCallbackId:0,pendingFreeformReplies:{},triggeringUserId:null}}function readChatId(e){if(typeof e==`string`&&e.length>0)return e;if(typeof e==`number`&&Number.isFinite(e))return String(e)}function readOptionalString(e){if(typeof e==`string`&&e.length>0)return e;if(typeof e==`number`&&Number.isFinite(e))return String(e)}export{telegramChannel};
1
+ import{createLogger,logError}from"#internal/logging.js";import{isCompiledChannel}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{formatTelegramContextBlock,parseTelegramUpdate}from"#public/channels/telegram/inbound.js";import{answerTelegramCallbackQuery,callTelegramApi,editTelegramMessageReplyMarkup,sendTelegramChatAction,sendTelegramMessage,splitTelegramMessageText,telegramContinuationToken}from"#public/channels/telegram/api.js";import{TELEGRAM_HITL_CALLBACK_PREFIX,isTelegramSyntheticResponse,resolveTelegramInputResponses,telegramCallbackInputResponse,telegramReplyInputResponse}from"#public/channels/telegram/hitl.js";import{buildTelegramTurnMessage,collectTelegramFileParts,createTelegramFetchFile}from"#public/channels/telegram/attachments.js";import{defaultEvents,defaultOnMessage}from"#public/channels/telegram/defaults.js";import{verifyTelegramRequest}from"#public/channels/telegram/verify.js";import{telegramInstrumentationMetadata}from"#public/channels/telegram/audience.js";const log=createLogger(`telegram.channel`);function telegramChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=e.onMessage??defaultOnMessage,r={...defaultEvents,...e.events},c=defineChannel({kindHint:`telegram`,turnPolicy:e.turnPolicy,state:initialTelegramState(e.botUsername),metadata:telegramInstrumentationMetadata,fetchFile:createTelegramFetchFile({api:e.api,credentials:e.credentials,policy:t}),context(t,n){return rebuildTelegramContext(t,n,e)},routes:[POST(e.route??`/eve/v1/telegram`,async(r,{from:a,waitUntil:o})=>{let s=await verifyInbound(r,e.credentials);if(s===null)return new Response(`unauthorized`,{status:401});let c;try{c=parseJsonObject(JSON.parse(s))}catch(e){return log.warn(`inbound Telegram body is not valid JSON`,{error:e}),new Response(`ok`)}let u=parseTelegramUpdate(c);return u===null?new Response(`ok`):u.kind===`message`?(o(dispatchMessage({config:e,message:u.message,onMessage:n,uploadPolicy:t,from:a})),new Response(`ok`)):(o(dispatchCallbackQuery({config:e,query:u.callbackQuery,from:a})),new Response(`ok`))})],async receive(t,{from:n}){let r=t.target,i=readChatId(r.chatId);if(i===void 0)throw Error(`telegramChannel().receive requires target.chatId.`);let a=typeof r.messageThreadId==`number`?r.messageThreadId:void 0,o=readOptionalString(r.conversationId),s=r.initialMessage;if(s!==void 0&&o!==void 0)throw Error("telegramChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let c={...initialTelegramState(e.botUsername),chatId:i,conversationId:o??null,messageThreadId:a??null};return s!==void 0&&await buildTelegramHandle({config:e,state:c}).sendMessage(s),n(continuationTokenFromState(c)).send(t.message,{auth:t.auth,state:c})},events:r});return attachTelegramDeliver(c),c}function rebuildTelegramContext(e,t,n){return{state:e,telegram:buildTelegramHandle({config:n,session:t,state:e})}}function buildTelegramHandle(e){let n=e.config.api,r=e.state,i=e.config.credentials;function anchor(t){let n=r.chatType??t.chatType??null;r.chatType===null&&t.chatType!==void 0&&(r.chatType=t.chatType),!(!t.id||!shouldAnchorTelegramConversation(n))&&(r.conversationId=t.id,r.chatId&&e.session?.continuation?.rekey(telegramContinuationToken({chatId:r.chatId,conversationId:t.id,messageThreadId:r.messageThreadId??void 0})))}async function sendOne(e){let t=r.chatId??``;if(!t)throw Error(`telegramChannel: missing chat id for outbound message.`);let a=await sendTelegramMessage({apiBaseUrl:n?.apiBaseUrl,body:{...e,message_thread_id:e.message_thread_id??r.messageThreadId??void 0},credentials:i,fetch:n?.fetch,fileBaseUrl:n?.fileBaseUrl,chatId:t});return anchor(a),a}return{botUsername:r.botUsername??e.config.botUsername,chatId:r.chatId??``,chatType:r.chatType??void 0,conversationId:r.conversationId??void 0,messageThreadId:r.messageThreadId??void 0,answerCallbackQuery(e){return answerTelegramCallbackQuery({apiBaseUrl:n?.apiBaseUrl,callbackQueryId:e.callbackQueryId,credentials:i,fetch:n?.fetch,showAlert:e.showAlert,text:e.text})},editMessageReplyMarkup(e){let t=r.chatId??``;if(!t)throw Error(`telegramChannel: missing chat id for reply-markup edit.`);return editTelegramMessageReplyMarkup({apiBaseUrl:n?.apiBaseUrl,chatId:t,credentials:i,fetch:n?.fetch,messageId:e.messageId,replyMarkup:e.replyMarkup})},post(e){return postTelegramMessage(e,sendOne)},request(e,t){return callTelegramApi({apiBaseUrl:n?.apiBaseUrl,body:t,botToken:i?.botToken,fetch:n?.fetch,method:e})},sendMessage(e){return postTelegramMessage(e,sendOne)},async startTyping(e=`typing`){let a=r.chatId??``;if(a)try{await sendTelegramChatAction({action:e,apiBaseUrl:n?.apiBaseUrl,chatId:a,credentials:i,fetch:n?.fetch,messageThreadId:r.messageThreadId??void 0})}catch(e){logError(log,`Telegram typing indicator failed — swallowed`,e,{chatId:a})}}}}function shouldAnchorTelegramConversation(e){return e===`group`||e===`supergroup`}async function postTelegramMessage(e,t){let n=typeof e==`string`?{text:e}:e,r=splitTelegramMessageText(n.text),i;for(let[e,a]of r.entries()){let r=await t(e===0?{...n,text:a}:{text:a});i===void 0&&(i=r)}return i??{id:``,raw:null}}async function verifyInbound(e,t){try{return await verifyTelegramRequest(e,{secretToken:t?.webhookVerifier?void 0:t?.webhookSecretToken,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`telegram inbound verification failed`,{error:e}),null}}async function dispatchMessage(e){if(e.message.from?.isBot===!0)return;let t=stateFromMessage(e.message,e.config),n={telegram:buildTelegramHandle({config:e.config,state:t})},r;try{r=await e.onMessage(n,e.message)}catch(e){log.error(`message handler failed`,{error:e});return}if(r==null)return;let i=collectTelegramFileParts(e.message.attachments,e.uploadPolicy),a=buildTelegramTurnMessage(e.message,i),o=formatTelegramContextBlock({botUsername:e.config.botUsername,chatId:e.message.chat.id,chatTitle:e.message.chat.title,chatType:e.message.chat.type,messageId:e.message.messageId,messageThreadId:e.message.messageThreadId,userId:e.message.from?.id,username:e.message.from?.username}),s=r.context??[],l=e.message.text||e.message.caption,u=e.message.replyToMessage?.from?.isBot===!0&&l.trim().length>0?[telegramReplyInputResponse({messageId:e.message.replyToMessage.messageId,text:l})]:void 0;try{let n=e.from(continuationTokenFromState(t));u===void 0?await n.send(a,{auth:r.auth,context:[o,...s],state:t,title:r.title}):await n.respond(u,{auth:r.auth,context:[o,...s]})}catch(e){log.error(`message delivery failed`,{error:e})}}async function dispatchCallbackQuery(e){let t=stateFromCallbackQuery(e.query,e.config),n={telegram:buildTelegramHandle({config:e.config,state:t})};if(e.query.data?.startsWith(TELEGRAM_HITL_CALLBACK_PREFIX)===!0){try{await n.telegram.answerCallbackQuery({callbackQueryId:e.query.id,text:`Answer received.`})}catch(e){log.warn(`Telegram callback-query acknowledgement failed`,{error:e})}if(!e.query.message||!t.chatId)return;try{await e.from(continuationTokenFromState(t)).respond([telegramCallbackInputResponse(e.query.data)],{auth:null})}catch(e){log.error(`callback query delivery failed`,{error:e})}return}if(e.config.onCallbackQuery!==void 0){try{await e.config.onCallbackQuery(n,e.query)}catch(e){log.error(`custom callback-query handler failed`,{error:e})}return}try{await n.telegram.answerCallbackQuery({callbackQueryId:e.query.id,text:`Unsupported action.`})}catch(e){log.warn(`Telegram unsupported callback-query acknowledgement failed`,{error:e})}}function attachTelegramDeliver(e){if(!isCompiledChannel(e))return;let t=e.adapter;t.deliver=(e,t)=>{let n=e.inputResponses??[];if(n.some(isTelegramSyntheticResponse)){let r=resolveTelegramInputResponses(t.state,n);return r.length>0?{inputResponses:r,context:e.context}:e.message===void 0?void 0:{message:e.message,context:e.context}}return defaultDeliverResult(e)}}function stateFromMessage(e,t){let n=e.chat.type===`private`;return{...initialTelegramState(t.botUsername),chatId:e.chat.id,chatType:e.chat.type,conversationId:n?null:conversationIdForMessage(e),messageThreadId:e.messageThreadId??null,triggeringUserId:e.from?.id??null}}function stateFromCallbackQuery(e,t){let n=e.message;if(!n)return{...initialTelegramState(t.botUsername),triggeringUserId:e.from.id};let r=n.chat.type===`private`;return{...initialTelegramState(t.botUsername),chatId:n.chat.id,chatType:n.chat.type,conversationId:r?null:n.messageId,messageThreadId:n.messageThreadId??null,triggeringUserId:e.from.id}}function conversationIdForMessage(e){return e.replyToMessage?.from?.isBot===!0?e.replyToMessage.messageId:e.messageId}function continuationTokenFromState(e){return telegramContinuationToken({chatId:e.chatId??``,conversationId:e.chatType===`private`?void 0:e.conversationId??void 0,messageThreadId:e.messageThreadId??void 0})}function initialTelegramState(e){return{botUsername:e??null,chatId:null,chatType:null,conversationId:null,hitlCallbacks:{},messageThreadId:null,nextHitlCallbackId:0,pendingFreeformReplies:{},triggeringUserId:null}}function readChatId(e){if(typeof e==`string`&&e.length>0)return e;if(typeof e==`number`&&Number.isFinite(e))return String(e)}function readOptionalString(e){if(typeof e==`string`&&e.length>0)return e;if(typeof e==`number`&&Number.isFinite(e))return String(e)}export{telegramChannel};
@@ -6,6 +6,7 @@ import { type TwilioApiOptions, type TwilioApiResponse, type TwilioCredentials }
6
6
  import { type TwilioTextMessage, type TwilioVoiceCall, type TwilioVoiceTranscription } from "#public/channels/twilio/inbound.js";
7
7
  import { type TwilioAuthToken, type TwilioWebhookUrl } from "#public/channels/twilio/verify.js";
8
8
  import { type Channel } from "#public/definitions/channel.js";
9
+ import type { ChannelAudience } from "#shared/channel-audience.js";
9
10
  type EventData<T extends UnstampedMessageStreamEvent["type"]> = Extract<UnstampedMessageStreamEvent, {
10
11
  type: T;
11
12
  }> extends {
@@ -35,6 +36,7 @@ export interface TwilioChannelState {
35
36
  }
36
37
  /** Per-session instrumentation snapshot for Twilio runtime telemetry. Reports the active phone-number pair and the most recent message and call SIDs. */
37
38
  export interface TwilioInstrumentationMetadata extends Record<string, unknown> {
39
+ readonly audience: ChannelAudience;
38
40
  readonly from: string | null;
39
41
  readonly lastCallSid: string | null;
40
42
  readonly lastMessageSid: string | null;
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/twilio/verify.js";import{callTwilioApi,sendTwilioMessage,twilioContinuationToken,updateTwilioCall}from"#public/channels/twilio/api.js";import{emptyTwilioResponse,gatherSpeechTwilioResponse,sayTwilioResponse}from"#public/channels/twilio/twiml.js";import{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription}from"#public/channels/twilio/defaults.js";import{formatTwilioContextBlock,parseTwilioTextMessage,parseTwilioVoiceCall,parseTwilioVoiceTranscription}from"#public/channels/twilio/inbound.js";import{buildTwilioActionUrl,buildTwilioRoutes,verifyTwilioInbound}from"#public/channels/twilio/routing.js";const log=createLogger(`twilio.channel`);function twilioChannel(e){assertAllowFromConfigured(e);let a=buildTwilioRoutes(e.route??`/eve/v1/twilio`),o=e.onText??defaultOnText,c=e.onVoice??defaultOnVoice,l=e.onVoiceTranscription??defaultOnVoiceTranscription,u={...defaultEvents,...e.events},d=handleTwilioMessages({config:e,onText:o}),f=handleTwilioVoice({config:e,onVoice:c,routes:a}),p=handleTwilioTranscription({config:e,onVoiceTranscription:l,routes:a});return defineChannel({kindHint:`twilio`,turnPolicy:e.turnPolicy,state:{from:null,to:null,lastCallSid:null,lastMessageSid:null},metadata(e){return{from:e.from,lastCallSid:e.lastCallSid??null,lastMessageSid:e.lastMessageSid??null,to:e.to}},context(t,n){return rebuildTwilioContext(t,n,e)},routes:[GET(a.messages,d),POST(a.messages,d),GET(a.voice,f),POST(a.voice,f),GET(a.transcription,p),POST(a.transcription,p)],async receive(n,{from:r}){let i=readNonEmptyString(n.target.phoneNumber);if(!i)throw Error(`twilioChannel().receive requires target.phoneNumber.`);let a=readNonEmptyString(n.target.from)??e.messaging?.from??null;return r(twilioContinuationToken(i,a??void 0)).send(n.message,{auth:n.auth,state:{from:i,lastCallSid:null,lastMessageSid:null,to:a}})},events:u})}function handleTwilioMessages(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioTextMessage(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchText({config:e.config,message:a,onText:e.onText,from:n})),emptyTwilioResponse()):new Response(`forbidden`,{status:403}):emptyTwilioResponse()}}function handleTwilioVoice(e){return async t=>{let n=await verifyTwilioInbound(t,e.config);if(n===null)return new Response(`unauthorized`,{status:401});let r=parseTwilioVoiceCall(n.params);if(!r)return sayTwilioResponse(`Missing caller information.`);if(!await isAllowed(r.from,e.config.allowFrom))return new Response(`forbidden`,{status:403});let i=await acceptVoiceCall({call:r,config:e.config,onVoice:e.onVoice});if(i===null)return new Response(`forbidden`,{status:403});let a=i??{};return gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),hints:a.hints??e.config.voice?.hints,language:a.language??e.config.voice?.language,profanityFilter:a.profanityFilter??e.config.voice?.profanityFilter,prompt:a.prompt??e.config.voice?.prompt??`Please say your message after the tone.`,speechModel:a.speechModel??e.config.voice?.speechModel,speechTimeout:a.speechTimeout??e.config.voice?.speechTimeout??`auto`,timeoutSeconds:a.timeoutSeconds??e.config.voice?.timeoutSeconds,voice:a.voice??e.config.voice?.voice})}}function handleTwilioTranscription(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioVoiceTranscription(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchVoiceTranscription({config:e.config,onVoiceTranscription:e.onVoiceTranscription,from:n,transcription:a})),sayTwilioResponse(e.config.voice?.acknowledgement??`Thanks. I'll follow up by text.`)):new Response(`forbidden`,{status:403}):gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),language:e.config.voice?.language,prompt:e.config.voice?.prompt??`Please say your message after the tone.`,speechTimeout:e.config.voice?.speechTimeout??`auto`,timeoutSeconds:e.config.voice?.timeoutSeconds})}}function rebuildTwilioContext(e,t,n){return{state:e,twilio:buildTwilioHandle({callSid:e.lastCallSid??void 0,config:n,from:e.from??``,to:e.to??void 0})}}function buildTwilioHandle(e){let t=e.config.api,n=e.config.credentials,r=e.config.messaging?.from??e.to,i=e.config.messaging?.messagingServiceSid,s=e.config.messaging?.statusCallbackUrl;return{callSid:e.callSid,from:e.from,to:e.to,request(e,r){return callTwilioApi({apiBaseUrl:t?.apiBaseUrl,body:r,credentials:n,fetch:t?.fetch,path:e})},sendMessage(a,c){return sendTwilioMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:n,fetch:t?.fetch,from:c?.from??r,messagingServiceSid:c?.messagingServiceSid??i,statusCallbackUrl:c?.statusCallbackUrl??s,to:c?.to??e.from})},updateCall(e,r){return updateTwilioCall({apiBaseUrl:t?.apiBaseUrl,callSid:e,credentials:n,fetch:t?.fetch,twiml:r})}}}function assertAllowFromConfigured(e){if(e?.allowFrom===void 0)throw Error(`twilioChannel requires allowFrom. Use allowFrom: "*" to allow all numbers.`)}async function dispatchText(e){let{message:t}=e,n={twilio:buildTwilioHandle({callSid:void 0,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onText(n,t)}catch(e){log.error(`text handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({channel:`text`,from:t.from,messageSid:t.messageSid,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.body,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:null,lastMessageSid:t.messageSid??null,to:t.to??null},title:r.title})}catch(e){log.error(`text delivery failed`,{error:e})}}async function acceptVoiceCall(e){let{call:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})};try{return await e.onVoice(n,t)}catch(e){return log.error(`voice handler failed`,{error:e}),null}}async function dispatchVoiceTranscription(e){let{transcription:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onVoiceTranscription(n,t)}catch(e){log.error(`voice transcription handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({callSid:t.callSid,channel:`voice`,from:t.from,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.text,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:t.callSid??null,lastMessageSid:null,to:t.to??null},title:r.title})}catch(e){log.error(`voice transcription delivery failed`,{error:e})}}async function isAllowed(e,t){let n=typeof t==`function`?await t():t;return n===`*`?!0:typeof n==`string`?n===e:n.includes(e)}export{twilioChannel};
1
+ import{createLogger}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/twilio/verify.js";import{callTwilioApi,sendTwilioMessage,twilioContinuationToken,updateTwilioCall}from"#public/channels/twilio/api.js";import{emptyTwilioResponse,gatherSpeechTwilioResponse,sayTwilioResponse}from"#public/channels/twilio/twiml.js";import{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription}from"#public/channels/twilio/defaults.js";import{formatTwilioContextBlock,parseTwilioTextMessage,parseTwilioVoiceCall,parseTwilioVoiceTranscription}from"#public/channels/twilio/inbound.js";import{buildTwilioActionUrl,buildTwilioRoutes,verifyTwilioInbound}from"#public/channels/twilio/routing.js";const log=createLogger(`twilio.channel`);function twilioChannel(e){assertAllowFromConfigured(e);let a=buildTwilioRoutes(e.route??`/eve/v1/twilio`),o=e.onText??defaultOnText,c=e.onVoice??defaultOnVoice,l=e.onVoiceTranscription??defaultOnVoiceTranscription,u={...defaultEvents,...e.events},d=handleTwilioMessages({config:e,onText:o}),f=handleTwilioVoice({config:e,onVoice:c,routes:a}),p=handleTwilioTranscription({config:e,onVoiceTranscription:l,routes:a});return defineChannel({kindHint:`twilio`,turnPolicy:e.turnPolicy,state:{from:null,to:null,lastCallSid:null,lastMessageSid:null},metadata(e){return{audience:`private`,from:e.from,lastCallSid:e.lastCallSid??null,lastMessageSid:e.lastMessageSid??null,to:e.to}},context(t,n){return rebuildTwilioContext(t,n,e)},routes:[GET(a.messages,d),POST(a.messages,d),GET(a.voice,f),POST(a.voice,f),GET(a.transcription,p),POST(a.transcription,p)],async receive(n,{from:r}){let i=readNonEmptyString(n.target.phoneNumber);if(!i)throw Error(`twilioChannel().receive requires target.phoneNumber.`);let a=readNonEmptyString(n.target.from)??e.messaging?.from??null;return r(twilioContinuationToken(i,a??void 0)).send(n.message,{auth:n.auth,state:{from:i,lastCallSid:null,lastMessageSid:null,to:a}})},events:u})}function handleTwilioMessages(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioTextMessage(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchText({config:e.config,message:a,onText:e.onText,from:n})),emptyTwilioResponse()):new Response(`forbidden`,{status:403}):emptyTwilioResponse()}}function handleTwilioVoice(e){return async t=>{let n=await verifyTwilioInbound(t,e.config);if(n===null)return new Response(`unauthorized`,{status:401});let r=parseTwilioVoiceCall(n.params);if(!r)return sayTwilioResponse(`Missing caller information.`);if(!await isAllowed(r.from,e.config.allowFrom))return new Response(`forbidden`,{status:403});let i=await acceptVoiceCall({call:r,config:e.config,onVoice:e.onVoice});if(i===null)return new Response(`forbidden`,{status:403});let a=i??{};return gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),hints:a.hints??e.config.voice?.hints,language:a.language??e.config.voice?.language,profanityFilter:a.profanityFilter??e.config.voice?.profanityFilter,prompt:a.prompt??e.config.voice?.prompt??`Please say your message after the tone.`,speechModel:a.speechModel??e.config.voice?.speechModel,speechTimeout:a.speechTimeout??e.config.voice?.speechTimeout??`auto`,timeoutSeconds:a.timeoutSeconds??e.config.voice?.timeoutSeconds,voice:a.voice??e.config.voice?.voice})}}function handleTwilioTranscription(e){return async(t,{from:n,waitUntil:r})=>{let i=await verifyTwilioInbound(t,e.config);if(i===null)return new Response(`unauthorized`,{status:401});let a=parseTwilioVoiceTranscription(i.params);return a?await isAllowed(a.from,e.config.allowFrom)?(r(dispatchVoiceTranscription({config:e.config,onVoiceTranscription:e.onVoiceTranscription,from:n,transcription:a})),sayTwilioResponse(e.config.voice?.acknowledgement??`Thanks. I'll follow up by text.`)):new Response(`forbidden`,{status:403}):gatherSpeechTwilioResponse({actionUrl:await buildTwilioActionUrl(t,e.config,e.routes.transcription),language:e.config.voice?.language,prompt:e.config.voice?.prompt??`Please say your message after the tone.`,speechTimeout:e.config.voice?.speechTimeout??`auto`,timeoutSeconds:e.config.voice?.timeoutSeconds})}}function rebuildTwilioContext(e,t,n){return{state:e,twilio:buildTwilioHandle({callSid:e.lastCallSid??void 0,config:n,from:e.from??``,to:e.to??void 0})}}function buildTwilioHandle(e){let t=e.config.api,n=e.config.credentials,r=e.config.messaging?.from??e.to,i=e.config.messaging?.messagingServiceSid,s=e.config.messaging?.statusCallbackUrl;return{callSid:e.callSid,from:e.from,to:e.to,request(e,r){return callTwilioApi({apiBaseUrl:t?.apiBaseUrl,body:r,credentials:n,fetch:t?.fetch,path:e})},sendMessage(a,c){return sendTwilioMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:n,fetch:t?.fetch,from:c?.from??r,messagingServiceSid:c?.messagingServiceSid??i,statusCallbackUrl:c?.statusCallbackUrl??s,to:c?.to??e.from})},updateCall(e,r){return updateTwilioCall({apiBaseUrl:t?.apiBaseUrl,callSid:e,credentials:n,fetch:t?.fetch,twiml:r})}}}function assertAllowFromConfigured(e){if(e?.allowFrom===void 0)throw Error(`twilioChannel requires allowFrom. Use allowFrom: "*" to allow all numbers.`)}async function dispatchText(e){let{message:t}=e,n={twilio:buildTwilioHandle({callSid:void 0,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onText(n,t)}catch(e){log.error(`text handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({channel:`text`,from:t.from,messageSid:t.messageSid,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.body,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:null,lastMessageSid:t.messageSid??null,to:t.to??null},title:r.title})}catch(e){log.error(`text delivery failed`,{error:e})}}async function acceptVoiceCall(e){let{call:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})};try{return await e.onVoice(n,t)}catch(e){return log.error(`voice handler failed`,{error:e}),null}}async function dispatchVoiceTranscription(e){let{transcription:t}=e,n={twilio:buildTwilioHandle({callSid:t.callSid,config:e.config,from:t.from,to:t.to})},r;try{r=await e.onVoiceTranscription(n,t)}catch(e){log.error(`voice transcription handler failed`,{error:e});return}if(r==null)return;let i=formatTwilioContextBlock({callSid:t.callSid,channel:`voice`,from:t.from,to:t.to});try{await e.from(twilioContinuationToken(t.from,t.to)).send(t.text,{auth:r.auth,context:[i],state:{from:t.from,lastCallSid:t.callSid??null,lastMessageSid:null,to:t.to??null},title:r.title})}catch(e){log.error(`voice transcription delivery failed`,{error:e})}}async function isAllowed(e,t){let n=typeof t==`function`?await t():t;return n===`*`?!0:typeof n==`string`?n===e:n.includes(e)}export{twilioChannel};
@@ -10,6 +10,7 @@ import type { GenericChannelDefinition, GenericReceiveInput } from "#shared/chan
10
10
  declare const CHANNEL_METADATA_TYPE: unique symbol;
11
11
  export type { CancelTurnResult, ClearSessionResult, CompactSessionResult, GetEventStreamOptions, ResetSessionResult, SessionCallback, TurnPolicy, } from "#channel/types.js";
12
12
  export type { Session, SessionHandle } from "#channel/session.js";
13
+ export type { ChannelAudience, ChannelAudienceMetadata } from "#shared/channel-audience.js";
13
14
  export type { SessionRespondOptions, SessionSendOptions } from "#channel/session.js";
14
15
  export type { ChannelFrom, ChannelReceiveContext, ChannelResolveSession, ChannelRespondOptions, ChannelSendOptions, ChannelSource, };
15
16
  export type { ChannelCors, ChannelCorsOptions } from "#channel/cors.js";
@@ -21,11 +21,13 @@ export interface RemoteAgentDefinition {
21
21
  readonly description: string;
22
22
  /**
23
23
  * Forwards the dispatching turn's session principal to the remote
24
- * deployment as the `forwardedPrincipal` create-session body field, so the
25
- * remote session runs as the same end user as the parent (per-user
26
- * Connect, local subagents, and further remote hops all see that
27
- * principal). Defaults to `false` — forwarding identity to another
28
- * deployment is an explicit decision, never ambient.
24
+ * deployment as the `forwardedPrincipal` session-request body field, so
25
+ * each remote turn runs as the same end user as the parent (per-user
26
+ * Connect, local subagents, and further remote hops all see that active
27
+ * principal). Session creation forwards current and initiator identity;
28
+ * continuation forwards only the active caller and leaves the remote
29
+ * session's initiator pinned. Defaults to `false` — forwarding identity to
30
+ * another deployment is an explicit decision, never ambient.
29
31
  *
30
32
  * Only principal metadata crosses the wire, never tokens or credentials —
31
33
  * {@link auth} keeps authenticating *this* deployment to the remote. The
@@ -3,12 +3,14 @@ import type { PublicToolDefinition, ToolModelOutput } from "#shared/tool-definit
3
3
  import type { SessionContext } from "#public/definitions/callback-context.js";
4
4
  import type { Approval } from "#public/definitions/approval.js";
5
5
  import type { JsonObject } from "#shared/json.js";
6
+ import type { TaskDelegated, TaskExec, TaskReceipt } from "#shared/tool-task.js";
6
7
  import type { AuthorizationDefinition, ConnectionAuthorizationContext, NonInteractiveAuthorizationDefinition, TokenResult } from "#runtime/connections/types.js";
7
8
  import { type DynamicEvents, type DynamicSentinel } from "#shared/dynamic-tool-definition.js";
8
9
  type ApprovalContextInput<TInput> = unknown extends TInput ? Record<string, unknown> : TInput;
9
10
  type DynamicEventMapHandler<TEvents extends DynamicEvents> = Extract<NonNullable<TEvents[keyof TEvents]>, (...args: never[]) => unknown>;
10
11
  type DynamicEventMapResult<TEvents extends DynamicEvents> = Awaited<ReturnType<DynamicEventMapHandler<TEvents>>>;
11
12
  export type { ToolModelOutput, ToolModelOutputPart } from "#shared/tool-definition.js";
13
+ export type { TaskBinding, TaskDelegated, TaskExec, TaskExecutorBinding, TaskReceipt, TaskSendCommand, } from "#shared/tool-task.js";
12
14
  /**
13
15
  * Authorization provider passed to {@link ToolContext.getToken} or
14
16
  * {@link ToolContext.requireAuth}. Accepts the same shapes as a connection's
@@ -88,6 +90,7 @@ export type ToolContext = SessionContext & {
88
90
  * Authored definitions have no `name` field; identity is path-derived.
89
91
  */
90
92
  export interface ToolDefinition<TInput = unknown, TOutput = unknown> extends PublicToolDefinition<TInput, TOutput> {
93
+ readonly execution?: never;
91
94
  execute(input: TInput, ctx: ToolContext): Promise<TOutput> | TOutput | AsyncIterable<TOutput>;
92
95
  /**
93
96
  * Optional per-tool approval gate. The return value determines whether
@@ -110,10 +113,21 @@ export interface ToolDefinition<TInput = unknown, TOutput = unknown> extends Pub
110
113
  */
111
114
  toModelOutput?: (output: TOutput) => ToolModelOutput | Promise<ToolModelOutput>;
112
115
  }
116
+ /** A tool whose executor can outlive the model tool-call phase as a durable task. */
117
+ export interface BackgroundToolDefinition<TInput = unknown, TOutput = unknown> extends PublicToolDefinition<TInput, TOutput> {
118
+ readonly execution: "background";
119
+ execute(input: TInput, ctx: ToolContext, task: TaskExec): Promise<TaskDelegated | TOutput> | TaskDelegated | TOutput;
120
+ approval?: Approval<ApprovalContextInput<TInput>>;
121
+ toModelOutput?: (output: TOutput) => ToolModelOutput | Promise<ToolModelOutput>;
122
+ }
113
123
  type ToolOutputFromExecuteReturn<TReturn> = TReturn extends Promise<infer TOutput> ? TOutput : TReturn extends AsyncIterable<infer TOutput> ? TOutput : TReturn;
124
+ type BackgroundToolOutputFromExecuteReturn<TReturn> = ToolOutputFromExecuteReturn<TReturn> extends infer TOutput ? TOutput extends TaskDelegated<infer TData> ? TaskReceipt<TData> : TOutput : never;
114
125
  type ToolDefinitionWithExecuteReturn<TInput, TOutput, TReturn> = ToolDefinition<TInput, TOutput> & {
115
126
  execute(input: TInput, ctx: ToolContext): TReturn;
116
127
  };
128
+ type BackgroundToolDefinitionWithExecuteReturn<TInput, TOutput, TReturn> = BackgroundToolDefinition<TInput, TOutput> & {
129
+ execute(input: TInput, ctx: ToolContext, task: TaskExec): TReturn;
130
+ };
117
131
  /**
118
132
  * Defines a tool configuration, used both for static tools (default export
119
133
  * from `agent/tools/*.ts`) and as the entry wrapper inside `defineDynamic`
@@ -122,6 +136,15 @@ type ToolDefinitionWithExecuteReturn<TInput, TOutput, TReturn> = ToolDefinition<
122
136
  * For static tools, the runtime tool name is the filename slug. `defineTool`
123
137
  * stamps a brand that lifecycle code validates; it rejects raw object literals.
124
138
  */
139
+ export declare function defineTool<TSchema extends StandardSchemaV1<unknown, unknown> | StandardJSONSchemaV1<unknown, unknown>, TReturn>(definition: {
140
+ description: BackgroundToolDefinition<unknown, unknown>["description"];
141
+ execution: "background";
142
+ inputSchema: TSchema;
143
+ outputSchema?: PublicToolDefinition<unknown, BackgroundToolOutputFromExecuteReturn<TReturn>>["outputSchema"];
144
+ execute(input: StandardSchemaV1.InferOutput<TSchema>, ctx: ToolContext, task: TaskExec): TReturn extends AsyncIterable<unknown> ? never : TReturn;
145
+ approval?: BackgroundToolDefinition<StandardSchemaV1.InferOutput<TSchema>, unknown>["approval"];
146
+ toModelOutput?: BackgroundToolDefinition<unknown, BackgroundToolOutputFromExecuteReturn<TReturn>>["toModelOutput"];
147
+ }): BackgroundToolDefinitionWithExecuteReturn<StandardSchemaV1.InferOutput<TSchema>, BackgroundToolOutputFromExecuteReturn<TReturn>, TReturn>;
125
148
  export declare function defineTool<TInputSchema extends StandardSchemaV1<unknown, unknown> | StandardJSONSchemaV1<unknown, unknown>, TOutputSchema extends StandardJSONSchemaV1<unknown, unknown>, TReturn extends Promise<StandardJSONSchemaV1.InferOutput<TOutputSchema>> | StandardJSONSchemaV1.InferOutput<TOutputSchema> | AsyncIterable<StandardJSONSchemaV1.InferOutput<TOutputSchema>>>(definition: {
126
149
  description: ToolDefinition<unknown, unknown>["description"];
127
150
  inputSchema: TInputSchema;
@@ -1 +1 @@
1
- import{DYNAMIC_SENTINEL_KIND,TOOL_BRAND}from"#shared/dynamic-tool-definition.js";import{stampDefinitionKey}from"#public/tool-result-narrowing.js";function defineTool(e){if(e.auth!==void 0)throw Error(`defineTool: The "auth" field is no longer supported. Pass auth providers inline to ctx.getToken(provider) or ctx.requireAuth(provider).`);return Object.assign(e,{[TOOL_BRAND]:!0}),stampDefinitionKey(e,`tool:${e.description}`),e}function defineDynamic(t){let n={kind:DYNAMIC_SENTINEL_KIND,events:t.events};return stampDefinitionKey(n,`dynamic:${Object.keys(t.events).join(`,`)}`),n}const DISABLED_TOOL_SENTINEL_KIND=`eve:disabled-tool`;function disableTool(){return{kind:DISABLED_TOOL_SENTINEL_KIND}}function isDisabledToolSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_TOOL_SENTINEL_KIND}const EXPERIMENTAL_WORKFLOW_TOOL_KIND=`eve:enable-workflow-tool`;function experimental_workflow(e={}){let t={kind:EXPERIMENTAL_WORKFLOW_TOOL_KIND};return e.maxSubagents!==void 0&&(t.maxSubagents=e.maxSubagents),t}function isExperimentalWorkflowToolDefinition(e){return typeof e==`object`&&!!e&&e.kind===EXPERIMENTAL_WORKFLOW_TOOL_KIND}export{defineDynamic,defineTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition};
1
+ import{DYNAMIC_SENTINEL_KIND,TOOL_BRAND}from"#shared/dynamic-tool-definition.js";import{collectDurableDynamicToolCallbacks,stampDurableDynamicToolCallbacks}from"#shared/durable-dynamic-tool-callbacks.js";import{stampDefinitionKey}from"#public/tool-result-narrowing.js";function defineTool(e){if(e.auth!==void 0)throw Error(`defineTool: The "auth" field is no longer supported. Pass auth providers inline to ctx.getToken(provider) or ctx.requireAuth(provider).`);return Object.assign(e,{[TOOL_BRAND]:!0}),stampDurableDynamicToolCallbacks(e,collectDurableDynamicToolCallbacks({approval:e.approval,execute:e.execute,toModelOutput:e.toModelOutput})),stampDefinitionKey(e,`tool:${e.description}`),e}function defineDynamic(t){let n={kind:DYNAMIC_SENTINEL_KIND,events:t.events};return stampDefinitionKey(n,`dynamic:${Object.keys(t.events).join(`,`)}`),n}const DISABLED_TOOL_SENTINEL_KIND=`eve:disabled-tool`;function disableTool(){return{kind:DISABLED_TOOL_SENTINEL_KIND}}function isDisabledToolSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_TOOL_SENTINEL_KIND}const EXPERIMENTAL_WORKFLOW_TOOL_KIND=`eve:enable-workflow-tool`;function experimental_workflow(e={}){let t={kind:EXPERIMENTAL_WORKFLOW_TOOL_KIND};return e.maxSubagents!==void 0&&(t.maxSubagents=e.maxSubagents),t}function isExperimentalWorkflowToolDefinition(e){return typeof e==`object`&&!!e&&e.kind===EXPERIMENTAL_WORKFLOW_TOOL_KIND}export{defineDynamic,defineTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition};
@@ -8,25 +8,21 @@
8
8
  * Reachable only with `experimental.instrumentationProviders` on. With the flag
9
9
  * off nothing discovers that directory, so these compile but never run.
10
10
  */
11
- import { type ContentOptions, type OtelIntegration } from "#tracing/otel-declaration.js";
12
- export { isOtelDeclaration, isOtelIntegration, otel, otelIntegration, type ContentOptions, type OtelDeclaration, type OtelIntegration, type OtelIntegrationOptions, type OtelOptions, } from "#tracing/otel-declaration.js";
11
+ import { type ManagedTraceOptions, type OtelIntegration } from "#tracing/otel-declaration.js";
12
+ export { isOtelDeclaration, isOtelIntegration, otel, otelIntegration, composeSpanExportPolicies, redactSpanInputs, redactSpanOutputs, type ContentOptions, type OtelDeclaration, type OtelIntegration, type OtelIntegrationOptions, type OtelOptions, type ManagedTraceOptions, type SpanAttributeDecision, type SpanExportAttributeValue, type SpanExportContext, type SpanExportPolicy, type SpanExportPredicate, type TraceCaptureContext, type TraceCapturePolicy, } from "#tracing/otel-declaration.js";
13
13
  export type { SpanExporter, SpanProcessor } from "#compiled/@vercel/otel/index.js";
14
14
  /**
15
15
  * Vercel Agent Runs, enabled by default in production.
16
16
  *
17
- * Export it from `agent/instrumentation/agent-runs.ts` to configure content
18
- * capture, or export `disableInstrumentation()` from that file to turn it off.
17
+ * Export it from `agent/instrumentation/agent-runs.ts` to configure export, or
18
+ * export `disableInstrumentation()` from that file to turn it off.
19
19
  */
20
- export declare function agentRuns(options?: ContentOptions): OtelIntegration;
20
+ export declare function agentRuns(options?: ManagedTraceOptions): OtelIntegration;
21
21
  /**
22
22
  * The local trace spool `eve dev` reads, as a destination.
23
23
  *
24
24
  * Export it from `agent/instrumentation/local.ts` to keep it alongside a hosted
25
25
  * backend, or export `disableInstrumentation()` from that file to turn it off.
26
26
  * Omitting the file leaves eve's default in place.
27
- *
28
- * `EVE_TRACES_CONTENT=on` opts the default local spool into content capture.
29
- * `off` overrides this destination and no other, so declining content locally
30
- * leaves what a hosted backend receives alone.
31
27
  */
32
- export declare function localTraces(options?: ContentOptions): OtelIntegration;
28
+ export declare function localTraces(options?: ManagedTraceOptions): OtelIntegration;
@@ -1 +1 @@
1
- import{agentRunsIntegration,isOtelDeclaration,isOtelIntegration,otel,otelIntegration,otelIntegration as otelIntegration$1}from"#tracing/otel-declaration.js";import{createLocalTracesProcessor,resolveLocalTracesContent}from"#tracing/local-traces.js";function agentRuns(t={}){return agentRunsIntegration(t)}function localTraces(e={}){return otelIntegration$1({...resolveLocalTracesContent(e),spanProcessors:[createLocalTracesProcessor()]})}export{agentRuns,isOtelDeclaration,isOtelIntegration,localTraces,otel,otelIntegration};
1
+ import{agentRunsIntegration,composeSpanExportPolicies,isOtelDeclaration,isOtelIntegration,managedOtelIntegration,otel,otelIntegration,redactSpanInputs,redactSpanOutputs}from"#tracing/otel-declaration.js";import{createLocalTracesProcessor,resolveLocalTracesContent}from"#tracing/local-traces.js";function agentRuns(t={}){return agentRunsIntegration(t)}function localTraces(e={}){return managedOtelIntegration({...e,...resolveLocalTracesContent(e),spanProcessors:[createLocalTracesProcessor()]})}export{agentRuns,composeSpanExportPolicies,isOtelDeclaration,isOtelIntegration,localTraces,otel,otelIntegration,redactSpanInputs,redactSpanOutputs};
@@ -1 +1 @@
1
- function always(){return()=>`user-approval`}function never(){return()=>`not-applicable`}function once(){return({approvedTools:e,toolName:t})=>e.has(t)?`not-applicable`:`user-approval`}export{always,never,once};
1
+ import{registerDurableDynamicCallback,stampDurableDynamicCallback}from"#shared/durable-dynamic-tool-callbacks.js";const ALWAYS_STEP_ID=`eve:dynamic-tool-helper//approval/always/v1`,NEVER_STEP_ID=`eve:dynamic-tool-helper//approval/never/v1`,ONCE_STEP_ID=`eve:dynamic-tool-helper//approval/once/v1`;function alwaysApproval(e){return`user-approval`}function neverApproval(e){return`not-applicable`}function onceApproval(e,t){return t.approvedTools.has(t.toolName)?`not-applicable`:`user-approval`}registerDurableDynamicCallback(ALWAYS_STEP_ID,alwaysApproval),registerDurableDynamicCallback(NEVER_STEP_ID,neverApproval),registerDurableDynamicCallback(ONCE_STEP_ID,onceApproval);function always(){return stampDurableDynamicCallback(()=>`user-approval`,{closure:{},stepId:ALWAYS_STEP_ID})}function never(){return stampDurableDynamicCallback(()=>`not-applicable`,{closure:{},stepId:NEVER_STEP_ID})}function once(){return stampDurableDynamicCallback(({approvedTools:e,toolName:t})=>e.has(t)?`not-applicable`:`user-approval`,{closure:{},stepId:ONCE_STEP_ID})}export{always,never,once};
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tool authoring helpers for `agent/tools/*.ts` files.
3
3
  */
4
- export { type DisabledToolSentinel, type ExperimentalWorkflowToolDefinition, type ExperimentalWorkflowToolInput, defineDynamic, defineTool, disableTool, experimental_workflow, isDisabledToolSentinel, isExperimentalWorkflowToolDefinition, type ToolAuthOptions, type ToolAuthProvider, type ToolDefinition, type ToolContext, type ToolModelOutput, type ToolModelOutputPart, } from "#public/definitions/tool.js";
4
+ export { type BackgroundToolDefinition, type DisabledToolSentinel, type ExperimentalWorkflowToolDefinition, type ExperimentalWorkflowToolInput, defineDynamic, defineTool, disableTool, experimental_workflow, isDisabledToolSentinel, isExperimentalWorkflowToolDefinition, type TaskBinding, type TaskDelegated, type TaskExec, type TaskExecutorBinding, type TaskReceipt, type ToolAuthOptions, type ToolAuthProvider, type ToolDefinition, type ToolContext, type ToolModelOutput, type ToolModelOutputPart, } from "#public/definitions/tool.js";
5
5
  export { toolOutput, toolOutputPart } from "#public/tools/output-builders.js";
6
6
  export type { Approval, ApprovalConfiguration, ApprovalContext, ApprovalPolicy, ApprovalRequest, ApprovalResponse, ApprovalResponseAuth, ApprovalResponseContext, ApprovalResponseDecision, ApprovalResponsePolicy, ApprovalResponseSession, ApprovalStatus, } from "#public/definitions/approval.js";
7
7
  export type { DynamicToolEntry, DynamicEvents, DynamicToolEvents, DynamicResolveContext, DynamicSentinel, DynamicToolSet, DynamicToolResult, } from "#shared/dynamic-tool-definition.js";
@@ -1,2 +1,2 @@
1
- import{createLogger}from"#internal/logging.js";import{z}from"#compiled/zod/index.js";import{toError}from"#shared/errors.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{ConnectionAuthorizationFailedError,isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{consumeAuthorizationResult,createAuthorizationAttempt,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{resolveAuthorizationCallbackUrl,stampChallengeDisplayName}from"#runtime/connections/scoped-authorization.js";import{defineDynamic,defineTool}from"#public/definitions/tool.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";var __eveStepRegistrySym=Symbol.for(`@workflow/core//registeredSteps`);globalThis[__eveStepRegistrySym]||(globalThis[__eveStepRegistrySym]=new Map);var __eveStepRegistry=globalThis[__eveStepRegistrySym];const logger=createLogger(`framework.connection-search-dynamic`),CONNECTION_SEARCH_INPUT_SCHEMA=z.strictObject({connection:z.string().describe(`Optional: limit search to a specific connection name.`).optional(),keywords:z.string().describe(`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`),limit:z.number().describe(`Max results to return. Default 10.`).optional()}),connectionSchema=z.looseObject({}),CONNECTION_SEARCH_RESULT_ITEM_SCHEMA=z.strictObject({connection:z.string(),description:z.string(),error:z.string().optional(),inputSchema:connectionSchema.optional(),needsAuthorization:z.boolean().optional(),outputSchema:connectionSchema.optional(),qualifiedName:z.string().optional(),tool:z.string().optional()}),CONNECTION_SEARCH_OUTPUT_SCHEMA=z.array(CONNECTION_SEARCH_RESULT_ITEM_SCHEMA),ConnectionSearchResultsKey=new ContextKey(`eve.connectionSearchResults`);function qualifiedConnectionToolName(e,t){return`${e}__${t}`}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}async function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n===void 0)return;let r=await resolveConnectionAuthorization(n);if(supportsInteractiveAuthorization(r))return r}async function completePendingAuthorizations(e,t){let n=loadContext(),i=new Set;for(let r of t){let t=consumeAuthorizationResult(r.connectionName);if(!t)continue;let a=await resolveInteractiveAuth(e,r.connectionName);if(!a)continue;let o=t.principal??resolveConnectionPrincipal(r.connectionName,a),s=await a.completeAuthorization({callbackUrl:t.hookUrl,connection:{url:r.url??``},principal:o,resume:t.resume,callback:t.callback});writeCachedToken(n,r.connectionName,principalKey(o),s),i.add(r.connectionName)}return i}async function executeConnectionSearch(e){let t=loadContext(),i=t.get(ConnectionRegistryKey);if(i===void 0)return[];let o=e.limit??10,l=tokenize(e.keywords),d=[],f=[],p=e.connection!==void 0&&e.connection!==``?i.getConnections().filter(t=>t.connectionName===e.connection):i.getConnections();if(e.connection&&p.length===0)throw Error(`Connection "${e.connection}" is not registered. Available connections: ${i.getConnectionNames().join(`, `)}.`);let m=await completePendingAuthorizations(i,p),h=[];for(let e of p){let t;try{t=await i.getClient(e.connectionName).getToolMetadata()}catch(t){if(isConnectionAuthorizationRequiredError(t)){if(m.has(e.connectionName)){logger.warn(`connection still unauthorized after authorization`,{connection:e.connectionName}),f.push({connection:e.connectionName,description:e.description,error:`Authorization for "${e.connectionName}" did not take effect; the token was rejected after sign-in.`});continue}let t=await resolveInteractiveAuth(i,e.connectionName);if(t){let r=createAuthorizationAttempt(e.connectionName);if(r){let i=resolveConnectionPrincipal(e.connectionName,t),a=resolveAuthorizationCallbackUrl({authorization:t,callbackUrl:r.hookUrl});try{let{challenge:n,resume:o}=await t.startAuthorization({callbackUrl:a,connection:{url:e.url??``},principal:i});h.push({attemptId:r.attemptId,name:e.connectionName,challenge:stampChallengeDisplayName(n,t),hookUrl:a,principal:i,resume:o})}catch(t){let r=toError(t);logger.warn(`startAuthorization failed`,{connection:e.connectionName,error:r}),f.push({connection:e.connectionName,description:e.description,error:`Failed to start authorization for "${e.connectionName}": ${r.message}`});continue}}}f.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(t)){logger.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),f.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let r=toError(t);logger.warn(`failed to load connection tools`,{connection:e.connectionName,error:r}),f.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${r.message}`});continue}for(let n of t){let t=scoreMatch(l,n);t>0&&d.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,outputSchema:n.outputSchema,qualifiedName:qualifiedConnectionToolName(e.connectionName,n.name),tool:n.name},score:t})}}if(h.length>0)return requestAuthorization(h);let g=f.filter(e=>e.error!==void 0);if(p.length>0&&g.length===p.length)throw Error(g.map(e=>e.error).join(`
2
- `));d.sort((e,t)=>t.score-e.score);let _=d.slice(0,o).map(e=>e.item);if(_.length>0){let e=[..._,...f],n=t.get(ConnectionSearchResultsKey)??[],r=new Map(n.map(e=>[e.qualifiedName,e]));for(let e of _)e.qualifiedName&&r.set(e.qualifiedName,e);return t.set(ConnectionSearchResultsKey,[...r.values()]),e}return p.map(e=>f.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function extractDiscoveredTools(e){let t=new Map;for(let n of e){if(n.role!==`tool`)continue;let e=n.content;for(let n of e){if(n.type!==`tool-result`||n.toolName!==`connection_search`)continue;let e=n.output;if(e==null)continue;let r=typeof e==`object`&&`type`in e&&`value`in e?e.value:e;if(Array.isArray(r))for(let e of r)e.tool&&e.qualifiedName&&t.set(e.qualifiedName,e)}}return[...t.values()]}const connectionSearchDynamicDefinition=defineDynamic({events:{"step.started":async(e,t)=>{let n=loadContext().get(ConnectionRegistryKey);if(!n||n.getConnections().length===0)return null;let i=n.getConnections().map(e=>e.connectionName),o=extractDiscoveredTools(t.messages),s=loadContext().get(ConnectionSearchResultsKey)??[],c=new Map;for(let e of s)e.qualifiedName&&c.set(e.qualifiedName,e);for(let e of o)e.qualifiedName&&c.set(e.qualifiedName,e);let l=[...c.values()],u={};u.connection_search=defineTool({description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. \`linear__list_issues\`) in your next response. Available connections: ${i.join(`, `)}.`,inputSchema:CONNECTION_SEARCH_INPUT_SCHEMA,execute:async e=>await __eve_dynamic_exec_0({},e),__executeStepFn:__eve_dynamic_exec_0,__closureVars:{},outputSchema:CONNECTION_SEARCH_OUTPUT_SCHEMA});for(let e of l){let r=e.connection,i=e.tool,a=n.getConnectionApproval(r);u[qualifiedConnectionToolName(r,i)]=defineTool({description:e.description,inputSchema:e.inputSchema??{type:`object`},approval:a,outputSchema:e.outputSchema,execute:async(e,n)=>await __eve_dynamic_exec_1({ctx:t,connectionName:r,toolName:i},e,n),__executeStepFn:__eve_dynamic_exec_1,__closureVars:{ctx:t,connectionName:r,toolName:i}})}return u}}});async function __eve_dynamic_exec_0(e,t){return executeConnectionSearch(t)}async function __eve_dynamic_exec_1(e,t,n){let{ctx:i,connectionName:s,toolName:d}=e,f=loadContext().get(ConnectionRegistryKey),p=f.getConnections().find(e=>e.connectionName===s),m=await resolveInteractiveAuth(f,s),_=!1;if(m){let e=consumeAuthorizationResult(s);if(e){_=!0;let t=loadContext(),n=e.principal??resolveConnectionPrincipal(s,m),i=await m.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:p?.url??``},principal:n,resume:e.resume,callback:e.callback});writeCachedToken(t,s,principalKey(n),i)}}try{return await f.getClient(s).executeTool(d,t,{abortSignal:n.abortSignal})}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!m)throw e;if(_)throw new ConnectionAuthorizationFailedError(s,{retryable:!1,reason:`token_rejected_after_authorization`,message:`Connection "${s}" rejected the token immediately after authorization.`});let t=createAuthorizationAttempt(s);if(!t)throw e;let n=resolveConnectionPrincipal(s,m),r=resolveAuthorizationCallbackUrl({authorization:m,callbackUrl:t.hookUrl}),{challenge:i,resume:a}=await m.startAuthorization({callbackUrl:r,connection:{url:p?.url??``},principal:n});return requestAuthorization([{attemptId:t.attemptId,name:s,challenge:stampChallengeDisplayName(i,m),hookUrl:r,principal:n,resume:a}])}}__eve_dynamic_exec_0.stepId=`eve:dynamic-tool//__eve_dynamic_exec_0`,__eveStepRegistry.set(`eve:dynamic-tool//__eve_dynamic_exec_0`,__eve_dynamic_exec_0),__eve_dynamic_exec_1.stepId=`eve:dynamic-tool//__eve_dynamic_exec_1`,__eveStepRegistry.set(`eve:dynamic-tool//__eve_dynamic_exec_1`,__eve_dynamic_exec_1);export{connectionSearchDynamicDefinition as default,extractDiscoveredTools};
1
+ import{createLogger}from"#internal/logging.js";import{z}from"#compiled/zod/index.js";import{toError}from"#shared/errors.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{registerDurableDynamicCallback,stampDurableDynamicToolCallbacks}from"#shared/durable-dynamic-tool-callbacks.js";import{ConnectionRegistryKey}from"#context/providers/connection-key.js";import{consumeAuthorizationResult,createAuthorizationAttempt,requestAuthorization}from"#harness/authorization.js";import{ConnectionAuthorizationFailedError,isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{resolveAuthorizationCallbackUrl,stampChallengeDisplayName}from"#runtime/connections/scoped-authorization.js";import{resolveApprovalPolicy}from"#public/definitions/approval.js";import{defineDynamic,defineTool}from"#public/definitions/tool.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";const logger=createLogger(`framework.connection-search-dynamic`),CONNECTION_SEARCH_INPUT_SCHEMA=z.strictObject({connection:z.string().describe(`Optional: limit search to a specific connection name.`).optional(),keywords:z.string().describe(`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`),limit:z.number().describe(`Max results to return. Default 10.`).optional()}),connectionSchema=z.looseObject({}),CONNECTION_SEARCH_RESULT_ITEM_SCHEMA=z.strictObject({connection:z.string(),description:z.string(),error:z.string().optional(),inputSchema:connectionSchema.optional(),needsAuthorization:z.boolean().optional(),outputSchema:connectionSchema.optional(),qualifiedName:z.string().optional(),tool:z.string().optional()}),CONNECTION_SEARCH_OUTPUT_SCHEMA=z.array(CONNECTION_SEARCH_RESULT_ITEM_SCHEMA),ConnectionSearchResultsKey=new ContextKey(`eve.connectionSearchResults`);function qualifiedConnectionToolName(e,t){return`${e}__${t}`}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}async function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n===void 0)return;let r=await resolveConnectionAuthorization(n);if(supportsInteractiveAuthorization(r))return r}async function completePendingAuthorizations(e,t){let n=loadContext(),i=new Set;for(let r of t){let t=consumeAuthorizationResult(r.connectionName);if(!t)continue;let a=await resolveInteractiveAuth(e,r.connectionName);if(!a)continue;let o=t.principal??resolveConnectionPrincipal(r.connectionName,a),s=await a.completeAuthorization({callbackUrl:t.hookUrl,connection:{url:r.url??``},principal:o,resume:t.resume,callback:t.callback});writeCachedToken(n,r.connectionName,principalKey(o),s),i.add(r.connectionName)}return i}async function executeConnectionSearch(e){let t=loadContext(),i=t.get(ConnectionRegistryKey);if(i===void 0)return[];let a=e.limit??10,o=tokenize(e.keywords),c=[],d=[],p=e.connection!==void 0&&e.connection!==``?i.getConnections().filter(t=>t.connectionName===e.connection):i.getConnections();if(e.connection&&p.length===0)throw Error(`Connection "${e.connection}" is not registered. Available connections: ${i.getConnectionNames().join(`, `)}.`);let m=await completePendingAuthorizations(i,p),h=[];for(let e of p){let t;try{t=await i.getClient(e.connectionName).getToolMetadata()}catch(t){if(isConnectionAuthorizationRequiredError(t)){if(m.has(e.connectionName)){logger.warn(`connection still unauthorized after authorization`,{connection:e.connectionName}),d.push({connection:e.connectionName,description:e.description,error:`Authorization for "${e.connectionName}" did not take effect; the token was rejected after sign-in.`});continue}let t=await resolveInteractiveAuth(i,e.connectionName);if(t){let r=createAuthorizationAttempt(e.connectionName);if(r){let i=resolveConnectionPrincipal(e.connectionName,t),a=resolveAuthorizationCallbackUrl({authorization:t,callbackUrl:r.hookUrl});try{let{challenge:n,resume:o}=await t.startAuthorization({callbackUrl:a,connection:{url:e.url??``},principal:i});h.push({attemptId:r.attemptId,name:e.connectionName,challenge:stampChallengeDisplayName(n,t),hookUrl:a,principal:i,resume:o})}catch(t){let r=toError(t);logger.warn(`startAuthorization failed`,{connection:e.connectionName,error:r}),d.push({connection:e.connectionName,description:e.description,error:`Failed to start authorization for "${e.connectionName}": ${r.message}`});continue}}}d.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(t)){logger.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),d.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let r=toError(t);logger.warn(`failed to load connection tools`,{connection:e.connectionName,error:r}),d.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${r.message}`});continue}for(let n of t){let t=scoreMatch(o,n);t>0&&c.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,outputSchema:n.outputSchema,qualifiedName:qualifiedConnectionToolName(e.connectionName,n.name),tool:n.name},score:t})}}if(h.length>0)return requestAuthorization(h);let g=d.filter(e=>e.error!==void 0);if(p.length>0&&g.length===p.length)throw Error(g.map(e=>e.error).join(`
2
+ `));c.sort((e,t)=>t.score-e.score);let _=c.slice(0,a).map(e=>e.item);if(_.length>0){let e=[..._,...d],n=t.get(ConnectionSearchResultsKey)??[],r=new Map(n.map(e=>[e.qualifiedName,e]));for(let e of _)e.qualifiedName&&r.set(e.qualifiedName,e);return t.set(ConnectionSearchResultsKey,[...r.values()]),e}return p.map(e=>d.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function extractDiscoveredTools(e){let t=new Map;for(let n of e){if(n.role!==`tool`)continue;let e=n.content;for(let n of e){if(n.type!==`tool-result`||n.toolName!==`connection_search`)continue;let e=n.output;if(e==null)continue;let r=typeof e==`object`&&`type`in e&&`value`in e?e.value:e;if(Array.isArray(r))for(let e of r)e.tool&&e.qualifiedName&&t.set(e.qualifiedName,e)}}return[...t.values()]}const CONNECTION_SEARCH_EXECUTE_STEP_ID=`eve:framework-dynamic//connection-search/execute/v1`,DISCOVERED_TOOL_EXECUTE_STEP_ID=`eve:framework-dynamic//connection-search/discovered-execute/v1`,DISCOVERED_TOOL_APPROVAL_REQUEST_STEP_ID=`eve:framework-dynamic//connection-search/discovered-approval-request/v1`,DISCOVERED_TOOL_APPROVAL_RESPONSE_STEP_ID=`eve:framework-dynamic//connection-search/discovered-approval-response/v1`;function readDiscoveredToolClosure(e){let t=e.connectionName,n=e.toolName;if(typeof t!=`string`||typeof n!=`string`)throw Error(`Discovered connection tool callback metadata is invalid.`);return{connectionName:t,toolName:n}}async function executeDiscoveredConnectionTool(e,t,n){let{connectionName:i,toolName:a}=readDiscoveredToolClosure(e),o=loadContext().get(ConnectionRegistryKey);if(o===void 0)throw Error(`Connection registry is unavailable while replaying a discovered tool.`);let f=o.getConnections().find(e=>e.connectionName===i),p=await resolveInteractiveAuth(o,i),m=!1;if(p){let e=consumeAuthorizationResult(i);if(e){m=!0;let t=loadContext(),n=e.principal??resolveConnectionPrincipal(i,p),a=await p.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:f?.url??``},principal:n,resume:e.resume,callback:e.callback});writeCachedToken(t,i,principalKey(n),a)}}try{return await o.getClient(i).executeTool(a,t,{abortSignal:n.abortSignal})}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!p)throw e;if(m)throw new ConnectionAuthorizationFailedError(i,{retryable:!1,reason:`token_rejected_after_authorization`,message:`Connection "${i}" rejected the token immediately after authorization.`});let t=createAuthorizationAttempt(i);if(!t)throw e;let n=resolveConnectionPrincipal(i,p),r=resolveAuthorizationCallbackUrl({authorization:p,callbackUrl:t.hookUrl}),{challenge:a,resume:o}=await p.startAuthorization({callbackUrl:r,connection:{url:f?.url??``},principal:n});return requestAuthorization([{attemptId:t.attemptId,name:i,challenge:stampChallengeDisplayName(a,p),hookUrl:r,principal:n,resume:o}])}}async function requestDiscoveredConnectionToolApproval(e,t){let{connectionName:n}=readDiscoveredToolClosure(e),i=loadContext().get(ConnectionRegistryKey)?.getConnectionApproval(n);return i===void 0?`not-applicable`:await resolveApprovalPolicy(i)(t)}async function authorizeDiscoveredConnectionToolApproval(e,t){let{connectionName:n}=readDiscoveredToolClosure(e),i=loadContext().get(ConnectionRegistryKey)?.getConnectionApproval(n),a=i===void 0||typeof i==`function`?void 0:i.response;return a===void 0?{reason:`Approval response authorization is unavailable.`,status:`rejected`}:await a(t)}registerDurableDynamicCallback(CONNECTION_SEARCH_EXECUTE_STEP_ID,(e,t)=>executeConnectionSearch(t)),registerDurableDynamicCallback(DISCOVERED_TOOL_EXECUTE_STEP_ID,executeDiscoveredConnectionTool),registerDurableDynamicCallback(DISCOVERED_TOOL_APPROVAL_REQUEST_STEP_ID,requestDiscoveredConnectionToolApproval),registerDurableDynamicCallback(DISCOVERED_TOOL_APPROVAL_RESPONSE_STEP_ID,authorizeDiscoveredConnectionToolApproval);const connectionSearchDynamicDefinition=defineDynamic({events:{"step.started":async(e,t)=>{let n=loadContext().get(ConnectionRegistryKey);if(!n||n.getConnections().length===0)return null;let i=n.getConnections().map(e=>e.connectionName),a=extractDiscoveredTools(t.messages),c=loadContext().get(ConnectionSearchResultsKey)??[],l=new Map;for(let e of c)e.qualifiedName&&l.set(e.qualifiedName,e);for(let e of a)e.qualifiedName&&l.set(e.qualifiedName,e);let u=[...l.values()],d={},f=defineTool({description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. \`linear__list_issues\`) in your next response. Available connections: ${i.join(`, `)}.`,inputSchema:CONNECTION_SEARCH_INPUT_SCHEMA,async execute(e){return executeConnectionSearch(e)},outputSchema:CONNECTION_SEARCH_OUTPUT_SCHEMA});stampDurableDynamicToolCallbacks(f,{execute:{closure:{},stepId:CONNECTION_SEARCH_EXECUTE_STEP_ID}}),d.connection_search=f;for(let e of u){let t=e.connection,r=e.tool,i=n.getConnectionApproval(t),a={connectionName:t,toolName:r},s=defineTool({description:e.description,inputSchema:e.inputSchema??{type:`object`},approval:i,outputSchema:e.outputSchema,async execute(e,t){return await executeDiscoveredConnectionTool(a,e,t)}});stampDurableDynamicToolCallbacks(s,{execute:{closure:a,stepId:DISCOVERED_TOOL_EXECUTE_STEP_ID},...i===void 0?{}:{approvalRequest:{closure:a,stepId:DISCOVERED_TOOL_APPROVAL_REQUEST_STEP_ID}},...i===void 0||typeof i==`function`||i.response===void 0?{}:{approvalResponse:{closure:a,stepId:DISCOVERED_TOOL_APPROVAL_RESPONSE_STEP_ID}}}),d[qualifiedConnectionToolName(t,r)]=s}return d}}});export{connectionSearchDynamicDefinition as default,extractDiscoveredTools};
@@ -0,0 +1,41 @@
1
+ import { type TaskExec, type ToolContext } from "#public/definitions/tool.js";
2
+ interface SubagentDefinitionInput {
3
+ readonly description: string;
4
+ readonly name: string;
5
+ readonly nodeId: string;
6
+ }
7
+ export declare function defineSubagent(input: SubagentDefinitionInput): import("#public/definitions/tool.js").BackgroundToolDefinition<{
8
+ message: string;
9
+ outputSchema?: {
10
+ [x: string]: unknown;
11
+ } | undefined;
12
+ agentId?: string | null | undefined;
13
+ }, import("#public/definitions/tool.js").TaskReceipt<{
14
+ agentId: string;
15
+ }>> & {
16
+ execute(input: {
17
+ message: string;
18
+ outputSchema?: {
19
+ [x: string]: unknown;
20
+ } | undefined;
21
+ agentId?: string | null | undefined;
22
+ }, ctx: ToolContext, task: TaskExec): Promise<import("#public/definitions/tool.js").TaskDelegated<{
23
+ agentId: string;
24
+ }>>;
25
+ };
26
+ export declare function registerLocalSubagentExecutor(execute: object): void;
27
+ export declare function countLocalSubagentCalls(calls: readonly {
28
+ readonly definition: {
29
+ readonly execute: object;
30
+ };
31
+ }[]): number;
32
+ export declare function executeSubagentTool(input: {
33
+ readonly definition: SubagentDefinitionInput;
34
+ readonly kind: "local" | "remote";
35
+ readonly task: TaskExec;
36
+ readonly toolContext: ToolContext;
37
+ readonly toolInput: unknown;
38
+ }): Promise<import("#public/definitions/tool.js").TaskDelegated<{
39
+ agentId: string;
40
+ }>>;
41
+ export {};
@@ -0,0 +1 @@
1
+ import{createLogger,logError}from"#internal/logging.js";import{HandleEventKey}from"#context/keys.js";import{createSubagentCalledEvent}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{loadContext}from"#context/container.js";import{PERSISTENT_SUBAGENT_TOOL_INPUT_SCHEMA}from"#runtime/subagents/registry.js";import{getHarnessEmissionState}from"#harness/emission.js";import{workflowEntryReference}from"#execution/workflow-runtime.js";import{serializeContext}from"#context/serialize.js";import{createDurableSessionState}from"#execution/durable-session-store.js";import{SUBAGENT_TASK_RECEIPT_OUTPUT_SCHEMA}from"#runtime/framework-tools/tasks.js";import{dispatchToTaskAgentAddress}from"#execution/agent-handle-dispatch.js";import{createAgentContinuationBundle}from"#execution/agent-continuation-bundle.js";import{prepareAgentActionDispatch,startSubagent}from"#execution/dispatch-runtime-actions-shared.js";import{activeTurnId}from"#harness/active-turn-id.js";import{createSubagentExecutorBinding}from"#tasks/types.js";import{findTaskAgentAddress}from"#execution/tasks/parent/control-shared.js";import{checkTaskContinuationAvailability,createTaskContinuationBusyResult,describeTaskDispatch}from"#execution/tasks/parent/continuation-dispatch.js";import{CallbackBaseUrlKey}from"#harness/authorization.js";import{defineTool}from"#public/definitions/tool.js";const localSubagentExecutors=new WeakSet,batchAgentClaims=new WeakMap,log=createLogger(`runtime.framework-tools.subagent`);function defineSubagent(e){return defineTool({description:e.description,execution:`background`,inputSchema:PERSISTENT_SUBAGENT_TOOL_INPUT_SCHEMA,outputSchema:SUBAGENT_TASK_RECEIPT_OUTPUT_SCHEMA,execute:(t,n,r)=>executeSubagentTool({definition:e,kind:`local`,task:r,toolContext:n,toolInput:t})})}function registerLocalSubagentExecutor(e){localSubagentExecutors.add(e)}function countLocalSubagentCalls(e){return e.filter(e=>localSubagentExecutors.has(e.definition.execute)).length}async function executeSubagentTool(e){let t=loadContext(),{batch:n,session:r,task:o}=e.task,s=getHarnessEmissionState(r.state),c={callId:e.toolContext.callId,description:e.definition.description,input:parseJsonObject(PERSISTENT_SUBAGENT_TOOL_INPUT_SCHEMA.parse(e.toolInput)),name:e.definition.name,nodeId:e.definition.nodeId},l=await dispatchSubagent({action:e.kind===`remote`?{...c,kind:`remote-agent-call`,remoteAgentName:e.definition.name}:{...c,kind:`subagent-call`,subagentName:e.definition.name},batch:n,callbackBaseUrl:t.get(CallbackBaseUrlKey),ctx:t,event:{...s,turnId:activeTurnId(s)},localFanoutSize:countLocalSubagentCalls(n),serializedContext:serializeContext(t),sessionState:createDurableSessionState({session:r}),task:o}),u=findTaskAgentAddress(l.session,l.agentId);if(u===void 0)throw Error(`Subagent dispatch for "${l.agentId}" recorded no task agent address.`);let d=createSubagentExecutorBinding({address:u.address,identity:u.identity});await emitSubagentCalled$1({callId:e.toolContext.callId,childSessionId:l.address.sessionId,event:{...s,turnId:activeTurnId(s)},name:l.name,remote:l.remote,sessionId:r.sessionId,toolName:e.definition.name});let f=e.task.delegated({executor:d,receipt:{agentId:l.agentId}});return await emitSubagentCompleted({callId:e.toolContext.callId,output:JSON.stringify(f.receipt),subagentName:l.name,taskId:f.receipt.taskId}),f}async function dispatchSubagent(e){let t=await prepareAgentActionDispatch({action:e.action,ctx:e.ctx,event:e.event,localFanoutSize:e.localFanoutSize,serializedContext:e.serializedContext,sessionState:e.sessionState}),n=t.plan[0];if(n===void 0||n.kind===`task-control`)throw Error(`Subagent tool dispatch produced no executable plan entry.`);if(n.kind===`reject`)throw Error(JSON.stringify(n.result.output));if(n.kind===`resume`){let r=await checkTaskContinuationAvailability({action:n.action,agentId:n.agentId,parentStepIndex:e.event.stepIndex,parentTurnId:e.event.turnId,session:t.session});if(r!==void 0)throw Error(JSON.stringify(r.output));let i=claimBatchAgent(e.batch,n.agentId,e.task.taskId);if(i!==void 0){let e=createTaskContinuationBusyResult({action:n.action,agentId:n.agentId,status:`working`,taskId:i});throw Error(JSON.stringify(e.output))}}let r=n.kind===`resume`?await dispatchToTaskAgentAddress({action:n.action,agentId:n.agentId,auth:t.auth,bundle:createAgentContinuationBundle({action:n.action,bundle:t.bundle,dynamicRemoteAgent:n.dynamicRemoteAgent}),currentSession:t.session,parentToken:e.task.taskInboxToken}):await startSubagent({auth:t.auth,batchEvent:e.event,bundle:t.bundle,callbackBaseUrl:e.callbackBaseUrl,capabilities:t.capabilities,channelMetadata:t.channelMetadata,currentSession:t.session,fanoutSize:t.fanoutSize,initiatorAuth:t.initiatorAuth,parentContinuationToken:e.task.taskInboxToken,parentTraceContext:t.parentTraceContext,persistentSessions:!0,sandboxSessionId:t.sandboxSessionId,serializedContext:t.serializedContext,session:t.session,taskOwned:!0,target:n.target});if(r.kind===`error`)throw Error(JSON.stringify(r.result.output));let i=describeTaskDispatch({action:e.action,agentId:n.kind===`resume`?n.agentId:void 0,parentSessionId:t.session.sessionId,parentTurnId:e.event.turnId,session:r.session}),a=n.kind===`resume`?n.dynamicRemoteAgent:n.target.kind===`remote`?n.target.dynamicRemoteAgent:void 0;return{address:r.address,agentId:i.agentId,mode:i.mode,name:i.name,...r.address.kind===`agent/remote`?{remote:{resolverId:a?.credentialsStepId??e.action.nodeId,url:r.address.url}}:{},session:r.session}}function claimBatchAgent(e,t,n){let r=batchAgentClaims.get(e);r===void 0&&(r=new Map,batchAgentClaims.set(e,r));let i=r.get(t);if(i!==void 0)return i;r.set(t,n)}async function emitSubagentCalled$1(e){let i=loadContext().get(HandleEventKey);if(i!==void 0)try{await i(createSubagentCalledEvent({callId:e.callId,childSessionId:e.childSessionId,name:e.name,remote:e.remote,sequence:e.event.sequence,sessionId:e.sessionId,toolName:e.toolName,turnId:e.event.turnId,workflowId:workflowEntryReference.workflowId}))}catch(n){logError(log,`subagent.called emission failed`,n,{callId:e.callId,childSessionId:e.childSessionId,toolName:e.toolName})}}async function emitSubagentCompleted(e){let r=loadContext().get(HandleEventKey);if(r!==void 0)try{await r({data:{backgroundTask:{status:`working`,taskId:e.taskId},callId:e.callId,output:e.output,subagentName:e.subagentName},type:`subagent.completed`})}catch(n){logError(log,`subagent.completed emission failed`,n,{callId:e.callId,taskId:e.taskId})}}export{countLocalSubagentCalls,defineSubagent,executeSubagentTool,registerLocalSubagentExecutor};
@@ -0,0 +1,23 @@
1
+ export declare function defineRemoteSubagent(input: {
2
+ readonly description: string;
3
+ readonly name: string;
4
+ readonly nodeId: string;
5
+ }): import("#public/definitions/tool.js").BackgroundToolDefinition<{
6
+ message: string;
7
+ outputSchema?: {
8
+ [x: string]: unknown;
9
+ } | undefined;
10
+ agentId?: string | null | undefined;
11
+ }, import("#public/definitions/tool.js").TaskReceipt<{
12
+ agentId: string;
13
+ }>> & {
14
+ execute(input: {
15
+ message: string;
16
+ outputSchema?: {
17
+ [x: string]: unknown;
18
+ } | undefined;
19
+ agentId?: string | null | undefined;
20
+ }, ctx: import("#public/definitions/tool.js").ToolContext, task: import("#public/definitions/tool.js").TaskExec): Promise<import("#public/definitions/tool.js").TaskDelegated<{
21
+ agentId: string;
22
+ }>>;
23
+ };
@@ -0,0 +1 @@
1
+ import{PERSISTENT_SUBAGENT_TOOL_INPUT_SCHEMA}from"#runtime/subagents/registry.js";import{SUBAGENT_TASK_RECEIPT_OUTPUT_SCHEMA}from"#runtime/framework-tools/tasks.js";import{executeSubagentTool}from"#runtime/framework-tools/subagent/local.js";import{defineTool}from"#public/definitions/tool.js";function defineRemoteSubagent(r){return defineTool({description:r.description,execution:`background`,inputSchema:PERSISTENT_SUBAGENT_TOOL_INPUT_SCHEMA,outputSchema:SUBAGENT_TASK_RECEIPT_OUTPUT_SCHEMA,execute:(e,t,n)=>executeSubagentTool({definition:r,kind:`remote`,task:n,toolContext:t,toolInput:e})})}export{defineRemoteSubagent};
@@ -32,7 +32,7 @@ export declare const TASK_VIEWS_OUTPUT_SCHEMA: z.ZodObject<{
32
32
  result: "result";
33
33
  }>;
34
34
  }, z.core.$strip>>;
35
- metadata: z.ZodObject<{
35
+ metadata: z.ZodUnion<readonly [z.ZodObject<{
36
36
  agentId: z.ZodString;
37
37
  kind: z.ZodLiteral<"subagent">;
38
38
  mode: z.ZodEnum<{
@@ -40,7 +40,11 @@ export declare const TASK_VIEWS_OUTPUT_SCHEMA: z.ZodObject<{
40
40
  remote: "remote";
41
41
  }>;
42
42
  name: z.ZodString;
43
- }, z.core.$strip>;
43
+ }, z.core.$strip>, z.ZodObject<{
44
+ data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
45
+ kind: z.ZodString;
46
+ name: z.ZodString;
47
+ }, z.core.$strip>]>;
44
48
  status: z.ZodEnum<{
45
49
  cancelled: "cancelled";
46
50
  completed: "completed";
@@ -51,6 +55,11 @@ export declare const TASK_VIEWS_OUTPUT_SCHEMA: z.ZodObject<{
51
55
  taskId: z.ZodString;
52
56
  }, z.core.$strip>>;
53
57
  }, z.core.$strip>;
58
+ export declare const SUBAGENT_TASK_RECEIPT_OUTPUT_SCHEMA: z.ZodObject<{
59
+ agentId: z.ZodString;
60
+ status: z.ZodLiteral<"working">;
61
+ taskId: z.ZodString;
62
+ }, z.core.$strict>;
54
63
  /**
55
64
  * Builds the harness definitions injected when the root agent enables
56
65
  * `experimental.tasks`. Follows the implicit `agent` tool pattern:
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";const TASK_CANCEL_TOOL_NAME=`task_cancel`,TASK_UPDATE_TOOL_NAME=`task_update`,TASK_TOOL_NAMES=new Set([TASK_CANCEL_TOOL_NAME,TASK_UPDATE_TOOL_NAME]),TASK_CONTROL_TOOL_NAMES=new Set([TASK_CANCEL_TOOL_NAME,TASK_UPDATE_TOOL_NAME]),TASK_IDS_SCHEMA=z.array(z.string().min(1)).min(1).describe(`Task ids from earlier subagent task receipts.`),TASK_CANCEL_INPUT_SCHEMA=z.strictObject({taskIds:TASK_IDS_SCHEMA}),TASK_UPDATE_INPUT_SCHEMA=z.strictObject({message:z.string().min(1).describe(`Brief description of what this task is currently doing.`)}),TASK_VIEW_SCHEMA=z.object({inputRequests:z.array(z.unknown()).optional(),lastOutput:z.object({data:z.unknown(),type:z.enum([`result`,`error`])}).optional(),metadata:z.object({agentId:z.string(),kind:z.literal(`subagent`),mode:z.enum([`local`,`remote`]),name:z.string()}),status:z.enum([`working`,`input_required`,`completed`,`failed`,`cancelled`]),taskId:z.string()}),TASK_VIEWS_OUTPUT_SCHEMA=z.object({tasks:z.array(TASK_VIEW_SCHEMA)}),TASK_CANCEL_DESCRIPTION=`Request cooperative cancellation of one or more background tasks. Cancellation is final: a task that finishes after you cancel it stays cancelled. Cancelling an already-finished task changes nothing.`,TASK_UPDATE_DESCRIPTION=`Briefly tell the parent agent what this background task is currently doing. Report activity, not preliminary findings or results.`;function createTaskToolHarnessDefinitions(){return[{description:TASK_CANCEL_DESCRIPTION,inputSchema:TASK_CANCEL_INPUT_SCHEMA,name:TASK_CANCEL_TOOL_NAME,outputSchema:TASK_VIEWS_OUTPUT_SCHEMA,runtimeAction:{kind:`task-control`}},{description:TASK_UPDATE_DESCRIPTION,inputSchema:TASK_UPDATE_INPUT_SCHEMA,name:TASK_UPDATE_TOOL_NAME,runtimeAction:{kind:`task-control`}}]}function isTaskToolAvailable(e){return e.tasksEnabled&&!e.disabledFrameworkTools.includes(e.toolName)&&!e.hasAuthoredTool}function createResolvedTaskToolStub(e){return{description:e.description,inputSchema:null,logicalPath:`eve:framework/${e.name}`,name:e.name,sourceId:`eve:${e.name}-tool`,sourceKind:`module`}}const TASK_TOOL_DEFINITIONS=[createResolvedTaskToolStub({description:TASK_CANCEL_DESCRIPTION,name:TASK_CANCEL_TOOL_NAME}),createResolvedTaskToolStub({description:TASK_UPDATE_DESCRIPTION,name:TASK_UPDATE_TOOL_NAME})];export{TASK_CANCEL_INPUT_SCHEMA,TASK_CANCEL_TOOL_NAME,TASK_CONTROL_TOOL_NAMES,TASK_TOOL_DEFINITIONS,TASK_TOOL_NAMES,TASK_UPDATE_INPUT_SCHEMA,TASK_UPDATE_TOOL_NAME,TASK_VIEWS_OUTPUT_SCHEMA,createTaskToolHarnessDefinitions,isTaskToolAvailable};
1
+ import{z}from"#compiled/zod/index.js";const TASK_CANCEL_TOOL_NAME=`task_cancel`,TASK_UPDATE_TOOL_NAME=`task_update`,TASK_TOOL_NAMES=new Set([TASK_CANCEL_TOOL_NAME,TASK_UPDATE_TOOL_NAME]),TASK_CONTROL_TOOL_NAMES=new Set([TASK_CANCEL_TOOL_NAME,TASK_UPDATE_TOOL_NAME]),TASK_IDS_SCHEMA=z.array(z.string().min(1)).min(1).describe(`Task ids from earlier subagent task receipts.`),TASK_CANCEL_INPUT_SCHEMA=z.strictObject({taskIds:TASK_IDS_SCHEMA}),TASK_UPDATE_INPUT_SCHEMA=z.strictObject({message:z.string().min(1).describe(`Brief description of what this task is currently doing.`)}),TASK_VIEW_SCHEMA=z.object({inputRequests:z.array(z.unknown()).optional(),lastOutput:z.object({data:z.unknown(),type:z.enum([`result`,`error`])}).optional(),metadata:z.union([z.object({agentId:z.string(),kind:z.literal(`subagent`),mode:z.enum([`local`,`remote`]),name:z.string()}),z.object({data:z.record(z.string(),z.unknown()).optional(),kind:z.string(),name:z.string()})]),status:z.enum([`working`,`input_required`,`completed`,`failed`,`cancelled`]),taskId:z.string()}),TASK_VIEWS_OUTPUT_SCHEMA=z.object({tasks:z.array(TASK_VIEW_SCHEMA)}),SUBAGENT_TASK_RECEIPT_OUTPUT_SCHEMA=z.strictObject({agentId:z.string(),status:z.literal(`working`),taskId:z.string()}),TASK_CANCEL_DESCRIPTION=`Request cooperative cancellation of one or more background tasks. Cancellation is final: a task that finishes after you cancel it stays cancelled. Cancelling an already-finished task changes nothing.`,TASK_UPDATE_DESCRIPTION=`Briefly tell the parent agent what this background task is currently doing. Report activity, not preliminary findings or results.`;function createTaskToolHarnessDefinitions(){return[{description:TASK_CANCEL_DESCRIPTION,inputSchema:TASK_CANCEL_INPUT_SCHEMA,name:TASK_CANCEL_TOOL_NAME,outputSchema:TASK_VIEWS_OUTPUT_SCHEMA,runtimeAction:{kind:`task-control`}},{description:TASK_UPDATE_DESCRIPTION,inputSchema:TASK_UPDATE_INPUT_SCHEMA,name:TASK_UPDATE_TOOL_NAME,runtimeAction:{kind:`task-control`}}]}function isTaskToolAvailable(e){return e.tasksEnabled&&!e.disabledFrameworkTools.includes(e.toolName)&&!e.hasAuthoredTool}function createResolvedTaskToolStub(e){return{description:e.description,inputSchema:null,logicalPath:`eve:framework/${e.name}`,name:e.name,sourceId:`eve:${e.name}-tool`,sourceKind:`module`}}const TASK_TOOL_DEFINITIONS=[createResolvedTaskToolStub({description:TASK_CANCEL_DESCRIPTION,name:TASK_CANCEL_TOOL_NAME}),createResolvedTaskToolStub({description:TASK_UPDATE_DESCRIPTION,name:TASK_UPDATE_TOOL_NAME})];export{SUBAGENT_TASK_RECEIPT_OUTPUT_SCHEMA,TASK_CANCEL_INPUT_SCHEMA,TASK_CANCEL_TOOL_NAME,TASK_CONTROL_TOOL_NAMES,TASK_TOOL_DEFINITIONS,TASK_TOOL_NAMES,TASK_UPDATE_INPUT_SCHEMA,TASK_UPDATE_TOOL_NAME,TASK_VIEWS_OUTPUT_SCHEMA,createTaskToolHarnessDefinitions,isTaskToolAvailable};
@@ -1 +1 @@
1
- import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{isToolSchema,toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{normalizeApproval}from"#internal/authored-definition/approval.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(i,o,s){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:i,kindLabel:`tool`,moduleMap:o,nodeId:s}),describe(i,`to return an object`)),a={kind:`tool`,logicalPath:i.logicalPath,name:i.name},c=`tool-source:${i.sourceId}`;stampDefinitionKey(n,c),registerDefinitionSource(c,a),registerDefinitionSource(`tool:${n.description}`,a);let l=expectFunction(n.execute,describe(i,`to provide an execute function`)),u=isToolSchema(n.inputSchema)?n.inputSchema:toInputSchema(i.inputSchema),d=isToolSchema(n.outputSchema)?n.outputSchema:toOutputSchema(i.outputSchema);return{description:i.description,execute:l,exportName:i.exportName,inputSchema:u,logicalPath:i.logicalPath,name:i.name,outputSchema:d,sourceId:i.sourceId,sourceKind:`module`,...extractOptionalHooks(n,i)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${i.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:i.logicalPath,sourceId:i.sourceId})}}function extractOptionalHooks(t,n){let r={};return t.approval!==void 0&&(r.approval=normalizeApproval(t.approval,describe(n,`to provide a valid approval definition`))),t.toModelOutput!==void 0&&(r.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),r}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}export{resolveToolDefinition};
1
+ import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{isToolSchema,toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{normalizeApproval}from"#internal/authored-definition/approval.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(i,o,s){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:i,kindLabel:`tool`,moduleMap:o,nodeId:s}),describe(i,`to return an object`)),a={kind:`tool`,logicalPath:i.logicalPath,name:i.name},c=`tool-source:${i.sourceId}`;stampDefinitionKey(n,c),registerDefinitionSource(c,a),registerDefinitionSource(`tool:${n.description}`,a);let l=expectFunction(n.execute,describe(i,`to provide an execute function`)),u=isToolSchema(n.inputSchema)?n.inputSchema:toInputSchema(i.inputSchema),d=isToolSchema(n.outputSchema)?n.outputSchema:toOutputSchema(i.outputSchema);return{description:i.description,execute:l,execution:i.execution,exportName:i.exportName,inputSchema:u,logicalPath:i.logicalPath,name:i.name,outputSchema:d,sourceId:i.sourceId,sourceKind:`module`,...extractOptionalHooks(n,i)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${i.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:i.logicalPath,sourceId:i.sourceId})}}function extractOptionalHooks(t,n){let r={};return t.approval!==void 0&&(r.approval=normalizeApproval(t.approval,describe(n,`to provide a valid approval definition`))),t.toModelOutput!==void 0&&(r.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),r}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}export{resolveToolDefinition};
@@ -1 +1 @@
1
- import{isInputRequest}from"#runtime/input/types.js";import{z}from"#compiled/zod/index.js";import{EVE_CALLBACK_ROUTE_PATTERN}from"#protocol/routes.js";import{jsonValueSchema}from"#shared/json-schemas.js";import{REMOTE_AGENT_FAILED}from"#harness/agent-handle-errors.js";import{readTaskIdFromInboxToken}from"#tasks/task-id.js";import{resumeHook}from"#internal/workflow/runtime.js";import{tokenUsageSchema}from"#shared/token-usage.js";import{agentTurnOutcomeSchema}from"#shared/agent-turn-outcome.js";const HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX=`eve/v1/callback`,HANDLED_METHODS=[`POST`],ZERO_TOKEN_USAGE={cacheReadTokens:0,cacheWriteTokens:0,inputTokens:0,outputTokens:0},eventCoordinateSchema=z.number().int().nonnegative(),authorizationChallengeSchema=z.looseObject({displayName:z.string().optional(),expiresAt:z.string().optional(),instructions:z.string().optional(),url:z.string().optional(),userCode:z.string().optional()}),taskInputEventSchema=z.looseObject({requests:z.array(jsonValueSchema.refine(isInputRequest)).min(1),sequence:eventCoordinateSchema,stepIndex:eventCoordinateSchema,turnId:z.string()}),taskAuthorizationEventSchema=z.discriminatedUnion(`type`,[z.looseObject({data:z.looseObject({attemptId:z.string().optional(),authorization:authorizationChallengeSchema.optional(),description:z.string(),name:z.string(),sequence:eventCoordinateSchema,stepIndex:eventCoordinateSchema,turnId:z.string(),webhookUrl:z.string().optional()}),type:z.literal(`authorization.required`)}),z.looseObject({data:z.looseObject({attemptId:z.string().optional(),authorization:authorizationChallengeSchema.optional(),name:z.string(),outcome:z.enum([`authorized`,`declined`,`failed`,`timed-out`]),reason:z.string().optional(),sequence:eventCoordinateSchema,stepIndex:eventCoordinateSchema,turnId:z.string()}),type:z.literal(`authorization.completed`)})]),taskEventCallbackSchema=z.discriminatedUnion(`kind`,[z.object({callId:z.string(),childContinuationToken:z.string(),childSessionId:z.string(),event:taskInputEventSchema,kind:z.literal(`task.input-requested`),subagentName:z.string(),taskId:z.string()}),z.object({callId:z.string(),childContinuationToken:z.string(),childSessionId:z.string(),event:taskAuthorizationEventSchema,kind:z.literal(`task.authorization`),subagentName:z.string(),taskId:z.string()})]),taskTurnStartedCallbackSchema=z.object({kind:z.literal(`turn.started`),sessionId:z.string().min(1),taskId:z.string().min(1),turnId:z.string().min(1)}),taskUpdateCallbackSchema=z.object({callId:z.string().min(1),childStepIndex:eventCoordinateSchema,childTurnId:z.string().min(1),kind:z.literal(`task.update`),message:z.string().min(1),taskId:z.string().min(1)}),sessionResultCallbackSchema=z.discriminatedUnion(`kind`,[z.object({callId:z.string().min(1),kind:z.literal(`session.completed`),output:jsonValueSchema.optional(),subagentName:z.string().min(1),usage:z.unknown().optional()}),z.object({callId:z.string().min(1),error:jsonValueSchema.optional(),kind:z.literal(`session.failed`),subagentName:z.string().min(1),usage:z.unknown().optional()}),z.object({callId:z.string().min(1),kind:z.literal(`turn.completed`),outcome:agentTurnOutcomeSchema,output:jsonValueSchema.optional(),subagentName:z.string().min(1)}),z.object({callId:z.string().min(1),error:jsonValueSchema,kind:z.literal(`turn.failed`),outcome:agentTurnOutcomeSchema,subagentName:z.string().min(1)})]);function getSessionCallbackChannelDefinitions(){return HANDLED_METHODS.map(e=>buildCallbackChannelDefinition(e))}function getSessionCallbackChannelNames(){return new Set(HANDLED_METHODS.map(channelNameForMethod))}function buildCallbackChannelDefinition(e){let t=channelNameForMethod(e);return{name:t,method:e,urlPath:EVE_CALLBACK_ROUTE_PATTERN,fetch:handleSessionCallbackRequest,logicalPath:`framework://channels/${t}`,sourceId:`eve:framework:session-callback-${e.toLowerCase()}`,sourceKind:`module`}}function channelNameForMethod(e){return`${HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX}/${e.toLowerCase()}`}async function handleSessionCallbackRequest(e,t){let n=t.params.token;if(typeof n!=`string`||n.length===0)return Response.json({error:`Missing callback token.`,ok:!1},{status:400});let r;try{r=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let i=projectTaskEvent(r,n);if(i instanceof Response)return i;if(i!==void 0){try{await resumeHook(n,i)}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}let a=projectTaskUpdate(r,n);if(a instanceof Response)return a;if(a!==void 0){try{await resumeHook(n,a)}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}let o=projectTaskTurnStarted(r,n);if(o instanceof Response)return o;if(o!==void 0){try{await resumeHook(n,o)}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}let s=projectSessionCallbackResult(r);if(s instanceof Response)return s;try{await resumeHook(n,{kind:`runtime-action-result`,results:[s]})}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}function callbackKind(e){if(!(typeof e!=`object`||!e))return Reflect.get(e,`kind`)}function projectTaskEvent(e,t){let n=callbackKind(e);if(n!==`task.input-requested`&&n!==`task.authorization`)return;let r=taskEventCallbackSchema.safeParse(e);if(!r.success)return Response.json({error:`Invalid task event callback.`,ok:!1},{status:400});let i=r.data,a=rejectMismatchedTaskToken(t,i.taskId);return a===void 0?i.kind===`task.input-requested`?{callId:i.callId,childContinuationToken:i.childContinuationToken,childSessionId:i.childSessionId,event:i.event,kind:`subagent-input-request`,subagentName:i.subagentName}:{callId:i.callId,childSessionId:i.childSessionId,event:i.event,kind:`authorization-event`,subagentName:i.subagentName}:a}function projectTaskTurnStarted(e,t){if(callbackKind(e)!==`turn.started`)return;let n=taskTurnStartedCallbackSchema.safeParse(e);if(!n.success)return Response.json({error:`Invalid task turn-start callback.`,ok:!1},{status:400});let r=rejectMismatchedTaskToken(t,n.data.taskId);return r===void 0?{childSessionId:n.data.sessionId,childTurnId:n.data.turnId,kind:`turn-started`,taskId:n.data.taskId}:r}function projectTaskUpdate(e,t){if(callbackKind(e)!==`task.update`)return;let n=taskUpdateCallbackSchema.safeParse(e);if(!n.success)return Response.json({error:`Invalid task update callback.`,ok:!1},{status:400});let r=rejectMismatchedTaskToken(t,n.data.taskId);return r===void 0?{callId:n.data.callId,childStepIndex:n.data.childStepIndex,childTurnId:n.data.childTurnId,kind:`task-update`,message:n.data.message}:r}function rejectMismatchedTaskToken(e,t){return readTaskIdFromInboxToken(e)===t?void 0:Response.json({error:`Task callback token mismatch.`,ok:!1},{status:403})}function projectSessionCallbackResult(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let t=callbackKind(e);if(t!==`session.completed`&&t!==`session.failed`&&t!==`turn.completed`&&t!==`turn.failed`)return Response.json({error:`Unsupported callback kind.`,ok:!1},{status:400});let n=sessionResultCallbackSchema.safeParse(e);if(!n.success)return Response.json({error:`Invalid session result callback.`,ok:!1},{status:400});let r=n.data;if(r.kind===`session.completed`){let e=r.output??``,t=parseCallbackUsage(r.usage),n={callId:r.callId,kind:`subagent-result`,origin:`child`,outcome:{kind:`terminal`,result:{kind:`succeeded`,output:e},usageDelta:t??ZERO_TOKEN_USAGE},output:e,subagentName:r.subagentName};return t===void 0?n:{...n,usage:t}}if(r.kind===`session.failed`){let e=r.error===void 0?{code:REMOTE_AGENT_FAILED,message:`Remote agent failed.`}:r.error,t=parseCallbackUsage(r.usage);return{callId:r.callId,isError:!0,kind:`subagent-result`,origin:`child`,outcome:{kind:`terminal`,result:{error:e,kind:`failed`},usageDelta:t??ZERO_TOKEN_USAGE},output:e,subagentName:r.subagentName}}return r.kind===`turn.completed`?{callId:r.callId,kind:`subagent-result`,origin:`child`,outcome:r.outcome,output:r.output??``,subagentName:r.subagentName,usage:r.outcome.usageDelta}:{callId:r.callId,isError:!0,kind:`subagent-result`,origin:`child`,outcome:r.outcome,output:r.error,subagentName:r.subagentName}}function parseCallbackUsage(e){if(e===void 0)return;let t=tokenUsageSchema.safeParse(e);return t.success?t.data:void 0}export{HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX,getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames,handleSessionCallbackRequest};
1
+ import{isInputRequest}from"#runtime/input/types.js";import{z}from"#compiled/zod/index.js";import{EVE_CALLBACK_ROUTE_PATTERN}from"#protocol/routes.js";import{jsonValueSchema}from"#shared/json-schemas.js";import{REMOTE_AGENT_FAILED}from"#harness/agent-handle-errors.js";import{readTaskIdFromInboxToken}from"#tasks/task-id.js";import{resumeHook}from"#internal/workflow/runtime.js";import{tokenUsageSchema}from"#shared/token-usage.js";import{agentTurnOutcomeSchema}from"#shared/agent-turn-outcome.js";const HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX=`eve/v1/callback`,HANDLED_METHODS=[`POST`],ZERO_TOKEN_USAGE={cacheReadTokens:0,cacheWriteTokens:0,inputTokens:0,outputTokens:0},eventCoordinateSchema=z.number().int().nonnegative(),authorizationChallengeSchema=z.looseObject({displayName:z.string().optional(),expiresAt:z.string().optional(),instructions:z.string().optional(),url:z.string().optional(),userCode:z.string().optional()}),taskInputEventSchema=z.looseObject({requests:z.array(jsonValueSchema.refine(isInputRequest)).min(1),sequence:eventCoordinateSchema,stepIndex:eventCoordinateSchema,turnId:z.string()}),taskAuthorizationEventSchema=z.discriminatedUnion(`type`,[z.looseObject({data:z.looseObject({attemptId:z.string().optional(),authorization:authorizationChallengeSchema.optional(),description:z.string(),name:z.string(),sequence:eventCoordinateSchema,stepIndex:eventCoordinateSchema,turnId:z.string(),webhookUrl:z.string().optional()}),type:z.literal(`authorization.required`)}),z.looseObject({data:z.looseObject({attemptId:z.string().optional(),authorization:authorizationChallengeSchema.optional(),name:z.string(),outcome:z.enum([`authorized`,`declined`,`failed`,`timed-out`]),reason:z.string().optional(),sequence:eventCoordinateSchema,stepIndex:eventCoordinateSchema,turnId:z.string()}),type:z.literal(`authorization.completed`)})]),taskEventCallbackSchema=z.discriminatedUnion(`kind`,[z.object({callId:z.string(),childContinuationToken:z.string(),childSessionId:z.string(),event:taskInputEventSchema,kind:z.literal(`task.input-requested`),subagentName:z.string(),taskId:z.string()}),z.object({callId:z.string(),childContinuationToken:z.string(),childSessionId:z.string(),event:taskAuthorizationEventSchema,kind:z.literal(`task.authorization`),subagentName:z.string(),taskId:z.string()})]),taskTurnStartedCallbackSchema=z.object({kind:z.literal(`turn.started`),sessionId:z.string().min(1),taskId:z.string().min(1),turnId:z.string().min(1)}),taskUpdateCallbackSchema=z.object({callId:z.string().min(1),kind:z.literal(`task.update`),message:z.string().min(1),taskId:z.string().min(1),updateEpoch:z.string().min(1),updateIndex:eventCoordinateSchema}),sessionResultCallbackSchema=z.discriminatedUnion(`kind`,[z.object({callId:z.string().min(1),kind:z.literal(`session.completed`),output:jsonValueSchema.optional(),subagentName:z.string().min(1),usage:z.unknown().optional()}),z.object({callId:z.string().min(1),error:jsonValueSchema.optional(),kind:z.literal(`session.failed`),subagentName:z.string().min(1),usage:z.unknown().optional()}),z.object({callId:z.string().min(1),kind:z.literal(`turn.completed`),outcome:agentTurnOutcomeSchema,output:jsonValueSchema.optional(),subagentName:z.string().min(1)}),z.object({callId:z.string().min(1),error:jsonValueSchema,kind:z.literal(`turn.failed`),outcome:agentTurnOutcomeSchema,subagentName:z.string().min(1)})]);function getSessionCallbackChannelDefinitions(){return HANDLED_METHODS.map(e=>buildCallbackChannelDefinition(e))}function getSessionCallbackChannelNames(){return new Set(HANDLED_METHODS.map(channelNameForMethod))}function buildCallbackChannelDefinition(e){let t=channelNameForMethod(e);return{name:t,method:e,urlPath:EVE_CALLBACK_ROUTE_PATTERN,fetch:handleSessionCallbackRequest,logicalPath:`framework://channels/${t}`,sourceId:`eve:framework:session-callback-${e.toLowerCase()}`,sourceKind:`module`}}function channelNameForMethod(e){return`${HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX}/${e.toLowerCase()}`}async function handleSessionCallbackRequest(e,t){let n=t.params.token;if(typeof n!=`string`||n.length===0)return Response.json({error:`Missing callback token.`,ok:!1},{status:400});let r;try{r=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}let i=projectTaskEvent(r,n);if(i instanceof Response)return i;if(i!==void 0){try{await resumeHook(n,i)}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}let a=projectTaskUpdate(r,n);if(a instanceof Response)return a;if(a!==void 0){try{await resumeHook(n,a)}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}let o=projectTaskTurnStarted(r,n);if(o instanceof Response)return o;if(o!==void 0){try{await resumeHook(n,o)}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}let s=projectSessionCallbackResult(r);if(s instanceof Response)return s;try{await resumeHook(n,{kind:`runtime-action-result`,results:[s]})}catch{return Response.json({error:`Session callback not pending.`,ok:!1},{status:404})}return Response.json({ok:!0},{status:202})}function callbackKind(e){if(!(typeof e!=`object`||!e))return Reflect.get(e,`kind`)}function projectTaskEvent(e,t){let n=callbackKind(e);if(n!==`task.input-requested`&&n!==`task.authorization`)return;let r=taskEventCallbackSchema.safeParse(e);if(!r.success)return Response.json({error:`Invalid task event callback.`,ok:!1},{status:400});let i=r.data,a=rejectMismatchedTaskToken(t,i.taskId);return a===void 0?i.kind===`task.input-requested`?{callId:i.callId,childContinuationToken:i.childContinuationToken,childSessionId:i.childSessionId,event:i.event,kind:`subagent-input-request`,subagentName:i.subagentName}:{callId:i.callId,childSessionId:i.childSessionId,event:i.event,kind:`authorization-event`,subagentName:i.subagentName}:a}function projectTaskTurnStarted(e,t){if(callbackKind(e)!==`turn.started`)return;let n=taskTurnStartedCallbackSchema.safeParse(e);if(!n.success)return Response.json({error:`Invalid task turn-start callback.`,ok:!1},{status:400});let r=rejectMismatchedTaskToken(t,n.data.taskId);return r===void 0?{childSessionId:n.data.sessionId,childTurnId:n.data.turnId,kind:`turn-started`,taskId:n.data.taskId}:r}function projectTaskUpdate(e,t){if(callbackKind(e)!==`task.update`)return;let n=taskUpdateCallbackSchema.safeParse(e);if(!n.success)return Response.json({error:`Invalid task update callback.`,ok:!1},{status:400});let r=rejectMismatchedTaskToken(t,n.data.taskId);return r===void 0?{callId:n.data.callId,kind:`task-update`,message:n.data.message,updateEpoch:n.data.updateEpoch,updateIndex:n.data.updateIndex}:r}function rejectMismatchedTaskToken(e,t){return readTaskIdFromInboxToken(e)===t?void 0:Response.json({error:`Task callback token mismatch.`,ok:!1},{status:403})}function projectSessionCallbackResult(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let t=callbackKind(e);if(t!==`session.completed`&&t!==`session.failed`&&t!==`turn.completed`&&t!==`turn.failed`)return Response.json({error:`Unsupported callback kind.`,ok:!1},{status:400});let n=sessionResultCallbackSchema.safeParse(e);if(!n.success)return Response.json({error:`Invalid session result callback.`,ok:!1},{status:400});let r=n.data;if(r.kind===`session.completed`){let e=r.output??``,t=parseCallbackUsage(r.usage),n={callId:r.callId,kind:`subagent-result`,origin:`child`,outcome:{kind:`terminal`,result:{kind:`succeeded`,output:e},usageDelta:t??ZERO_TOKEN_USAGE},output:e,subagentName:r.subagentName};return t===void 0?n:{...n,usage:t}}if(r.kind===`session.failed`){let e=r.error===void 0?{code:REMOTE_AGENT_FAILED,message:`Remote agent failed.`}:r.error,t=parseCallbackUsage(r.usage);return{callId:r.callId,isError:!0,kind:`subagent-result`,origin:`child`,outcome:{kind:`terminal`,result:{error:e,kind:`failed`},usageDelta:t??ZERO_TOKEN_USAGE},output:e,subagentName:r.subagentName}}return r.kind===`turn.completed`?{callId:r.callId,kind:`subagent-result`,origin:`child`,outcome:r.outcome,output:r.output??``,subagentName:r.subagentName,usage:r.outcome.usageDelta}:{callId:r.callId,isError:!0,kind:`subagent-result`,origin:`child`,outcome:r.outcome,output:r.error,subagentName:r.subagentName}}function parseCallbackUsage(e){if(e===void 0)return;let t=tokenUsageSchema.safeParse(e);return t.success?t.data:void 0}export{HTTP_SESSION_CALLBACK_CHANNEL_NAME_PREFIX,getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames,handleSessionCallbackRequest};
@@ -0,0 +1,5 @@
1
+ export interface LinqManagementDeps {
2
+ fetch: typeof fetch;
3
+ }
4
+ /** Lists the phone numbers assigned to a Linq partner API token. */
5
+ export declare function listLinqPhoneNumbers(apiToken: string, signal?: AbortSignal, deps?: LinqManagementDeps): Promise<string[]>;
@@ -0,0 +1 @@
1
+ import{z}from"#compiled/zod/index.js";const PhoneNumbersSchema=z.object({phone_numbers:z.array(z.object({phone_number:z.string().min(1)}))}),defaultDeps={fetch};async function listLinqPhoneNumbers(e,t,n=defaultDeps){let r=await n.fetch(`https://api.linqapp.com/api/partner/v3/phone_numbers`,{headers:{accept:`application/json`,authorization:`Bearer ${e}`},signal:t});if(!r.ok)throw Error(`Could not fetch Linq phone numbers (${r.status}). Confirm the partner API token is valid.`);let i=PhoneNumbersSchema.safeParse(await r.json());if(!i.success)throw Error(`Linq returned invalid phone number data.`);let a=i.data.phone_numbers.map(({phone_number:e})=>e);if(a.length===0)throw Error(`No phone numbers are assigned to this Linq partner API token.`);return a}export{listLinqPhoneNumbers};
@@ -1,6 +1,10 @@
1
1
  import type { VercelProjectReference } from "#setup/project-resolution.js";
2
2
  import { type LinqExistingAccountCredentials } from "./connect.js";
3
+ import { listLinqPhoneNumbers } from "./management.js";
3
4
  import { type SetupApplyContext, type SetupPrepareContext } from "../types.js";
5
+ export interface LinqSetupDeps {
6
+ listPhoneNumbers: typeof listLinqPhoneNumbers;
7
+ }
4
8
  interface LinqSetupPlan {
5
9
  credentials: "connect" | "portable";
6
10
  connectorSlug?: string;
@@ -9,7 +13,7 @@ interface LinqSetupPlan {
9
13
  apiKey?: string;
10
14
  signingSecret?: string;
11
15
  }
12
- export declare function prepareLinqSetup(context: SetupPrepareContext): Promise<LinqSetupPlan>;
16
+ export declare function prepareLinqSetup(context: SetupPrepareContext, deps?: LinqSetupDeps): Promise<LinqSetupPlan>;
13
17
  export declare function applyLinqSetup(plan: LinqSetupPlan, context: SetupApplyContext): Promise<{
14
18
  facts: {
15
19
  label: string;