eve 0.27.12 → 0.28.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 (157) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/src/channel/adapter.d.ts +5 -5
  3. package/dist/src/channel/session.d.ts +2 -2
  4. package/dist/src/channel/types.d.ts +10 -6
  5. package/dist/src/chunks/{use-eve-agent-CsSQOKnp.js → use-eve-agent-CZkX_ZTT.js} +90 -1
  6. package/dist/src/chunks/{use-eve-agent-CWYe-vqE.js → use-eve-agent-hdPX68_i.js} +90 -1
  7. package/dist/src/cli/commands/channels.js +1 -1
  8. package/dist/src/cli/commands/integration-setup.js +1 -1
  9. package/dist/src/cli/commands/register-registry-commands.js +1 -1
  10. package/dist/src/cli/commands/registry-setup-command.d.ts +5 -3
  11. package/dist/src/cli/commands/registry-setup-command.js +1 -1
  12. package/dist/src/cli/commands/registry.d.ts +9 -3
  13. package/dist/src/cli/commands/registry.js +1 -1
  14. package/dist/src/cli/dev/tui/runner.js +1 -1
  15. package/dist/src/cli/dev/tui/subagent-pump.d.ts +8 -2
  16. package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
  17. package/dist/src/cli/invoke/result.d.ts +15 -0
  18. package/dist/src/cli/invoke/result.js +1 -1
  19. package/dist/src/client/eve-agent-store.d.ts +7 -4
  20. package/dist/src/client/eve-agent-store.js +1 -1
  21. package/dist/src/client/index.d.ts +3 -3
  22. package/dist/src/client/index.js +1 -1
  23. package/dist/src/client/message-action-parts.js +1 -1
  24. package/dist/src/client/message-reducer-types.d.ts +5 -3
  25. package/dist/src/client/message-response.d.ts +4 -4
  26. package/dist/src/client/ndjson.d.ts +3 -3
  27. package/dist/src/client/open-stream.d.ts +2 -2
  28. package/dist/src/client/output-schema.d.ts +2 -2
  29. package/dist/src/client/reducer.d.ts +2 -2
  30. package/dist/src/client/session-utils.d.ts +5 -5
  31. package/dist/src/client/session.d.ts +2 -2
  32. package/dist/src/client/types.d.ts +2 -2
  33. package/dist/src/compiler/compile-from-memory.d.ts +1 -0
  34. package/dist/src/compiler/extension-compatibility.d.ts +8 -8
  35. package/dist/src/compiler/extension-compatibility.js +1 -1
  36. package/dist/src/compiler/manifest.d.ts +2 -2
  37. package/dist/src/compiler/manifest.js +1 -1
  38. package/dist/src/compiler/normalize-agent-config.js +1 -1
  39. package/dist/src/context/dynamic-instruction-lifecycle.d.ts +2 -2
  40. package/dist/src/context/dynamic-model-lifecycle.d.ts +2 -2
  41. package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -2
  42. package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -2
  43. package/dist/src/context/hook-lifecycle.d.ts +2 -2
  44. package/dist/src/evals/assertions/run.d.ts +3 -3
  45. package/dist/src/evals/match.d.ts +4 -4
  46. package/dist/src/evals/runner/derive-run-facts.d.ts +2 -2
  47. package/dist/src/evals/session.d.ts +3 -3
  48. package/dist/src/evals/types.d.ts +12 -12
  49. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  50. package/dist/src/execution/route-child-delivery.d.ts +4 -3
  51. package/dist/src/execution/route-child-delivery.js +1 -1
  52. package/dist/src/execution/session-delivery-hook.d.ts +1 -0
  53. package/dist/src/execution/session-delivery-hook.js +1 -1
  54. package/dist/src/execution/session-timeout-control.d.ts +9 -0
  55. package/dist/src/execution/session-timeout-control.js +1 -0
  56. package/dist/src/execution/session-timeout-steps.d.ts +13 -0
  57. package/dist/src/execution/session-timeout-steps.js +1 -0
  58. package/dist/src/execution/session-timeout-workflow.d.ts +6 -0
  59. package/dist/src/execution/session-timeout-workflow.js +1 -0
  60. package/dist/src/execution/session-timeout.d.ts +2 -0
  61. package/dist/src/execution/session-timeout.js +1 -0
  62. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  63. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  64. package/dist/src/execution/subagent-hitl-proxy.d.ts +5 -1
  65. package/dist/src/execution/subagent-hitl-proxy.js +1 -1
  66. package/dist/src/execution/terminal-session-completion-step.d.ts +5 -0
  67. package/dist/src/execution/terminal-session-completion-step.js +1 -0
  68. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  69. package/dist/src/execution/turn-workflow.js +1 -1
  70. package/dist/src/execution/workflow-entry.d.ts +1 -0
  71. package/dist/src/execution/workflow-entry.js +1 -1
  72. package/dist/src/execution/workflow-runtime.d.ts +4 -0
  73. package/dist/src/execution/workflow-runtime.js +1 -1
  74. package/dist/src/execution/workflow-steps.d.ts +5 -2
  75. package/dist/src/execution/workflow-steps.js +1 -1
  76. package/dist/src/harness/agent-otel-provider.js +1 -1
  77. package/dist/src/harness/ai-sdk-hook-bridge.js +1 -1
  78. package/dist/src/harness/input-extraction.js +1 -1
  79. package/dist/src/harness/input-request-class.d.ts +23 -0
  80. package/dist/src/harness/input-request-class.js +1 -0
  81. package/dist/src/harness/input-requests.d.ts +20 -9
  82. package/dist/src/harness/input-requests.js +1 -1
  83. package/dist/src/harness/instrumentation-lifecycle.d.ts +12 -1
  84. package/dist/src/harness/proxy-input-requests.d.ts +10 -4
  85. package/dist/src/harness/proxy-input-requests.js +1 -1
  86. package/dist/src/harness/session-limit-continuation.d.ts +0 -11
  87. package/dist/src/harness/session-limit-continuation.js +1 -1
  88. package/dist/src/harness/session-limit-enforcement.d.ts +3 -2
  89. package/dist/src/harness/session-limit-enforcement.js +1 -1
  90. package/dist/src/harness/session-token-limits.d.ts +41 -0
  91. package/dist/src/harness/session-token-limits.js +1 -0
  92. package/dist/src/harness/stale-input-responses.js +1 -1
  93. package/dist/src/harness/subagent-token-budget.d.ts +6 -4
  94. package/dist/src/harness/subagent-token-budget.js +1 -1
  95. package/dist/src/harness/tool-loop.js +1 -1
  96. package/dist/src/harness/turn-tag-state.d.ts +26 -17
  97. package/dist/src/harness/turn-tag-state.js +1 -1
  98. package/dist/src/harness/types.d.ts +4 -4
  99. package/dist/src/harness/workflow-lifecycle.d.ts +2 -2
  100. package/dist/src/internal/application/package.js +1 -1
  101. package/dist/src/internal/authored-definition/core.js +1 -1
  102. package/dist/src/internal/node-esm-compat-banner.js +1 -1
  103. package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +1 -1
  104. package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
  105. package/dist/src/protocol/event-dedupe.d.ts +25 -0
  106. package/dist/src/protocol/event-dedupe.js +1 -0
  107. package/dist/src/protocol/event-id.d.ts +16 -0
  108. package/dist/src/protocol/event-id.js +1 -0
  109. package/dist/src/protocol/message.d.ts +39 -23
  110. package/dist/src/protocol/message.js +2 -2
  111. package/dist/src/public/channels/discord/discordChannel.d.ts +3 -3
  112. package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
  113. package/dist/src/public/channels/linear/defaults.js +4 -2
  114. package/dist/src/public/channels/linear/linearChannel.d.ts +3 -3
  115. package/dist/src/public/channels/slack/hitl.js +1 -1
  116. package/dist/src/public/channels/slack/slackChannel.d.ts +3 -3
  117. package/dist/src/public/channels/teams/hitl.js +1 -1
  118. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
  119. package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -3
  120. package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
  121. package/dist/src/public/definitions/channel.d.ts +4 -4
  122. package/dist/src/public/definitions/hook.d.ts +2 -2
  123. package/dist/src/react/use-eve-agent.d.ts +3 -2
  124. package/dist/src/runtime/framework-tools/ask-question.js +1 -1
  125. package/dist/src/runtime/hooks/registry.d.ts +2 -2
  126. package/dist/src/runtime/input/types.d.ts +19 -4
  127. package/dist/src/runtime/input/types.js +1 -1
  128. package/dist/src/runtime/resolve-agent.js +1 -1
  129. package/dist/src/runtime/types.d.ts +2 -2
  130. package/dist/src/setup/scaffold/create/project.js +1 -1
  131. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  132. package/dist/src/setup/scaffold/create/web-template.js +2 -2
  133. package/dist/src/shared/agent-definition.d.ts +12 -0
  134. package/dist/src/shared/dynamic-tool-definition.d.ts +2 -2
  135. package/dist/src/shared/ulid.d.ts +39 -0
  136. package/dist/src/shared/ulid.js +1 -0
  137. package/dist/src/svelte/index.js +1 -1
  138. package/dist/src/svelte/use-eve-agent.d.ts +4 -4
  139. package/dist/src/svelte/use-eve-agent.js +1 -1
  140. package/dist/src/vue/index.js +1 -1
  141. package/dist/src/vue/use-eve-agent.d.ts +4 -4
  142. package/dist/src/vue/use-eve-agent.js +1 -1
  143. package/docs/agent-config.md +28 -16
  144. package/docs/channels/linear.mdx +4 -0
  145. package/docs/concepts/execution-model-and-durability.mdx +1 -1
  146. package/docs/concepts/sessions-runs-and-streaming.md +61 -0
  147. package/docs/extensions.md +3 -1
  148. package/docs/guides/client/streaming.mdx +9 -3
  149. package/docs/guides/frontend/overview.mdx +4 -2
  150. package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -1
  151. package/docs/guides/frontend/use-eve-agent-vue.mdx +10 -10
  152. package/docs/guides/hooks.md +40 -2
  153. package/docs/guides/instrumentation.md +4 -0
  154. package/docs/install-integrations.mdx +76 -1
  155. package/docs/reference/cli.md +3 -0
  156. package/docs/tools/human-in-the-loop.md +5 -0
  157. package/package.json +1 -1
@@ -1 +1 @@
1
- import{resolveRuntimeActionResultsForKeys}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{turnStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{activeTurnId}from"#harness/active-turn-id.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#execution/subagent-event-proxy-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";function canSettleCancelledTurnAsPark(e){return e.mode===`conversation`||e.stepInput.sessionState.continuationToken!==``}async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(e){let c=createHook({token:`${e.completionToken}:inbox`}),l=c[Symbol.asyncIterator](),u=new TurnExecutionCursor({controlToken:e.completionToken,parentWritable:e.stepInput.parentWritable,serializedContext:e.stepInput.serializedContext,sessionState:e.stepInput.sessionState}),d=0,nextDeliveryRequestId=()=>`${c.token}:delivery:${String(d++)}`,f=[],p=e.stepInput.input,m=!1,h;try{try{await claimHookOwnership(c),m=!0}catch(e){if(isHookConflictError(e))return;throw e}for(e.driverCapabilities?.cancelledTurnSettle===!0&&canSettleCancelledTurnAsPark(e)&&(h=await createTurnCancellationControl({expectedTurnId:activeTurnId(e.stepInput.sessionState.emissionState),sessionId:e.stepInput.sessionState.sessionId}));;){let i=await turnStep(u.createStepInput(p,h?.signal));if(i.action===`cancelled`){await cancelDescendantTurnsStep({serializedContext:u.serializedContext,sessionState:u.sessionState}),await h?.dispose(),await u.finish({sessionState:u.sessionState},{cancelled:!0,kind:`park`},f);return}if(i.action===`done`){await h?.dispose(),await u.finish(i,{kind:`done`,output:i.output??``,isError:i.isError,usage:i.usage},f);return}let o=i.action===`dispatch-workflow-runtime-actions`||i.action===`park`?i.pendingRuntimeActionKeys:void 0;if(o!==void 0){await u.adopt(i);let e=await(i.action===`dispatch-workflow-runtime-actions`?dispatchWorkflowRuntimeActionsStep:dispatchRuntimeActionsStep)({callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),parentContinuationToken:c.token,parentWritable:u.parentWritable,serializedContext:u.serializedContext,sessionState:u.sessionState});await u.adopt(e);let r=await waitForRuntimeActionResults({bufferedDeliveries:f,cancellation:h,cursor:u,inboxToken:c.token,initialResults:e.results,iterator:l,nextDeliveryRequestId,pendingActionKeys:o});if(r===`cancelled`){p=void 0;continue}p={kind:`runtime-action-result`,results:r};continue}if(i.action===`park`){if(!(i.hasPendingAuthorization||i.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);await h?.dispose(),await u.finish(i,{authorizationNames:i.authorizationNames,kind:`park`},f);return}await u.adopt(i),p=void 0}}catch(e){throw await u.send({error:normalizeSerializableError(e),kind:`turn-error`}),e}finally{h!==void 0&&await h.dispose(),m&&await disposeHook(c)}}async function waitForRuntimeActionResults(t){let n,r=[...t.initialResults];for(;;){let i=resolveRuntimeActionResultsForKeys({pendingKeys:t.pendingActionKeys,results:r});if(i!==void 0)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),i;t.cursor.sessionState.hasProxyInputRequests&&n===void 0&&(n=t.nextDeliveryRequestId(),await t.cursor.send({continuationToken:t.cursor.sessionState.continuationToken,inboxToken:t.inboxToken,kind:`turn-delivery-request`,requestId:n}));let a=t.iterator.next();a.catch(()=>{});let o=await(t.cancellation===void 0?a:Promise.race([a,t.cancellation.requested]));if(o===`cancel`)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),`cancelled`;if(o.done)throw Error(`Turn inbox closed before runtime actions completed.`);let s=o.value;if(s.kind===`runtime-action-result`){r.push(...s.results);continue}if(s.kind===`subagent-input-request`||s.kind===`subagent-authorization-event`){let e=await runProxySubagentEventStep({hookPayload:s,parentWritable:t.cursor.parentWritable,serializedContext:t.cursor.serializedContext,sessionState:t.cursor.sessionState});await t.cursor.adopt(e);continue}if(s.kind===`driver-delivery`&&s.requestId===n){await t.cursor.send({kind:`turn-delivery-accepted`,requestId:s.requestId}),n=void 0;let e=await routeDeliverToChildren({auth:s.delivery.auth,parentWritable:t.cursor.parentWritable,payloads:s.delivery.payloads,sessionState:t.cursor.sessionState});e!==void 0&&t.bufferedDeliveries.push({...s.delivery,payloads:[e]})}}}async function runLegacyTurnWorkflow(e){let t=e.stepInput;try{for(;;){let n=await turnStep(t);if(n.action===`done`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`done`,output:n.output??``,isError:n.isError,serializedContext:n.serializedContext,sessionState:n.sessionState,usage:n.usage},kind:`turn-result`}});return}if(n.action===`dispatch-workflow-runtime-actions`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`dispatch-workflow-runtime-actions`,pendingActionKeys:n.pendingRuntimeActionKeys,serializedContext:n.serializedContext,sessionState:n.sessionState},kind:`turn-result`}});return}if(n.action===`park`){let t=n.pendingRuntimeActionKeys;if(!(t!==void 0||n.hasPendingAuthorization||n.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);let r=t===void 0?{kind:`park`,serializedContext:n.serializedContext,sessionState:n.sessionState,authorizationNames:n.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:n.serializedContext,sessionState:n.sessionState};await sendTurnControlStep({controlToken:e.completionToken,payload:{action:r,kind:`turn-result`}});return}t={input:void 0,parentWritable:t.parentWritable,serializedContext:n.serializedContext,sessionState:n.sessionState}}}catch(t){throw await sendTurnControlStep({controlToken:e.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}export{turnWorkflow};
1
+ import{resolveRuntimeActionResultsForKeys}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{turnStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{activeTurnId}from"#harness/active-turn-id.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#execution/subagent-event-proxy-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";function canSettleCancelledTurnAsPark(e){return e.mode===`conversation`||e.stepInput.sessionState.continuationToken!==``}async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(e){let c=createHook({token:`${e.completionToken}:inbox`}),l=c[Symbol.asyncIterator](),u=new TurnExecutionCursor({controlToken:e.completionToken,parentWritable:e.stepInput.parentWritable,serializedContext:e.stepInput.serializedContext,sessionState:e.stepInput.sessionState}),d=0,nextDeliveryRequestId=()=>`${c.token}:delivery:${String(d++)}`,f=[],p=e.stepInput.input,m=!1,h;try{try{await claimHookOwnership(c),m=!0}catch(e){if(isHookConflictError(e))return;throw e}for(e.driverCapabilities?.cancelledTurnSettle===!0&&canSettleCancelledTurnAsPark(e)&&(h=await createTurnCancellationControl({expectedTurnId:activeTurnId(e.stepInput.sessionState.emissionState),sessionId:e.stepInput.sessionState.sessionId}));;){let i=await turnStep(u.createStepInput(p,h?.signal));if(i.action===`cancelled`){await finishCancelledTurn({bufferedDeliveries:f,cancellation:h,cursor:u});return}if(i.action===`done`){await h?.dispose(),await u.finish(i,{kind:`done`,output:i.output??``,isError:i.isError,usage:i.usage},f);return}let o=i.action===`dispatch-workflow-runtime-actions`||i.action===`park`?i.pendingRuntimeActionKeys:void 0;if(o!==void 0){await u.adopt(i);let e=await(i.action===`dispatch-workflow-runtime-actions`?dispatchWorkflowRuntimeActionsStep:dispatchRuntimeActionsStep)({callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),parentContinuationToken:c.token,parentWritable:u.parentWritable,serializedContext:u.serializedContext,sessionState:u.sessionState});await u.adopt(e);let r=await waitForRuntimeActionResults({bufferedDeliveries:f,cancellation:h,cursor:u,inboxToken:c.token,initialResults:e.results,iterator:l,nextDeliveryRequestId,pendingActionKeys:o});if(r===`cancelled`){p=void 0;continue}if(r===`cancel-turn`){await finishCancelledTurn({bufferedDeliveries:f,cancellation:h,cursor:u});return}p={kind:`runtime-action-result`,results:r};continue}if(i.action===`park`){if(!(i.hasPendingAuthorization||i.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);await h?.dispose(),await u.finish(i,{authorizationNames:i.authorizationNames,kind:`park`},f);return}await u.adopt(i),p=void 0}}catch(e){throw await u.send({error:normalizeSerializableError(e),kind:`turn-error`}),e}finally{h!==void 0&&await h.dispose(),m&&await disposeHook(c)}}async function finishCancelledTurn(e){await cancelDescendantTurnsStep({serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState}),await e.cancellation?.dispose(),await e.cursor.finish({sessionState:e.cursor.sessionState},{cancelled:!0,kind:`park`},e.bufferedDeliveries)}async function waitForRuntimeActionResults(t){let n,r=[...t.initialResults];for(;;){let i=resolveRuntimeActionResultsForKeys({pendingKeys:t.pendingActionKeys,results:r});if(i!==void 0)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),i;t.cursor.sessionState.hasProxyInputRequests&&n===void 0&&(n=t.nextDeliveryRequestId(),await t.cursor.send({continuationToken:t.cursor.sessionState.continuationToken,inboxToken:t.inboxToken,kind:`turn-delivery-request`,requestId:n}));let a=t.iterator.next();a.catch(()=>{});let o=await(t.cancellation===void 0?a:Promise.race([a,t.cancellation.requested]));if(o===`cancel`)return n!==void 0&&await t.cursor.send({kind:`turn-delivery-cancelled`,requestId:n}),`cancelled`;if(o.done)throw Error(`Turn inbox closed before runtime actions completed.`);let s=o.value;if(s.kind===`runtime-action-result`){r.push(...s.results);continue}if(s.kind===`subagent-input-request`||s.kind===`subagent-authorization-event`){let e=await runProxySubagentEventStep({hookPayload:s,parentWritable:t.cursor.parentWritable,serializedContext:t.cursor.serializedContext,sessionState:t.cursor.sessionState});await t.cursor.adopt(e);continue}if(s.kind===`driver-delivery`&&s.requestId===n){await t.cursor.send({kind:`turn-delivery-accepted`,requestId:s.requestId}),n=void 0;let e=await routeDeliverToChildren({auth:s.delivery.auth,parentWritable:t.cursor.parentWritable,payloads:s.delivery.payloads,sessionState:t.cursor.sessionState});if(e.kind===`cancel-turn`)return e.kind;e.remainder!==void 0&&t.bufferedDeliveries.push({...s.delivery,payloads:[e.remainder]})}}}async function runLegacyTurnWorkflow(e){let t=e.stepInput;try{for(;;){let n=await turnStep(t);if(n.action===`done`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`done`,output:n.output??``,isError:n.isError,serializedContext:n.serializedContext,sessionState:n.sessionState,usage:n.usage},kind:`turn-result`}});return}if(n.action===`dispatch-workflow-runtime-actions`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`dispatch-workflow-runtime-actions`,pendingActionKeys:n.pendingRuntimeActionKeys,serializedContext:n.serializedContext,sessionState:n.sessionState},kind:`turn-result`}});return}if(n.action===`park`){let t=n.pendingRuntimeActionKeys;if(!(t!==void 0||n.hasPendingAuthorization||n.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);let r=t===void 0?{kind:`park`,serializedContext:n.serializedContext,sessionState:n.sessionState,authorizationNames:n.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:n.serializedContext,sessionState:n.sessionState};await sendTurnControlStep({controlToken:e.completionToken,payload:{action:r,kind:`turn-result`}});return}t={input:void 0,parentWritable:t.parentWritable,serializedContext:n.serializedContext,sessionState:n.sessionState}}}catch(t){throw await sendTurnControlStep({controlToken:e.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}export{turnWorkflow};
@@ -7,6 +7,7 @@ import type { RunInput } from "#channel/types.js";
7
7
  export interface WorkflowEntryInput {
8
8
  readonly input: RunInput["input"];
9
9
  readonly limits?: RunInput["limits"];
10
+ readonly sessionTimeoutMs?: number | false;
10
11
  readonly serializedContext: Record<string, unknown>;
11
12
  }
12
13
  export interface WorkflowEntryResult {
@@ -1 +1 @@
1
- import{coalesceDeliveries}from"#harness/messages.js";import{readSerializedSubagentDepth}from"#harness/subagent-depth.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{disposeHook}from"#execution/hook-ownership.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{notifyDelegatedParentStep}from"#execution/delegated-parent-notification.js";import{createDelegatedSubagentErrorResult,createDelegatedSubagentSuccessResult}from"#execution/delegated-parent-result.js";import{dispatchAndAwaitTurn}from"#execution/turn-dispatch.js";import{createSessionStep}from"#execution/create-session-step.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import{emitTerminalSessionFailureStep}from"#execution/terminal-session-failure-step.js";import{fireSessionCallbackStep}from"#execution/session-callback-step.js";import{createSessionDeliveryHook}from"#execution/session-delivery-hook.js";async function workflowEntry(e){"use workflow";let{workflowRunId:n}=getWorkflowMetadata(),a=e.serializedContext[`eve.continuationToken`]||``,s=e.serializedContext[`eve.mode`],u=e.serializedContext[`eve.capabilities`],d=e.serializedContext[`eve.bundle`];e.serializedContext[`eve.sessionId`]=n;let f=getWritable();try{let r=readRootSessionId(e.serializedContext),i=readSerializedSubagentDepth(e.serializedContext),{state:o}=await createSessionStep({compiledArtifactsSource:d.source,continuationToken:a,inheritedLimits:e.limits,nodeId:d.nodeId,outputSchema:e.input.outputSchema,rootSessionId:r,sessionId:n,subagentDepth:i});return await runDriverLoop({capabilities:u,driverWritable:f,initialInput:{kind:`deliver`,payloads:[{message:e.input.message,context:e.input.context,outputSchema:e.input.outputSchema}],requestId:readChannelRequestId(e.serializedContext)},mode:s,serializedContext:e.serializedContext,sessionState:o})}catch(t){throw await emitTerminalSessionFailureStep({error:normalizeSerializableError(t),parentWritable:f,serializedContext:e.serializedContext}),await fireSessionCallbackStep({error:normalizeSerializableError(t),serializedContext:e.serializedContext,status:`failed`}),await notifyDelegatedParentStep({result:createDelegatedSubagentErrorResult(e.serializedContext,t),serializedContext:e.serializedContext}),createSafeOuterWorkflowError()}}function createSafeOuterWorkflowError(){let e=Error(`Agent workflow failed. Inspect the private session trace for details.`);return e.name=`EveWorkflowFailure`,e}async function runDriverLoop(e){let t=createHook({token:`${e.sessionState.sessionId}:auth`}),r=t[Symbol.asyncIterator](),i=0,nextTurnControlToken=()=>`${e.sessionState.sessionId}:turn-control:${String(i++)}`,o=[],c=createSessionDeliveryHook(o),l,runTurn=async t=>{let n=await dispatchAndAwaitTurn({bufferedDeliveries:o,capabilities:e.capabilities,controlToken:nextTurnControlToken(),delivery:t.delivery,deliveryHook:c,mode:e.mode,parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});return await l?.(),l=n.dispose,n.action};try{e.sessionState.continuationToken&&await c.rekey(e.sessionState.continuationToken);let t=await runTurn({delivery:e.initialInput,serializedContext:e.serializedContext,sessionState:e.sessionState});for(;;){if(t.kind===`done`)return await finalizeDone({action:t,driverWritable:e.driverWritable});if(t.kind!==`park`)throw Error(`Driver received unexpected turn action "${t.kind}".`);if(t.cancelled===!0){let n=await settleCancelledTurnStep({parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});t={...t,serializedContext:n.serializedContext,sessionState:n.sessionState}}if(!t.sessionState.continuationToken)throw Error("Cannot park: no continuation token available. The channel must post the first message during the initial turn (anchoring the session) or `send()` must be called with an explicit continuationToken.");if(await c.rekey(t.sessionState.continuationToken),t.authorizationNames&&t.authorizationNames.length>0){let e=t.authorizationNames.length,n=[];for(;n.length<e;){let e=await r.next();if(e.done)break;e.value.kind===`deliver`&&n.push(...e.value.payloads)}t=await runTurn({delivery:{kind:`deliver`,payloads:n},serializedContext:t.serializedContext,sessionState:t.sessionState});continue}let n=await waitForNextDeliver({bufferedDeliveries:o,deliveryHook:c});if(n===null)return{output:``};let i=await routeDeliverToChildren({auth:n.auth,parentWritable:e.driverWritable,payloads:n.payloads,sessionState:t.sessionState});i!==void 0&&(t=await runTurn({delivery:{auth:n.auth,kind:`deliver`,payloads:[i],requestId:n.requestId},serializedContext:t.serializedContext,sessionState:t.sessionState}))}}finally{await l?.(),await c.dispose(),await disposeHook(t)}}async function finalizeDone(e){let{output:t,serializedContext:n}=e.action,r=e.action.isError===!0;return await fireSessionCallbackStep({error:r?t:void 0,output:r?void 0:t,serializedContext:n,status:r?`failed`:`completed`,usage:r?void 0:e.action.usage}),await notifyDelegatedParentStep({result:r?createDelegatedSubagentErrorResult(n,t):createDelegatedSubagentSuccessResult(n,t),serializedContext:n,usage:r?void 0:e.action.usage}),{output:t}}async function waitForNextDeliver(t){if(t.bufferedDeliveries.length>0)return coalesceDeliveries(t.bufferedDeliveries.splice(0));for(;;){let n=await t.deliveryHook.next();if(t.deliveryHook.consumeNext(),n.done)return null;if(n.value.kind!==`deliver`)continue;let r=n.value;for(;;){let n=await takeReadyPayload(t.deliveryHook.next());if(n===NO_READY_MESSAGE||(t.deliveryHook.consumeNext(),n.done))break;n.value.kind===`deliver`&&(r=coalesceDeliveries([r,n.value]))}return r}}const NO_READY_MESSAGE=Symbol(`no-ready-message`);async function takeReadyPayload(e){return await Promise.resolve(),await Promise.race([e,Promise.resolve(NO_READY_MESSAGE)])}export{workflowEntry};
1
+ import{coalesceDeliveries}from"#harness/messages.js";import{readSerializedSubagentDepth}from"#harness/subagent-depth.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{disposeHook}from"#execution/hook-ownership.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{notifyDelegatedParentStep}from"#execution/delegated-parent-notification.js";import{createDelegatedSubagentErrorResult,createDelegatedSubagentSuccessResult}from"#execution/delegated-parent-result.js";import{dispatchAndAwaitTurn}from"#execution/turn-dispatch.js";import{createSessionStep}from"#execution/create-session-step.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import{emitTerminalSessionFailureStep}from"#execution/terminal-session-failure-step.js";import{fireSessionCallbackStep}from"#execution/session-callback-step.js";import{createSessionDeliveryHook}from"#execution/session-delivery-hook.js";import{DEFAULT_SESSION_TIMEOUT_MS}from"#execution/session-timeout.js";import{emitTerminalSessionCompletionStep}from"#execution/terminal-session-completion-step.js";import{createSessionTimeoutControl}from"#execution/session-timeout-control.js";async function workflowEntry(e){"use workflow";let{workflowRunId:n,workflowStartedAt:a}=getWorkflowMetadata(),s=e.serializedContext[`eve.continuationToken`]||``,c=e.serializedContext[`eve.mode`],f=e.serializedContext[`eve.capabilities`],p=e.serializedContext[`eve.bundle`];e.serializedContext[`eve.sessionId`]=n;let m=getWritable();try{let r=readRootSessionId(e.serializedContext),i=readSerializedSubagentDepth(e.serializedContext),{state:o}=await createSessionStep({compiledArtifactsSource:p.source,continuationToken:s,inheritedLimits:e.limits,nodeId:p.nodeId,outputSchema:e.input.outputSchema,rootSessionId:r,sessionId:n,subagentDepth:i}),d=await runDriverLoop({capabilities:f,driverWritable:m,initialInput:{kind:`deliver`,payloads:[{message:e.input.message,context:e.input.context,outputSchema:e.input.outputSchema}],requestId:readChannelRequestId(e.serializedContext)},mode:c,serializedContext:e.serializedContext,sessionState:o,sessionTimeoutDeadline:e.sessionTimeoutMs===!1?void 0:new Date(a.getTime()+(e.sessionTimeoutMs??DEFAULT_SESSION_TIMEOUT_MS))});return d.kind===`result`?d.result:await finalizeExpiredSession({driverWritable:m,serializedContext:d.serializedContext})}catch(t){throw await emitTerminalSessionFailureStep({error:normalizeSerializableError(t),parentWritable:m,serializedContext:e.serializedContext}),await fireSessionCallbackStep({error:normalizeSerializableError(t),serializedContext:e.serializedContext,status:`failed`}),await notifyDelegatedParentStep({result:createDelegatedSubagentErrorResult(e.serializedContext,t),serializedContext:e.serializedContext}),createSafeOuterWorkflowError()}}function createSafeOuterWorkflowError(){let e=Error(`Agent workflow failed. Inspect the private session trace for details.`);return e.name=`EveWorkflowFailure`,e}async function runDriverLoop(e){let t=createHook({token:`${e.sessionState.sessionId}:auth`}),r=t[Symbol.asyncIterator](),i=0,nextTurnControlToken=()=>`${e.sessionState.sessionId}:turn-control:${String(i++)}`,o=[],l=createSessionDeliveryHook(o),u=e.sessionTimeoutDeadline===void 0?void 0:createSessionTimeoutControl({deadline:e.sessionTimeoutDeadline}),d,runTurn=async t=>{let n=await dispatchAndAwaitTurn({bufferedDeliveries:o,capabilities:e.capabilities,controlToken:nextTurnControlToken(),delivery:t.delivery,deliveryHook:l,mode:e.mode,parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});return await d?.(),d=n.dispose,n.action};try{e.sessionState.continuationToken&&(await l.rekey(e.sessionState.continuationToken),await u?.rekey(e.sessionState.continuationToken));let t=await runTurn({delivery:e.initialInput,serializedContext:e.serializedContext,sessionState:e.sessionState});for(;;){if(t.kind===`done`)return{kind:`result`,result:await finalizeDone({action:t,driverWritable:e.driverWritable})};if(t.kind!==`park`)throw Error(`Driver received unexpected turn action "${t.kind}".`);if(t.cancelled===!0){let n=await settleCancelledTurnStep({parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});t={...t,serializedContext:n.serializedContext,sessionState:n.sessionState}}if(!t.sessionState.continuationToken)throw Error("Cannot park: no continuation token available. The channel must post the first message during the initial turn (anchoring the session) or `send()` must be called with an explicit continuationToken.");if(await l.rekey(t.sessionState.continuationToken),await u?.rekey(t.sessionState.continuationToken),t.authorizationNames&&t.authorizationNames.length>0){let e=t.authorizationNames.length,n=[];for(;n.length<e;){let e=await r.next();if(e.done)break;e.value.kind===`deliver`&&n.push(...e.value.payloads)}t=await runTurn({delivery:{kind:`deliver`,payloads:n},serializedContext:t.serializedContext,sessionState:t.sessionState});continue}let n=await waitForNextSessionAction({bufferedDeliveries:o,deliveryHook:l});if(n.kind===`expired`)return{kind:`expired`,serializedContext:t.serializedContext};let i=n.delivery;if(i===null)return{kind:`result`,result:{output:``}};let a=await routeDeliverToChildren({auth:i.auth,parentWritable:e.driverWritable,payloads:i.payloads,sessionState:t.sessionState});if(a.kind===`cancel-turn`){await cancelDescendantTurnsStep({serializedContext:t.serializedContext,sessionState:t.sessionState});let n=await settleCancelledTurnStep({parentWritable:e.driverWritable,serializedContext:t.serializedContext,sessionState:t.sessionState});t={...t,serializedContext:n.serializedContext,sessionState:n.sessionState};continue}a.remainder!==void 0&&(t=await runTurn({delivery:{auth:i.auth,kind:`deliver`,payloads:[a.remainder],requestId:i.requestId},serializedContext:t.serializedContext,sessionState:t.sessionState}))}}finally{await d?.(),await u?.dispose(),await l.dispose(),await disposeHook(t)}}async function waitForNextSessionAction(t){if(t.deliveryHook.consumeSessionTimeout())return{kind:`expired`};if(t.bufferedDeliveries.length>0)return{delivery:coalesceDeliveries(t.bufferedDeliveries.splice(0)),kind:`delivery`};for(;;){let n=await t.deliveryHook.next();if(t.deliveryHook.consumeNext(),n.done)return{delivery:null,kind:`delivery`};if(n.value.kind===`session-timeout`)return{kind:`expired`};if(n.value.kind!==`deliver`)continue;let r=n.value;for(;;){let n=await takeReadyPayload(t.deliveryHook.next());if(n===NO_READY_MESSAGE)break;if(n.done){t.deliveryHook.consumeNext();break}if(n.value.kind===`session-timeout`)break;t.deliveryHook.consumeNext(),n.value.kind===`deliver`&&(r=coalesceDeliveries([r,n.value]))}return{delivery:r,kind:`delivery`}}}async function finalizeExpiredSession(e){return await emitTerminalSessionCompletionStep({parentWritable:e.driverWritable,serializedContext:e.serializedContext}),await fireSessionCallbackStep({output:``,serializedContext:e.serializedContext,status:`completed`}),await notifyDelegatedParentStep({result:createDelegatedSubagentSuccessResult(e.serializedContext,``),serializedContext:e.serializedContext}),{output:``}}async function finalizeDone(e){let{output:t,serializedContext:n}=e.action,r=e.action.isError===!0;return await fireSessionCallbackStep({error:r?t:void 0,output:r?void 0:t,serializedContext:n,status:r?`failed`:`completed`,usage:r?void 0:e.action.usage}),await notifyDelegatedParentStep({result:r?createDelegatedSubagentErrorResult(n,t):createDelegatedSubagentSuccessResult(n,t),serializedContext:n,usage:r?void 0:e.action.usage}),{output:t}}const NO_READY_MESSAGE=Symbol(`no-ready-message`);async function takeReadyPayload(e){return await Promise.resolve(),await Promise.race([e,Promise.resolve(NO_READY_MESSAGE)])}export{workflowEntry};
@@ -32,6 +32,10 @@ export declare const workflowEntryReference: {
32
32
  export declare const turnWorkflowReference: {
33
33
  workflowId: string;
34
34
  };
35
+ /** Stable workflow reference for session deadline timers. */
36
+ export declare const sessionTimeoutWorkflowReference: {
37
+ workflowId: string;
38
+ };
35
39
  /**
36
40
  * Creates a workflow-backed runtime whose long-lived driver owns the
37
41
  * event stream and dispatches each turn as a child workflow run.
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{RuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{serializeContext}from"#context/serialize.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRun,getHookByToken,getRun,getWorld,resumeHook,start}from"#internal/workflow/runtime.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{sessionCancelHookToken}from"#execution/turn-cancellation-token.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{parseNdjsonStream}from"#execution/ndjson-stream.js";const WORKFLOW_ENTRY_NAME=`workflowEntry`,TURN_WORKFLOW_NAME=`turnWorkflow`,EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE=`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`,STABLE_WORKFLOW_NAMES=new Set([WORKFLOW_ENTRY_NAME,TURN_WORKFLOW_NAME]),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},turnWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${TURN_WORKFLOW_NAME}`};function createWorkflowRuntime(e){return{async run(n){let r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),i=serializeContext(buildRunContext({bundle:r,run:n})),a=readParentLineage(i),o=a.sessionId===void 0?buildSessionAttributes({inputMessage:n.title??n.input.message,serializedContext:i}):buildSubagentRootAttributes({identity:{nodeId:r.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:a.callId,parentSessionId:a.sessionId,parentTurnId:a.turnId,rootSessionId:a.rootSessionId??a.sessionId,serializedContext:i}),s;try{s=await startWorkflowPreferLatest(workflowEntryReference,[{input:n.input,limits:n.limits,serializedContext:i}],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(o)})}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:n.continuationToken}),e}let c,getEvents=()=>(c??=parseNdjsonStream(()=>getRun(s.runId).getReadable()),c);return{continuationToken:n.continuationToken??s.runId,get events(){return getEvents()},sessionId:s.runId}},async cancelTurn(e){return await requestWorkflowTurnCancellation(e)},async terminateSession(e){try{return await cancelRun(await getWorld(),e.sessionId,{cancelReason:e.reason??`Session reset by channel`}),{status:`terminated`}}catch(e){if(isAlreadyTerminalSessionError(e))return{status:`already_terminal`};throw e}},async deliver(e){let r={auth:e.auth,kind:`deliver`,payloads:[e.payload],requestId:e.requestId};try{return{sessionId:normalizeWorkflowHook(await resumeHook(e.continuationToken,r)).runId}}catch(r){throw HookNotFoundError.is(r)?new RuntimeNoActiveSessionError(e.continuationToken):(logError(log,`failed to deliver to active session`,r,{continuationToken:e.continuationToken}),r)}},async getEventStream(e,t){return parseNdjsonStream(()=>getRun(e).getReadable({startIndex:t?.startIndex}))},async getStreamTailIndex(e){let t=getRun(e).getReadable();try{return await t.getTailIndex()}finally{await t.cancel().catch(()=>{})}},async resolveSession(e){try{return{sessionId:(await getHookByToken(e)).runId}}catch(n){if(HookNotFoundError.is(n))return;throw logError(log,`failed to resolve session by continuation token`,n,{continuationToken:e}),n}}}}async function requestWorkflowTurnCancellation(e){let t=e.turnId===void 0?{}:{turnId:e.turnId};try{return await resumeHook(sessionCancelHookToken(e.sessionId),t),{status:`accepted`}}catch(e){if(isInactiveCancelTarget(e))return{status:`no_active_turn`};throw e}}function isInactiveCancelTarget(e){return HookNotFoundError.is(e)||WorkflowRunNotFoundError.is(e)||RunExpiredError.is(e)||EntityConflictError.is(e)}function isAlreadyTerminalSessionError(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function startWorkflowPreferLatest(e,t,n){if(!shouldRouteToLatestDeployment())return n===void 0?await start(e,t):await start(e,t,n);try{return await start(e,t,{...n,deploymentId:`latest`})}catch(r){if(!isLatestDeploymentUnsupportedError(r))throw r;return n===void 0?await start(e,t):await start(e,t,n)}}function shouldRouteToLatestDeployment(){return process.env.VERCEL_ENV===`production`||isEveDevEnvironment()}function isLatestDeploymentUnsupportedError(e){return e instanceof Error&&e.message.includes(`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}export{LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE,STABLE_WORKFLOW_NAMES,createWorkflowRuntime,requestWorkflowTurnCancellation,startWorkflowPreferLatest,turnWorkflowReference,workflowEntryReference};
1
+ import{createLogger,logError}from"#internal/logging.js";import{RuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{serializeContext}from"#context/serialize.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRun,getHookByToken,getRun,getWorld,resumeHook,start}from"#internal/workflow/runtime.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{sessionCancelHookToken}from"#execution/turn-cancellation-token.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{parseNdjsonStream}from"#execution/ndjson-stream.js";const WORKFLOW_ENTRY_NAME=`workflowEntry`,TURN_WORKFLOW_NAME=`turnWorkflow`,SESSION_TIMEOUT_WORKFLOW_NAME=`sessionTimeoutWorkflow`,EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE=`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`,STABLE_WORKFLOW_NAMES=new Set([WORKFLOW_ENTRY_NAME,TURN_WORKFLOW_NAME,SESSION_TIMEOUT_WORKFLOW_NAME]),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},turnWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${TURN_WORKFLOW_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`};function createWorkflowRuntime(e){return{async run(n){let r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),i=serializeContext(buildRunContext({bundle:r,run:n})),a=readParentLineage(i),o=r.resolvedAgent.config.limits?.sessionTimeoutMs,s={input:n.input,limits:n.limits,serializedContext:i};o!==void 0&&(s.sessionTimeoutMs=o);let c=a.sessionId===void 0?buildSessionAttributes({inputMessage:n.title??n.input.message,serializedContext:i}):buildSubagentRootAttributes({identity:{nodeId:r.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:a.callId,parentSessionId:a.sessionId,parentTurnId:a.turnId,rootSessionId:a.rootSessionId??a.sessionId,serializedContext:i}),l;try{l=await startWorkflowPreferLatest(workflowEntryReference,[s],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(c)})}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:n.continuationToken}),e}let u,getEvents=()=>(u??=parseNdjsonStream(()=>getRun(l.runId).getReadable()),u);return{continuationToken:n.continuationToken??l.runId,get events(){return getEvents()},sessionId:l.runId}},async cancelTurn(e){return await requestWorkflowTurnCancellation(e)},async terminateSession(e){try{return await cancelRun(await getWorld(),e.sessionId,{cancelReason:e.reason??`Session reset by channel`}),{status:`terminated`}}catch(e){if(isAlreadyTerminalSessionError(e))return{status:`already_terminal`};throw e}},async deliver(e){let r={auth:e.auth,kind:`deliver`,payloads:[e.payload],requestId:e.requestId};try{return{sessionId:normalizeWorkflowHook(await resumeHook(e.continuationToken,r)).runId}}catch(r){throw HookNotFoundError.is(r)?new RuntimeNoActiveSessionError(e.continuationToken):(logError(log,`failed to deliver to active session`,r,{continuationToken:e.continuationToken}),r)}},async getEventStream(e,t){return parseNdjsonStream(()=>getRun(e).getReadable({startIndex:t?.startIndex}))},async getStreamTailIndex(e){let t=getRun(e).getReadable();try{return await t.getTailIndex()}finally{await t.cancel().catch(()=>{})}},async resolveSession(e){try{return{sessionId:(await getHookByToken(e)).runId}}catch(n){if(HookNotFoundError.is(n))return;throw logError(log,`failed to resolve session by continuation token`,n,{continuationToken:e}),n}}}}async function requestWorkflowTurnCancellation(e){let t=e.turnId===void 0?{}:{turnId:e.turnId};try{return await resumeHook(sessionCancelHookToken(e.sessionId),t),{status:`accepted`}}catch(e){if(isInactiveCancelTarget(e))return{status:`no_active_turn`};throw e}}function isInactiveCancelTarget(e){return HookNotFoundError.is(e)||WorkflowRunNotFoundError.is(e)||RunExpiredError.is(e)||EntityConflictError.is(e)}function isAlreadyTerminalSessionError(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function startWorkflowPreferLatest(e,t,n){if(!shouldRouteToLatestDeployment())return n===void 0?await start(e,t):await start(e,t,n);try{return await start(e,t,{...n,deploymentId:`latest`})}catch(r){if(!isLatestDeploymentUnsupportedError(r))throw r;return n===void 0?await start(e,t):await start(e,t,n)}}function shouldRouteToLatestDeployment(){return process.env.VERCEL_ENV===`production`||isEveDevEnvironment()}function isLatestDeploymentUnsupportedError(e){return e instanceof Error&&e.message.includes(`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}export{LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE,STABLE_WORKFLOW_NAMES,createWorkflowRuntime,requestWorkflowTurnCancellation,sessionTimeoutWorkflowReference,startWorkflowPreferLatest,turnWorkflowReference,workflowEntryReference};
@@ -66,10 +66,13 @@ export declare function resolveEffectiveOutputSchema(input: {
66
66
  readonly mode: RunMode;
67
67
  readonly session: HarnessSession;
68
68
  }): HarnessSession;
69
- export interface RoutedDeliverResult {
69
+ export type RoutedDeliverResult = {
70
+ readonly kind: "cancel-turn";
71
+ } | {
72
+ readonly kind: "continue";
70
73
  /** `undefined` when the entire payload was routed to descendants. */
71
74
  readonly remainder: DeliverPayload | undefined;
72
- }
75
+ };
73
76
  /**
74
77
  * Splits an inbound deliver payload into parent-local and
75
78
  * proxied-child buckets and forwards the child buckets via
@@ -1 +1 @@
1
- import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ModeKey,SessionDynamicToolRuntimeRevisionKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{createWorkflowRuntime,requestWorkflowTurnCancellation,startWorkflowPreferLatest,turnWorkflowReference}from"#execution/workflow-runtime.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resumeHook}from"#internal/workflow/runtime.js";import{coalesceTurnInputs}from"#harness/messages.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getRuntimeActionKeysFromWorkflowInterrupt,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{runStep}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{isSessionLimitDecline,isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{buildTurnAttributes,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{preserveSerializedAgentTraceState}from"#harness/agent-trace-context-store.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{getTurnUsageState,toUsage}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{recordSubagentUsageSpans}from"#execution/subagent-usage-span.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";async function turnStep(a){"use step";let o=a,s=await readDurableSession(o.sessionState),c=await deserializeContext(o.serializedContext),l=c.require(ChannelKey),u=c.require(BundleKey);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&c.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let d=getPendingAuthorization(s.state),f;if(d&&o.input?.kind===`deliver`){let e=[],t=[],n=[];for(let r of o.input.payloads){let i=r.authorizationCallback;if(i){let n=d.challenges.find(e=>e.name===i.connectionName);n&&(e.push({name:n.name,resume:n.resume,callback:i.callback,hookUrl:n.hookUrl}),t.push({name:n.name,authorization:n.challenge}))}else n.push(r)}e.length>0&&(c.set(PendingAuthorizationResultKey,e),s={...s,state:clearPendingAuthorization(s.state,e.map(e=>e.name))},f=t,o=n.length>0?{...o,input:{...o.input,payloads:n}}:{...o,input:void 0})}o.input?.kind===`deliver`&&o.input.auth!==void 0&&c.set(AuthKey,o.input.auth??null);let p=hydrateDurableSession({compactionOverrides:{thresholdPercent:u.resolvedAgent.config.compaction?.thresholdPercent},durable:s,turnAgent:u.turnAgent}),m=buildAdapterContext(l,c),h;if(o.input?.kind===`deliver`){let e=[];for(let n of o.input.payloads){let r=l.deliver?await l.deliver(n,m):defaultDeliverResult(n);r!=null&&e.push(r)}h=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else o.input?.kind===`runtime-action-result`&&(recordSubagentUsageSpans(o.input.results),h={runtimeActionResults:o.input.results});if(o.input?.kind===`deliver`&&setChannelContext(c,{...l,state:{...m.state}}),o.input?.kind===`deliver`&&h===void 0){let e=reconcileSessionContinuationToken(c,p),t=serializeContext(c),n=e===p?o.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:t,sessionState:n}}let g=u.hookRegistry,_=u.resolvedAgent.dynamicInstructionsResolvers??[],v=u.resolvedAgent.dynamicSkillResolvers??[],y=u.resolvedAgent.dynamicToolResolvers??[],b=buildRuntimeIdentity(u.graph.root),x=process.env.VERCEL_DEPLOYMENT_ID?.trim(),S=x?`deployment:${x}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(u.compiledArtifactsSource);getHarnessEmissionState(p.state).sessionStarted?await refreshDynamicSessionToolsForRuntimeRevision({ctx:c,resolvers:y,event:createSessionStartedEvent({runtime:b}),messages:p.history,runtimeRevision:S}):c.set(SessionDynamicToolRuntimeRevisionKey,S);let C=o.parentWritable.getWriter(),emit=async t=>{let n=await callAdapterEventHandler(l,t,m);return setChannelContext(c,{...l,state:{...m.state}}),await C.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(n))),n},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:c,registry:g,event:n}),n.type!==`step.started`&&await dispatchDynamicModelEvent({ctx:c,dynamicModel:u.turnAgent.dynamicModel,event:n,fallback:u.turnAgent.model,messages:t??[],scope:{moduleMap:u.moduleMap,nodeId:u.nodeId}}),await dispatchDynamicToolEvent({ctx:c,resolvers:y,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:c,resolvers:v,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:c,resolvers:_,event:n,messages:t??[]})},w=c.require(ModeKey),T;try{throwIfTurnAborted(o.abortSignal),T=await runStep(c,p,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:u.turnAgent.outputSchema,input:h,mode:w,session:e});if(f){let e=getHarnessEmissionState(t.state);for(let{name:t,authorization:n}of f)await handleEvent(createAuthorizationCompletedEvent({authorization:n,name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=c.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:u.resolvedAgent.config.compaction?.thresholdPercent},session:e,turnAgent:u.turnAgent});return createExecutionNodeStep({abortSignal:o.abortSignal,capabilities:n,createRuntime:createWorkflowRuntime,handleEvent,mode:w,modelResolutionScope:{moduleMap:u.moduleMap,nodeId:u.nodeId},node:u.graph.root,workflowMaxSubagents:r.workflowMaxSubagents})(r,t)})(t,h)})}catch(e){if(!isTurnCancellation(e))throw e;if(C.releaseLock(),isSessionLimitDecline(e)){let e=readRootSessionId(o.serializedContext);e!==void 0&&await requestWorkflowTurnCancellation({sessionId:e})}return{action:`cancelled`,serializedContext:preserveSerializedAgentTraceState(o.serializedContext,serializeContext(c)),sessionState:o.sessionState}}let E=reconcileSessionContinuationToken(c,T.session),D=serializeContext(c);T={...T,session:E};let O=createDurableSessionState({session:T.session});if(T.next!==null&&typeof T.next==`object`&&`done`in T.next){await C.close();let e=getTurnUsageState(T.session.state)?.session;return{action:`done`,output:T.next.output,isError:T.next.isError,serializedContext:D,sessionState:O,usage:e===void 0?void 0:toUsage(e)}}if(T.next===null){C.releaseLock();let e=getPendingWorkflowInterrupt(T.session.state);return e!==void 0&&isWorkflowRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-workflow-runtime-actions`,pendingRuntimeActionKeys:getRuntimeActionKeysFromWorkflowInterrupt(e.interrupt),serializedContext:D,sessionState:O}:{action:`park`,...derivePendingState(T.session),serializedContext:D,sessionState:O}}return C.releaseLock(),{action:`continue`,serializedContext:D,sessionState:O}}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state});for(let t of n.forChildren)await resumeHook(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return{remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflowReference,[createTurnWorkflowInput(e)],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,requestId:e.delivery.kind===`deliver`?e.delivery.requestId:void 0,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}))})).runId}}export{dispatchTurnStep,resolveEffectiveOutputSchema,routeProxiedDeliverStep,turnStep};
1
+ import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ModeKey,SessionDynamicToolRuntimeRevisionKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionStartedEvent,encodeMessageStreamEvent,stampMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{createWorkflowRuntime,startWorkflowPreferLatest,turnWorkflowReference}from"#execution/workflow-runtime.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resumeHook}from"#internal/workflow/runtime.js";import{coalesceTurnInputs}from"#harness/messages.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getRuntimeActionKeysFromWorkflowInterrupt,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{dispatchDynamicModelEvent}from"#context/dynamic-model-lifecycle.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{setChannelContext}from"#execution/channel-context.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{runStep}from"#context/run-step.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{buildTurnAttributes,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{preserveSerializedAgentTraceState}from"#harness/agent-trace-context-store.js";import{getTurnUsageState,toUsage}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{recordSubagentUsageSpans}from"#execution/subagent-usage-span.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";async function turnStep(a){"use step";let o=a,s=await readDurableSession(o.sessionState),c=await deserializeContext(o.serializedContext),l=c.require(ChannelKey),u=c.require(BundleKey);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&c.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let d=getPendingAuthorization(s.state),f;if(d&&o.input?.kind===`deliver`){let e=[],t=[],n=[];for(let r of o.input.payloads){let i=r.authorizationCallback;if(i){let n=d.challenges.find(e=>e.name===i.connectionName);n&&(e.push({name:n.name,resume:n.resume,callback:i.callback,hookUrl:n.hookUrl}),t.push({name:n.name,authorization:n.challenge}))}else n.push(r)}e.length>0&&(c.set(PendingAuthorizationResultKey,e),s={...s,state:clearPendingAuthorization(s.state,e.map(e=>e.name))},f=t,o=n.length>0?{...o,input:{...o.input,payloads:n}}:{...o,input:void 0})}o.input?.kind===`deliver`&&o.input.auth!==void 0&&c.set(AuthKey,o.input.auth??null);let p=hydrateDurableSession({compactionOverrides:{thresholdPercent:u.resolvedAgent.config.compaction?.thresholdPercent},durable:s,turnAgent:u.turnAgent}),m=buildAdapterContext(l,c),h;if(o.input?.kind===`deliver`){let e=[];for(let n of o.input.payloads){let r=l.deliver?await l.deliver(n,m):defaultDeliverResult(n);r!=null&&e.push(r)}h=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else o.input?.kind===`runtime-action-result`&&(recordSubagentUsageSpans(o.input.results),h={runtimeActionResults:o.input.results});if(o.input?.kind===`deliver`&&setChannelContext(c,{...l,state:{...m.state}}),o.input?.kind===`deliver`&&h===void 0){let e=reconcileSessionContinuationToken(c,p),t=serializeContext(c),n=e===p?o.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:t,sessionState:n}}let g=u.hookRegistry,_=u.resolvedAgent.dynamicInstructionsResolvers??[],v=u.resolvedAgent.dynamicSkillResolvers??[],y=u.resolvedAgent.dynamicToolResolvers??[],b=buildRuntimeIdentity(u.graph.root),x=process.env.VERCEL_DEPLOYMENT_ID?.trim(),S=x?`deployment:${x}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(u.compiledArtifactsSource);getHarnessEmissionState(p.state).sessionStarted?await refreshDynamicSessionToolsForRuntimeRevision({ctx:c,resolvers:y,event:createSessionStartedEvent({runtime:b}),messages:p.history,runtimeRevision:S}):c.set(SessionDynamicToolRuntimeRevisionKey,S);let C=o.parentWritable.getWriter(),emit=async t=>{let n=await callAdapterEventHandler(l,t,m);setChannelContext(c,{...l,state:{...m.state}});let r=stampMessageStreamEvent(n);return await C.write(encodeMessageStreamEvent(r)),r},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:c,registry:g,event:n}),n.type!==`step.started`&&await dispatchDynamicModelEvent({ctx:c,dynamicModel:u.turnAgent.dynamicModel,event:n,fallback:u.turnAgent.model,messages:t??[],scope:{moduleMap:u.moduleMap,nodeId:u.nodeId}}),await dispatchDynamicToolEvent({ctx:c,resolvers:y,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:c,resolvers:v,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:c,resolvers:_,event:n,messages:t??[]})},w=c.require(ModeKey),T;try{throwIfTurnAborted(o.abortSignal),T=await runStep(c,p,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:u.turnAgent.outputSchema,input:h,mode:w,session:e});if(f){let e=getHarnessEmissionState(t.state);for(let{name:t,authorization:n}of f)await handleEvent(createAuthorizationCompletedEvent({authorization:n,name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=c.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:u.resolvedAgent.config.compaction?.thresholdPercent},session:e,turnAgent:u.turnAgent});return createExecutionNodeStep({abortSignal:o.abortSignal,capabilities:n,createRuntime:createWorkflowRuntime,handleEvent,mode:w,modelResolutionScope:{moduleMap:u.moduleMap,nodeId:u.nodeId},node:u.graph.root,workflowMaxSubagents:r.workflowMaxSubagents})(r,t)})(t,h)})}catch(e){if(!isTurnCancellation(e))throw e;return C.releaseLock(),{action:`cancelled`,serializedContext:preserveSerializedAgentTraceState(o.serializedContext,serializeContext(c)),sessionState:o.sessionState}}let E=reconcileSessionContinuationToken(c,T.session),D=serializeContext(c);T={...T,session:E};let O=createDurableSessionState({session:T.session});if(T.next!==null&&typeof T.next==`object`&&`done`in T.next){await C.close();let e=getTurnUsageState(T.session.state)?.session;return{action:`done`,output:T.next.output,isError:T.next.isError,serializedContext:D,sessionState:O,usage:e===void 0?void 0:toUsage(e)}}if(T.next===null){C.releaseLock();let e=getPendingWorkflowInterrupt(T.session.state);return e!==void 0&&isWorkflowRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-workflow-runtime-actions`,pendingRuntimeActionKeys:getRuntimeActionKeysFromWorkflowInterrupt(e.interrupt),serializedContext:D,sessionState:O}:{action:`park`,...derivePendingState(T.session),serializedContext:D,sessionState:O}}return C.releaseLock(),{action:`continue`,serializedContext:D,sessionState:O}}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state});for(let t of n.forChildren)await resumeHook(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return n.parentAction??{kind:`continue`,remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflowReference,[createTurnWorkflowInput(e)],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,requestId:e.delivery.kind===`deliver`?e.delivery.requestId:void 0,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}))})).runId}}export{dispatchTurnStep,resolveEffectiveOutputSchema,routeProxiedDeliverStep,turnStep};
@@ -1 +1 @@
1
- import{createHash}from"node:crypto";import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";var InMemoryAgentTraceStateStore=class{#e=new Map;#t=new Map;deleteSession(e){this.#e.delete(e)}deleteTurn(e,t){this.#t.delete(turnKey(e,t))}getSession(e){return this.#e.get(e)}getTurn(e,t){return this.#t.get(turnKey(e,t))}setSession(e,t){this.#e.set(e,t)}setTurn(e,t,n){this.#t.set(turnKey(e,t),n)}};function createAgentOtelInstrumentation(e){let t=new WeakMap,n=new WeakMap,onSessionStarted=async e=>{await ensureSessionContext(e)},onTurnStarted=async t=>{let n=await ensureSessionContext({agentName:void 0,channelKind:void 0,rootSessionId:t.rootSessionId,sessionId:t.sessionId,type:`session.started`}),r=e.tracer.startSpan(`agent.turn`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":n.agentName,"agent.root.session.id":t.rootSessionId,"agent.session.id":t.sessionId,"agent.turn.id":t.turnId,"agent.turn.sequence":t.sequence}},contextFromSpanContext(n.context));r.addEvent(`turn.started`),n.pendingStarted&&r.addEvent(`session.started`),await e.stateStore.setSession(t.sessionId,{...n,pendingStarted:!1}),await e.stateStore.setTurn(t.sessionId,t.turnId,{context:r.spanContext(),rootSessionId:t.rootSessionId,sequence:t.sequence}),r.end()},onAttemptStarted=async t=>{let r=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(r===void 0)return;let a=contextFromSpanContext(r.context),o=e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId}},a);o.addEvent(`step.started`);let s=trace.setSpan(a,o),c=t.operation.operationId,l=e.tracer.startSpan(c,{attributes:{"gen_ai.operation.name":c,"gen_ai.provider.name":t.operation.provider,"gen_ai.request.model":t.operation.modelId}},s);n.set(t.scope,{operation:{context:trace.setSpan(s,l),name:c,span:l},step:{context:s,span:o}})},onAttemptTerminal=e=>{t.delete(e.scope);let r=n.get(e.scope);r!==void 0&&(r.step.span.addEvent(e.type===`attempt.completed`?`step.completed`:`step.failed`),e.type===`attempt.failed`&&(recordError(r.operation.span,e.error),recordError(r.step.span,e.error)),r.operation.span.end(),r.step.span.end(),n.delete(e.scope))},onTurnTerminal=async t=>{let n=await e.stateStore.getTurn(t.sessionId,t.turnId);n!==void 0&&await e.stateStore.setTurn(t.sessionId,t.turnId,{...n,terminal:{error:t.error,type:t.type}})},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let r=e.tracer.startSpan(`agent.turn.terminal`,{attributes:{"agent.root.session.id":n.rootSessionId,"agent.session.id":t.sessionId,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence}},contextFromSpanContext(n.context));n.terminal!==void 0&&(r.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(r,n.terminal.error)),r.addEvent(t.type),r.end(),await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&await e.stateStore.deleteSession(t.sessionId)},beforeModelCall=t=>{let r=n.get(t.scope);if(r===void 0)return;r.step.span.setAttribute(`agent.model.id`,t.source.modelId),r.step.span.setAttribute(`agent.model.provider`,t.source.provider);let a=e.tracer.startSpan(modelSpanName(r.operation.name),{attributes:{"gen_ai.operation.name":r.operation.name,"gen_ai.provider.name":t.source.provider,"gen_ai.request.model":t.source.modelId}},r.operation.context),o={context:trace.setSpan(r.operation.context,a),span:a};return getExecutionContexts(t.scope).models.set(t.id,o.context),o},afterModelCall=(e,r)=>{if(t.get(e.scope)?.models.delete(e.id),isSpanState(r)){if(e.type===`model.call.failed`)recordError(r.span,e.error);else{setUsage(r.span,e.source.usage);let t=n.get(e.scope);t!==void 0&&setUsage(t.step.span,e.source.usage)}r.span.end()}},beforeToolCall=t=>{let r=n.get(t.scope);if(r===void 0)return;let a=e.tracer.startSpan(`agent.action`,{attributes:{"agent.action.call_id":t.source.toolCall.toolCallId,"agent.action.kind":`tool`,"agent.action.name":t.source.toolCall.toolName,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.session.id":t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId}},r.step.context),o=trace.setSpan(r.step.context,a),s=e.tracer.startSpan(`ai.toolCall`,{attributes:{"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":t.source.toolCall.toolCallId,"gen_ai.tool.name":t.source.toolCall.toolName}},o),c={context:trace.setSpan(o,s),span:a,toolSpan:s};return getExecutionContexts(t.scope).tools.set(t.id,c.context),c},afterToolCall=(e,n)=>{t.get(e.scope)?.tools.delete(e.id),isToolSpanState(n)&&(e.type===`tool.call.failed`?(recordError(n.toolSpan,e.error),recordError(n.span,e.error)):e.source.toolOutput.type!==`tool-result`&&(recordError(n.toolSpan,e.source.toolOutput.error),recordError(n.span,e.source.toolOutput.error)),n.toolSpan.end(),n.span.end())},ensureSessionContext=async t=>{let n=await e.stateStore.getSession(t.sessionId);return n===void 0&&(n={agentName:t.agentName,channelKind:t.channelKind,context:sessionTraceContext(t.sessionId),pendingStarted:!0,rootSessionId:t.rootSessionId},await e.stateStore.setSession(t.sessionId,n)),n};return{hook:{events:{"attempt.completed":onAttemptTerminal,"attempt.failed":onAttemptTerminal,"attempt.started":onAttemptStarted,"model.call":{after:afterModelCall,before:beforeModelCall},"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,"tool.call":{after:afterToolCall,before:beforeToolCall},"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted}},runInContext(e,n){let i=t.get(e.scope),a=e.type===`model.call`?i?.models.get(e.id):i?.tools.get(e.id);return a===void 0?n():context.with(a,n)}};function getExecutionContexts(e){let n=t.get(e);return n===void 0&&(n={models:new Map,tools:new Map},t.set(e,n)),n}}function turnKey(e,t){return`${e}:${t}`}function sessionTraceContext(e){return{spanId:digestId(`eve:session-parent:${e}`,16),traceFlags:1,traceId:digestId(`eve:session:${e}`,32)}}function digestId(t,n){return createHash(`sha256`).update(t).digest(`hex`).slice(0,n)}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function isSpanState(e){return typeof e==`object`&&!!e&&`context`in e&&`span`in e}function isToolSpanState(e){return isSpanState(e)&&`toolSpan`in e}function modelSpanName(e){return e===`ai.generateText`?`ai.generateText.doGenerate`:`ai.streamText.doStream`}function setUsage(e,t){t.inputTokens!==void 0&&e.setAttribute(`agent.usage.input_tokens`,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(`agent.usage.output_tokens`,t.outputTokens)}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{InMemoryAgentTraceStateStore,createAgentOtelInstrumentation};
1
+ import{createHash}from"node:crypto";import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";var InMemoryAgentTraceStateStore=class{#e=new Map;#t=new Map;deleteSession(e){this.#e.delete(e)}deleteTurn(e,t){this.#t.delete(turnKey(e,t))}getSession(e){return this.#e.get(e)}getTurn(e,t){return this.#t.get(turnKey(e,t))}setSession(e,t){this.#e.set(e,t)}setTurn(e,t,n){this.#t.set(turnKey(e,t),n)}};function createAgentOtelInstrumentation(e){let t=new WeakMap,n=new WeakMap,onSessionStarted=async e=>{await ensureSessionContext(e)},onTurnStarted=async t=>{let n=await ensureSessionContext({agentName:void 0,channelKind:void 0,rootSessionId:t.rootSessionId,sessionId:t.sessionId,type:`session.started`}),r=e.tracer.startSpan(`agent.turn`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":n.agentName,"agent.root.session.id":t.rootSessionId,"agent.session.id":t.sessionId,"agent.turn.id":t.turnId,"agent.turn.sequence":t.sequence}},contextFromSpanContext(n.context));r.addEvent(`turn.started`),n.pendingStarted&&r.addEvent(`session.started`),await e.stateStore.setSession(t.sessionId,{...n,pendingStarted:!1}),await e.stateStore.setTurn(t.sessionId,t.turnId,{context:r.spanContext(),rootSessionId:t.rootSessionId,sequence:t.sequence}),r.end()},onAttemptStarted=async t=>{let r=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(r===void 0)return;let a=contextFromSpanContext(r.context),o=e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId}},a);o.addEvent(`step.started`);let s=trace.setSpan(a,o),c=t.operation.operationId,l=e.tracer.startSpan(c,{attributes:{"gen_ai.operation.name":c,"gen_ai.provider.name":t.operation.provider,"gen_ai.request.model":t.operation.modelId}},s);n.set(t.scope,{operation:{context:trace.setSpan(s,l),name:c,span:l},step:{context:s,span:o}})},onAttemptTerminal=e=>{t.delete(e.scope);let r=n.get(e.scope);r!==void 0&&(r.step.span.addEvent(e.type===`attempt.completed`?`step.completed`:`step.failed`),e.type===`attempt.failed`&&(recordError(r.operation.span,e.error),recordError(r.step.span,e.error)),r.operation.span.end(),r.step.span.end(),n.delete(e.scope))},onTurnTerminal=async t=>{let n=await e.stateStore.getTurn(t.sessionId,t.turnId);n!==void 0&&await e.stateStore.setTurn(t.sessionId,t.turnId,{...n,terminal:{error:t.error,type:t.type}})},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let r=e.tracer.startSpan(`agent.turn.terminal`,{attributes:{"agent.root.session.id":n.rootSessionId,"agent.session.id":t.sessionId,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence}},contextFromSpanContext(n.context));n.terminal!==void 0&&(r.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(r,n.terminal.error)),r.addEvent(t.type),r.end(),await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&await e.stateStore.deleteSession(t.sessionId)},beforeModelCall=t=>{let r=n.get(t.scope);if(r===void 0)return;r.step.span.setAttribute(`agent.model.id`,t.source.modelId),r.step.span.setAttribute(`agent.model.provider`,t.source.provider);let a=e.tracer.startSpan(modelSpanName(r.operation.name),{attributes:{"gen_ai.operation.name":r.operation.name,"gen_ai.provider.name":t.source.provider,"gen_ai.request.model":t.source.modelId}},r.operation.context),o={context:trace.setSpan(r.operation.context,a),span:a};return getExecutionContexts(t.scope).models.set(t.id,o.context),o},afterModelCall=(e,r)=>{if(t.get(e.scope)?.models.delete(e.id),isSpanState(r)){if(e.type===`model.call.failed`)recordError(r.span,e.error);else{setUsage(r.span,e.source.usage);let t=n.get(e.scope);t!==void 0&&setUsage(t.step.span,e.source.usage)}r.span.end()}},beforeToolCall=t=>{let r=n.get(t.scope);if(r===void 0)return;let a=e.tracer.startSpan(`agent.action`,{attributes:{"agent.action.call_id":t.source.toolCall.toolCallId,"agent.action.kind":`tool`,"agent.action.name":t.source.toolCall.toolName,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.session.id":t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId}},r.step.context),o=trace.setSpan(r.step.context,a),s=e.tracer.startSpan(`ai.toolCall`,{attributes:{"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":t.source.toolCall.toolCallId,"gen_ai.tool.name":t.source.toolCall.toolName}},o),c={context:trace.setSpan(o,s),span:a,toolSpan:s};return getExecutionContexts(t.scope).tools.set(t.id,c.context),c},afterToolCall=(e,n)=>{t.get(e.scope)?.tools.delete(e.id),isToolSpanState(n)&&(e.type===`tool.call.failed`?(recordError(n.toolSpan,e.error),recordError(n.span,e.error)):e.source.toolOutput.type!==`tool-result`&&(recordError(n.toolSpan,e.source.toolOutput.error),recordError(n.span,e.source.toolOutput.error)),n.toolSpan.end(),n.span.end())},ensureSessionContext=async t=>{let n=await e.stateStore.getSession(t.sessionId);return n===void 0&&(n={agentName:t.agentName,channelKind:t.channelKind,context:sessionTraceContext(t.sessionId),pendingStarted:!0,rootSessionId:t.rootSessionId},await e.stateStore.setSession(t.sessionId,n)),n};return{hook:{events:{"attempt.completed":onAttemptTerminal,"attempt.failed":onAttemptTerminal,"attempt.metadata":e=>{let t=n.get(e.scope);if(t===void 0)return;let r=readGatewayCost(e.providerMetadata);if(r!==void 0)for(let[e,n]of Object.entries(r))t.step.span.setAttribute(e,n)},"attempt.started":onAttemptStarted,"model.call":{after:afterModelCall,before:beforeModelCall},"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,"tool.call":{after:afterToolCall,before:beforeToolCall},"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted}},runInContext(e,n){let i=t.get(e.scope),a=e.type===`model.call`?i?.models.get(e.id):i?.tools.get(e.id);return a===void 0?n():context.with(a,n)}};function getExecutionContexts(e){let n=t.get(e);return n===void 0&&(n={models:new Map,tools:new Map},t.set(e,n)),n}}function turnKey(e,t){return`${e}:${t}`}function sessionTraceContext(e){return{spanId:digestId(`eve:session-parent:${e}`,16),traceFlags:1,traceId:digestId(`eve:session:${e}`,32)}}function digestId(t,n){return createHash(`sha256`).update(t).digest(`hex`).slice(0,n)}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function readGatewayCost(e){let t=e.gateway;if(!isRecord(t))return;let n={},r=readUsd(t.cost);r!==void 0&&(n[`gen_ai.usage.cost`]=r);let i=readUsd(t.gatewayCost);i!==void 0&&(n[`gen_ai.usage.gateway_cost`]=i);let a=readUsd(t.inputInferenceCost);a!==void 0&&(n[`gen_ai.usage.input_cost`]=a);let o=readUsd(t.outputInferenceCost);return o!==void 0&&(n[`gen_ai.usage.output_cost`]=o),typeof t.generationId==`string`&&t.generationId.length>0&&(n[`gen_ai.generation.id`]=t.generationId),Object.keys(n).length===0?void 0:n}function readUsd(e){if(typeof e!=`string`)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function isSpanState(e){return typeof e==`object`&&!!e&&`context`in e&&`span`in e}function isToolSpanState(e){return isSpanState(e)&&`toolSpan`in e}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function modelSpanName(e){return e===`ai.generateText`?`ai.generateText.doGenerate`:`ai.streamText.doStream`}function setUsage(e,t){t.inputTokens!==void 0&&e.setAttribute(`agent.usage.input_tokens`,t.inputTokens),t.outputTokens!==void 0&&e.setAttribute(`agent.usage.output_tokens`,t.outputTokens);let n=t.inputTokenDetails;n?.cacheReadTokens!==void 0&&e.setAttribute(`gen_ai.usage.cache_read.input_tokens`,n.cacheReadTokens),n?.cacheWriteTokens!==void 0&&e.setAttribute(`gen_ai.usage.cache_creation.input_tokens`,n.cacheWriteTokens)}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{InMemoryAgentTraceStateStore,createAgentOtelInstrumentation};
@@ -1 +1 @@
1
- function createAiSdkHookBridge(e,t,n=directRunInContext){let r={modelIds:new Map,scope:e,toolIds:new Map};return{onStart(e){r.operationStart=snapshot(e)},async onStepStart(e){r.stepStart=snapshot(e);let n=toAttemptStarted(r);n!==void 0&&await t.publish(n)},async onLanguageModelCallStart(e){let n=createModelCallIdentity(r,e.callId);r.modelIds.set(e.callId,n);let i=toModelCallStarted(r,n,e);await t.before(`model.call`,i)},executeLanguageModelCall({callId:t,execute:i}){let a=r.modelIds.get(t);return a===void 0?i():n({id:a,scope:e,type:`model.call`},i)},async onLanguageModelCallEnd(e){let n=r.modelIds.get(e.callId);if(n===void 0)return;r.modelIds.delete(e.callId);let i=toModelCallCompleted(r,n,e);await t.after(`model.call`,i)},async onToolExecutionStart(e){let n=createToolCallIdentity(r,e.toolCall.toolCallId);r.toolIds.set(e.toolCall.toolCallId,n);let i=toToolCallStarted(r,n,e);await t.before(`tool.call`,i)},executeTool({toolCallId:t,execute:i}){let a=r.toolIds.get(t);return a===void 0?i():n({id:a,scope:e,type:`tool.call`},i)},async onToolExecutionEnd(e){let n=e.toolCall.toolCallId,i=r.toolIds.get(n);if(i===void 0)return;r.toolIds.delete(n);let a=toToolCallCompleted(r,i,e);await t.after(`tool.call`,a)},async onAbort(e){await failOpenOperations(e)},async onError(e){await failOpenOperations(e)}};async function failOpenOperations(n){let i=[];for(let a of r.modelIds.values())i.push(t.after(`model.call`,{error:n,id:a,scope:e,type:`model.call.failed`}));for(let a of r.toolIds.values())i.push(t.after(`tool.call`,{error:n,id:a,scope:e,type:`tool.call.failed`}));r.modelIds.clear(),r.toolIds.clear(),await Promise.all(i)}}const directRunInContext=(e,t)=>t();function snapshot(e){return Object.freeze({...e})}function toAttemptStarted(e){if(!(e.operationStart===void 0||e.stepStart===void 0))return{operation:e.operationStart,scope:e.scope,step:e.stepStart,type:`attempt.started`}}function createModelCallIdentity(e,t){return`${e.scope.attemptId}:model:${t}:${e.stepStart?.stepNumber??0}`}function toModelCallStarted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`model.call.started`}}function toModelCallCompleted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`model.call.completed`}}function createToolCallIdentity(e,t){return`${e.scope.attemptId}:tool:${t}:${e.stepStart?.stepNumber??0}`}function toToolCallStarted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`tool.call.started`}}function toToolCallCompleted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`tool.call.completed`}}export{createAiSdkHookBridge};
1
+ function createAiSdkHookBridge(e,t,n=directRunInContext){let r={modelIds:new Map,scope:e,toolIds:new Map};return{onStart(e){r.operationStart=snapshot(e)},async onStepStart(e){r.stepStart=snapshot(e);let n=toAttemptStarted(r);n!==void 0&&await t.publish(n)},async onLanguageModelCallStart(e){let n=createModelCallIdentity(r,e.callId);r.modelIds.set(e.callId,n);let i=toModelCallStarted(r,n,e);await t.before(`model.call`,i)},executeLanguageModelCall({callId:t,execute:i}){let a=r.modelIds.get(t);return a===void 0?i():n({id:a,scope:e,type:`model.call`},i)},async onLanguageModelCallEnd(e){let n=r.modelIds.get(e.callId);if(n===void 0)return;r.modelIds.delete(e.callId);let i=toModelCallCompleted(r,n,e);await t.after(`model.call`,i)},async onStepEnd(e){e.providerMetadata!==void 0&&await t.publish({providerMetadata:e.providerMetadata,scope:r.scope,type:`attempt.metadata`})},async onToolExecutionStart(e){let n=createToolCallIdentity(r,e.toolCall.toolCallId);r.toolIds.set(e.toolCall.toolCallId,n);let i=toToolCallStarted(r,n,e);await t.before(`tool.call`,i)},executeTool({toolCallId:t,execute:i}){let a=r.toolIds.get(t);return a===void 0?i():n({id:a,scope:e,type:`tool.call`},i)},async onToolExecutionEnd(e){let n=e.toolCall.toolCallId,i=r.toolIds.get(n);if(i===void 0)return;r.toolIds.delete(n);let a=toToolCallCompleted(r,i,e);await t.after(`tool.call`,a)},async onAbort(e){await failOpenOperations(e)},async onError(e){await failOpenOperations(e)}};async function failOpenOperations(n){let i=[];for(let a of r.modelIds.values())i.push(t.after(`model.call`,{error:n,id:a,scope:e,type:`model.call.failed`}));for(let a of r.toolIds.values())i.push(t.after(`tool.call`,{error:n,id:a,scope:e,type:`tool.call.failed`}));r.modelIds.clear(),r.toolIds.clear(),await Promise.all(i)}}const directRunInContext=(e,t)=>t();function snapshot(e){return Object.freeze({...e})}function toAttemptStarted(e){if(!(e.operationStart===void 0||e.stepStart===void 0))return{operation:e.operationStart,scope:e.scope,step:e.stepStart,type:`attempt.started`}}function createModelCallIdentity(e,t){return`${e.scope.attemptId}:model:${t}:${e.stepStart?.stepNumber??0}`}function toModelCallStarted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`model.call.started`}}function toModelCallCompleted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`model.call.completed`}}function createToolCallIdentity(e,t){return`${e.scope.attemptId}:tool:${t}:${e.stepStart?.stepNumber??0}`}function toToolCallStarted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`tool.call.started`}}function toToolCallCompleted(e,t,n){return{id:t,scope:e.scope,source:snapshot(n),type:`tool.call.completed`}}export{createAiSdkHookBridge};
@@ -1 +1 @@
1
- import{boolean,literal,object,string,unknown}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{createRuntimeToolCallActionFromToolCall}from"#harness/input-requests.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";const ToolCallDescriptorSchema=object({input:unknown(),toolCallId:string(),toolName:string()}),PersistedToolCallSchema=ToolCallDescriptorSchema.extend({type:literal(`tool-call`)}),ToolApprovalRequestSchema=object({approvalId:string(),isAutomatic:boolean().optional().catch(void 0),toolCall:ToolCallDescriptorSchema.optional().catch(void 0),toolCallId:string().optional().catch(void 0),type:literal(`tool-approval-request`)});function extractQuestionInputRequests(e){return extractQuestionRequests(e)}function extractQuestionRequests(e){let t=[];for(let n of e.toolCalls){if(n.toolName!==ASK_QUESTION_TOOL_NAME||e.excludedCallIds.has(n.toolCallId))continue;let r=createRuntimeToolCallActionFromToolCall({toolCall:n}),i=r.input,s={action:r,display:`text`,prompt:String(i.prompt),requestId:r.callId};i.allowFreeform!==void 0&&(s.allowFreeform=i.allowFreeform),i.options!==void 0&&(s.options=i.options,s.display=`select`),t.push(s)}return t}function extractToolApprovalInputRequests(e){return extractApprovalRequests(e)}function extractApprovalRequests(e){let t=[],n=new Map;for(let t of e.content){let e=PersistedToolCallSchema.safeParse(t);e.success&&n.set(e.data.toolCallId,e.data)}for(let r of e.content){let i=ToolApprovalRequestSchema.safeParse(r);if(!i.success)continue;let o=i.data;if(e.includedRequestIds!==void 0&&!e.includedRequestIds.has(o.approvalId)||o.isAutomatic===!0)continue;let s=o.toolCall??(o.toolCallId===void 0?void 0:n.get(o.toolCallId));s!==void 0&&(e.excludedCallIds?.has(s.toolCallId)||t.push({action:createRuntimeToolCallActionFromToolCall({toolCall:s}),allowFreeform:!1,display:`confirmation`,options:[{id:`approve`,label:`Yes`},{id:`deny`,label:`No`}],prompt:`Approve tool call: ${s.toolName}`,requestId:o.approvalId}))}return t}function extractHistoricalInputRequests(e){let t=new Map;for(let n=e.history.length-1;n>=0;--n){let r=e.history[n];if(r?.role!==`assistant`||!Array.isArray(r.content))continue;let i=r.content.flatMap(t=>{let n=PersistedToolCallSchema.safeParse(t);return n.success&&e.requestIds.has(n.data.toolCallId)?[n.data]:[]}),a=[...extractQuestionRequests({excludedCallIds:new Set,toolCalls:i}),...extractApprovalRequests({content:r.content,includedRequestIds:e.requestIds})];for(let n of a)!e.requestIds.has(n.requestId)||t.has(n.requestId)||t.set(n.requestId,n);if(t.size===e.requestIds.size)break}return t}export{extractHistoricalInputRequests,extractQuestionInputRequests,extractToolApprovalInputRequests};
1
+ import{boolean,literal,object,string,unknown}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{createRuntimeToolCallActionFromToolCall}from"#harness/input-requests.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";const ToolCallDescriptorSchema=object({input:unknown(),toolCallId:string(),toolName:string()}),PersistedToolCallSchema=ToolCallDescriptorSchema.extend({type:literal(`tool-call`)}),ToolApprovalRequestSchema=object({approvalId:string(),isAutomatic:boolean().optional().catch(void 0),toolCall:ToolCallDescriptorSchema.optional().catch(void 0),toolCallId:string().optional().catch(void 0),type:literal(`tool-approval-request`)});function extractQuestionInputRequests(e){return extractQuestionRequests(e)}function extractQuestionRequests(e){let t=[];for(let n of e.toolCalls){if(n.toolName!==ASK_QUESTION_TOOL_NAME||e.excludedCallIds.has(n.toolCallId))continue;let r=createRuntimeToolCallActionFromToolCall({toolCall:n}),i=r.input,s={action:r,display:`text`,kind:`question`,prompt:String(i.prompt),requestId:r.callId};i.allowFreeform!==void 0&&(s.allowFreeform=i.allowFreeform),i.options!==void 0&&(s.options=i.options,s.display=`select`),t.push(s)}return t}function extractToolApprovalInputRequests(e){return extractApprovalRequests(e)}function extractApprovalRequests(e){let t=[],n=new Map;for(let t of e.content){let e=PersistedToolCallSchema.safeParse(t);e.success&&n.set(e.data.toolCallId,e.data)}for(let r of e.content){let i=ToolApprovalRequestSchema.safeParse(r);if(!i.success)continue;let o=i.data;if(e.includedRequestIds!==void 0&&!e.includedRequestIds.has(o.approvalId)||o.isAutomatic===!0)continue;let s=o.toolCall??(o.toolCallId===void 0?void 0:n.get(o.toolCallId));s!==void 0&&(e.excludedCallIds?.has(s.toolCallId)||t.push({action:createRuntimeToolCallActionFromToolCall({toolCall:s}),allowFreeform:!1,display:`confirmation`,kind:`tool-approval`,options:[{id:`approve`,label:`Yes`},{id:`deny`,label:`No`}],prompt:`Approve tool call: ${s.toolName}`,requestId:o.approvalId}))}return t}function extractHistoricalInputRequests(e){let t=new Map;for(let n=e.history.length-1;n>=0;--n){let r=e.history[n];if(r?.role!==`assistant`||!Array.isArray(r.content))continue;let i=r.content.flatMap(t=>{let n=PersistedToolCallSchema.safeParse(t);return n.success&&e.requestIds.has(n.data.toolCallId)?[n.data]:[]}),a=[...extractQuestionRequests({excludedCallIds:new Set,toolCalls:i}),...extractApprovalRequests({content:r.content,includedRequestIds:e.requestIds})];for(let n of a)!e.requestIds.has(n.requestId)||t.has(n.requestId)||t.set(n.requestId,n);if(t.size===e.requestIds.size)break}return t}export{extractHistoricalInputRequests,extractQuestionInputRequests,extractToolApprovalInputRequests};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shape and behavior classification for pending input requests, shared by
3
+ * the harness resolution path and protocol clients (e.g. the dev TUI's
4
+ * rendering decisions).
5
+ */
6
+ import type { InputRequest } from "#runtime/input/types.js";
7
+ /** Returns true when the request gates an AI SDK tool call. */
8
+ export declare function isApprovalRequest(request: InputRequest): boolean;
9
+ /**
10
+ * Behavioral class of a pending input request.
11
+ *
12
+ * `"required"` — the request must be explicitly answered before the turn can
13
+ * move on. While one is unanswered, any other arriving input is queued and
14
+ * replayed on the step after the answer. The pending batch never churns, so
15
+ * the request ids the user is answering stay valid.
16
+ *
17
+ * `"dismissable"` — a plain follow-up message counts as the user moving on.
18
+ * The request resolves as a real `tool-result` with `status: "ignored"` and
19
+ * the model continues with the message in the same step.
20
+ */
21
+ export type InputRequestClass = "dismissable" | "required";
22
+ /** Classifies one pending request; see {@link InputRequestClass}. */
23
+ export declare function classifyInputRequest(request: InputRequest): InputRequestClass;
@@ -0,0 +1 @@
1
+ function isApprovalRequest(e){return e.kind===`tool-approval`}function classifyInputRequest(e){switch(e.kind){case`tool-approval`:return`required`;case`session-limit`:return`required`;case`question`:return`dismissable`;default:return e.kind}}export{classifyInputRequest,isApprovalRequest};
@@ -45,13 +45,13 @@ export declare function hasDeferredStepInput(session: HarnessSession): boolean;
45
45
  /**
46
46
  * Resolves pending input at the start of a harness step.
47
47
  *
48
- * When the pending batch contains tool-approval requests and the step input
49
- * also carries a follow-up user message, the message is deferred to the next
50
- * internal harness step rather than appended to the current turn. This is
51
- * necessary because AI SDK cannot process tool-approval responses and a new
52
- * user message in the same request -- the approval must be resolved in
53
- * isolation first, and the user message replayed on the subsequent step via
54
- * {@link consumeDeferredStepInput}.
48
+ * Each pending request is either `"required"` or `"dismissable"` — see
49
+ * {@link classifyInputRequest}. While a required request is unanswered,
50
+ * follow-up input is deferred instead of dismissing and recreating the
51
+ * request; {@link consumeDeferredStepInput} replays it on the subsequent
52
+ * step. Tool approval responses additionally resolve in isolation because
53
+ * AI SDK cannot process an approval response and a new user message in the
54
+ * same request.
55
55
  */
56
56
  export declare function resolvePendingInput(input: {
57
57
  readonly history?: readonly ModelMessage[];
@@ -59,6 +59,19 @@ export declare function resolvePendingInput(input: {
59
59
  readonly session: HarnessSession;
60
60
  readonly stepInput?: StepInput;
61
61
  }): ResolvePendingInputResult;
62
+ /**
63
+ * Drops a pending session-limit continuation prompt from a parked session.
64
+ *
65
+ * A cancelled turn settles with the step's input snapshot, which can
66
+ * resurrect a continuation prompt the user already answered — the decline
67
+ * that cancelled the turn consumed the answer inside the discarded turn
68
+ * state. Left in place, the stale prompt would queue every follow-up
69
+ * message behind an answer that will never come. Harness-authored prompts
70
+ * are deterministically re-raised by the pre-model gate, so dropping is
71
+ * always safe; model-anchored batches (tool approvals, questions) are kept
72
+ * because their tool calls still require resolution.
73
+ */
74
+ export declare function clearPendingSessionLimitPrompt(session: HarnessSession): HarnessSession;
62
75
  type ResolvePendingInputResult = {
63
76
  readonly consumedMessage?: boolean;
64
77
  readonly deferredContext?: boolean;
@@ -99,8 +112,6 @@ export declare function setPendingInputBatch(input: {
99
112
  * during this session.
100
113
  */
101
114
  export declare function getApprovedTools(session: HarnessSession): ReadonlySet<string>;
102
- /** Shared approval predicate: a request whose options are exactly `approve` / `deny`. */
103
- export declare function isApprovalRequest(request: InputRequest): boolean;
104
115
  /**
105
116
  * Creates a runtime tool-call action shape from an AI SDK tool call.
106
117
  */
@@ -1 +1 @@
1
- import{resolveTextToResponses}from"#channel/resolve-text.js";import{resolveToolCallInputObject}from"#harness/runtime-actions.js";import{coalesceTurnInputs}from"#harness/messages.js";import{isSessionLimitContinuationRequest,resolveSessionLimitContinuation}from"#harness/session-limit-continuation.js";const PENDING_INPUT_BATCH_KEY=`eve.runtime.pendingInputBatch`,APPROVED_TOOLS_KEY=`eve.runtime.hitl.approvedTools`,DEFERRED_STEP_INPUT_KEY=`eve.runtime.deferredStepInput`,TOOL_EXECUTION_DENIED_MESSAGE=`Tool execution was denied.`;function hasStepInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}function consumeDeferredStepInput(e){let t=getDeferredStepInput(e.session);if(t===void 0)return e;let r=clearDeferredStepInput(e.session);return e.input===void 0?{input:t,session:r}:{input:coalesceTurnInputs(t,e.input),session:r}}function hasDeferredStepInput(e){return getDeferredStepInput(e)!==void 0}function resolvePendingInput(e){let{stepInput:t}=e,n=e.session,r=[...e.history??n.history],a=getPendingInputBatch(n.state);if(a===void 0)return{outcome:`continue`,messages:r,session:n};let o=resolveTextMessageInput(a,t),s=o?.inputResponses??[],c=a.requests.some(e=>isApprovalRequest(e));if(s.length===0&&o?.message===void 0)return{outcome:`unresolved`,messages:r,session:n};if(c&&hasUnansweredApproval({pendingBatch:a,responses:s}))return n=queueDeferredStepInput(n,compactStepInput(o)),{deferredMessage:!0,outcome:`unresolved`,messages:r,session:n};if(s.length===0&&o?.message!==void 0){let e=buildToolResponseParts(a,[]),t=[...r,...a.responseMessages];e.length>0&&t.push({content:e,role:`tool`});let i=buildRejectedActionBatch(a,[]);return n=clearPendingInputBatch(n),{consumedMessage:o?.messageConsumed,outcome:`resolved`,messages:t,rejectedActions:i,session:n}}let l=resolveSessionLimitContinuation({requests:a.requests,responses:s});n=recordApprovedTools({pendingBatch:a,resolveApprovalKey:e.resolveApprovalKey,responses:s,session:n});let u=buildToolResponseParts(a,s),d=[...r,...a.responseMessages];u.length>0&&d.push({content:u,role:`tool`});let f=buildRejectedActionBatch(a,s);if(n=clearPendingInputBatch(n),c){let e={};if((o?.context?.length??0)>0&&(e.context=o?.context),o?.message!==void 0&&(e.message=o.message),e.context!==void 0||e.message!==void 0)return n=queueDeferredStepInput(n,e),{consumedMessage:o?.messageConsumed,deferredContext:e.context!==void 0||void 0,deferredMessage:e.message!==void 0||void 0,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}return{consumedMessage:o?.messageConsumed,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}function resolveTextMessageInput(t,n){if(typeof n?.message!=`string`||(n.inputResponses?.length??0)>0)return n;let r=resolveTextToResponses(n.message,t.requests);return r.length===0?n:compactStepInput({...n,inputResponses:r,messageConsumed:!0,message:void 0})}function compactStepInput(e){if(e===void 0)return{};let t={};return(e.context?.length??0)>0&&(t.context=e.context),(e.inputResponses?.length??0)>0&&(t.inputResponses=e.inputResponses),e.message!==void 0&&(t.message=e.message),e.messageConsumed===!0&&(t.messageConsumed=!0),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),t}function hasUnansweredApproval(e){let t=new Set(e.responses.map(e=>e.requestId));return e.pendingBatch.requests.some(e=>isApprovalRequest(e)&&!t.has(e.requestId))}function hasPendingInputBatch(e){return getPendingInputBatch(e)!==void 0}function getPendingInputRequestIds(e){return new Set(getPendingInputBatch(e)?.requests.map(e=>e.requestId))}function getPendingInputBatch(e){let t=e?.[PENDING_INPUT_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.requests)||!Array.isArray(n.responseMessages)))return n}function setPendingInputBatch(e){let t={...e.session.state};return t[PENDING_INPUT_BATCH_KEY]={event:e.event,requests:[...e.requests],responseMessages:[...e.responseMessages]},{...e.session,state:t}}function clearPendingInputBatch(e){if(e.state?.[PENDING_INPUT_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_INPUT_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getDeferredStepInput(e){return e.state?.[DEFERRED_STEP_INPUT_KEY]}function queueDeferredStepInput(e,t){let r=getDeferredStepInput(e),i=r===void 0?t:coalesceTurnInputs(r,t),a={...e.state};return a[DEFERRED_STEP_INPUT_KEY]=i,{...e,state:a}}function clearDeferredStepInput(e){if(e.state?.[DEFERRED_STEP_INPUT_KEY]===void 0)return e;let t={...e.state};return delete t[DEFERRED_STEP_INPUT_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getApprovedTools(e){let t=e.state?.[APPROVED_TOOLS_KEY];return Array.isArray(t)?new Set(t):new Set}function recordApprovedTools(e){let t=new Set(e.responses.filter(e=>e.optionId===`approve`).map(e=>e.requestId)),n=e.pendingBatch.requests.filter(e=>t.has(e.requestId)).map(t=>e.resolveApprovalKey?.(t)??t.action.toolName);if(n.length===0)return e.session;let r=getApprovedTools(e.session),i=[...new Set([...r,...n])],a={...e.session.state};return a[APPROVED_TOOLS_KEY]=i,{...e.session,state:a}}function resolveApprovalOutcome(e){return e===void 0?{approved:!1,reason:`Ignored because the user continued without responding.`,status:`ignored`}:e.optionId===`approve`?{approved:!0,reason:void 0,status:`approved`}:e.optionId===`deny`?{approved:!1,reason:TOOL_EXECUTION_DENIED_MESSAGE,status:`denied`}:{approved:!1,reason:`Invalid approval response.`,status:`invalid`}}function buildRejectedActionBatch(e,t){if(e.event===void 0)return;let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests){if(!isApprovalRequest(t))continue;let{approved:e,reason:i,status:a}=resolveApprovalOutcome(n.get(t.requestId));e||r.push({callId:t.action.callId,isError:!0,kind:`tool-result`,output:{approval:{requestId:t.requestId,status:a},code:`TOOL_EXECUTION_DENIED`,message:i??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}},toolName:t.action.toolName})}return r.length>0?{event:e.event,results:r}:void 0}function buildToolResponseParts(e,t){let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests)r.push(...buildToolResponsePartsForRequest(t,n.get(t.requestId)));return r}function buildToolResponsePartsForRequest(e,t){if(isSessionLimitContinuationRequest(e))return[];if(isApprovalRequest(e)){let{approved:n,reason:r}=resolveApprovalOutcome(t),i=[{approvalId:e.requestId,approved:n,reason:r,type:`tool-approval-response`}];return n||i.push({output:{type:`execution-denied`,reason:r},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}),i}return[{output:{type:`json`,value:t===void 0?{status:`ignored`}:{optionId:t.optionId,text:t.text,status:`answered`}},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}]}function isApprovalRequest(e){return e.options?.length===2&&e.options[0]?.id===`approve`&&e.options[1]?.id===`deny`}function createRuntimeToolCallActionFromToolCall(e){return{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}export{consumeDeferredStepInput,createRuntimeToolCallActionFromToolCall,getApprovedTools,getPendingInputRequestIds,hasDeferredStepInput,hasPendingInputBatch,hasStepInput,isApprovalRequest,resolvePendingInput,setPendingInputBatch};
1
+ import{resolveTextToResponses}from"#channel/resolve-text.js";import{resolveToolCallInputObject}from"#harness/runtime-actions.js";import{coalesceTurnInputs}from"#harness/messages.js";import{isSessionLimitContinuationRequest,resolveSessionLimitContinuation}from"#harness/session-limit-continuation.js";import{classifyInputRequest,isApprovalRequest}from"#harness/input-request-class.js";const PENDING_INPUT_BATCH_KEY=`eve.runtime.pendingInputBatch`,APPROVED_TOOLS_KEY=`eve.runtime.hitl.approvedTools`,DEFERRED_STEP_INPUT_KEY=`eve.runtime.deferredStepInput`,TOOL_EXECUTION_DENIED_MESSAGE=`Tool execution was denied.`;function hasStepInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}function consumeDeferredStepInput(e){let t=getDeferredStepInput(e.session);if(t===void 0)return e;let r=clearDeferredStepInput(e.session);return e.input===void 0?{input:t,session:r}:{input:coalesceTurnInputs(t,e.input),session:r}}function hasDeferredStepInput(e){return getDeferredStepInput(e)!==void 0}function resolvePendingInput(e){let{stepInput:t}=e,n=e.session,r=[...e.history??n.history],a=getPendingInputBatch(n.state);if(a===void 0)return{outcome:`continue`,messages:r,session:n};let o=resolveTextMessageInput(a,t),s=o?.inputResponses??[],c=a.requests.some(e=>isApprovalRequest(e));if(s.length===0&&o?.message===void 0)return{outcome:`unresolved`,messages:r,session:n};if(hasUnansweredRequiredRequest({pendingBatch:a,responses:s}))return n=queueDeferredStepInput(n,compactStepInput(o)),{deferredMessage:!0,outcome:`unresolved`,messages:r,session:n};if(s.length===0&&o?.message!==void 0){let e=buildToolResponseParts(a,[]),t=[...r,...a.responseMessages];e.length>0&&t.push({content:e,role:`tool`});let i=buildRejectedActionBatch(a,[]);return n=clearPendingInputBatch(n),{consumedMessage:o?.messageConsumed,outcome:`resolved`,messages:t,rejectedActions:i,session:n}}let l=resolveSessionLimitContinuation({requests:a.requests,responses:s});n=recordApprovedTools({pendingBatch:a,resolveApprovalKey:e.resolveApprovalKey,responses:s,session:n});let u=buildToolResponseParts(a,s),d=[...r,...a.responseMessages];u.length>0&&d.push({content:u,role:`tool`});let f=buildRejectedActionBatch(a,s);if(n=clearPendingInputBatch(n),c){let e={};if((o?.context?.length??0)>0&&(e.context=o?.context),o?.message!==void 0&&(e.message=o.message),e.context!==void 0||e.message!==void 0)return n=queueDeferredStepInput(n,e),{consumedMessage:o?.messageConsumed,deferredContext:e.context!==void 0||void 0,deferredMessage:e.message!==void 0||void 0,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}return{consumedMessage:o?.messageConsumed,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}function resolveTextMessageInput(t,n){if(typeof n?.message!=`string`||(n.inputResponses?.length??0)>0)return n;let r=resolveTextToResponses(n.message,t.requests);return r.length===0?n:compactStepInput({...n,inputResponses:r,messageConsumed:!0,message:void 0})}function compactStepInput(e){if(e===void 0)return{};let t={};return(e.context?.length??0)>0&&(t.context=e.context),(e.inputResponses?.length??0)>0&&(t.inputResponses=e.inputResponses),e.message!==void 0&&(t.message=e.message),e.messageConsumed===!0&&(t.messageConsumed=!0),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),t}function clearPendingSessionLimitPrompt(e){let t=getPendingInputBatch(e.state);return t===void 0||t.requests.length===0||!t.requests.every(e=>isSessionLimitContinuationRequest(e))?e:clearPendingInputBatch(e)}function hasUnansweredRequiredRequest(e){let t=new Set(e.responses.map(e=>e.requestId));return e.pendingBatch.requests.some(e=>classifyInputRequest(e)===`required`&&!t.has(e.requestId))}function hasPendingInputBatch(e){return getPendingInputBatch(e)!==void 0}function getPendingInputRequestIds(e){return new Set(getPendingInputBatch(e)?.requests.map(e=>e.requestId))}function getPendingInputBatch(e){let t=e?.[PENDING_INPUT_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.requests)||!Array.isArray(n.responseMessages)))return n}function setPendingInputBatch(e){let t={...e.session.state};return t[PENDING_INPUT_BATCH_KEY]={event:e.event,requests:[...e.requests],responseMessages:[...e.responseMessages]},{...e.session,state:t}}function clearPendingInputBatch(e){if(e.state?.[PENDING_INPUT_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_INPUT_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getDeferredStepInput(e){return e.state?.[DEFERRED_STEP_INPUT_KEY]}function queueDeferredStepInput(e,t){let r=getDeferredStepInput(e),i=r===void 0?t:coalesceTurnInputs(r,t),a={...e.state};return a[DEFERRED_STEP_INPUT_KEY]=i,{...e,state:a}}function clearDeferredStepInput(e){if(e.state?.[DEFERRED_STEP_INPUT_KEY]===void 0)return e;let t={...e.state};return delete t[DEFERRED_STEP_INPUT_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getApprovedTools(e){let t=e.state?.[APPROVED_TOOLS_KEY];return Array.isArray(t)?new Set(t):new Set}function recordApprovedTools(e){let t=new Set(e.responses.filter(e=>e.optionId===`approve`).map(e=>e.requestId)),n=e.pendingBatch.requests.filter(e=>t.has(e.requestId)).map(t=>e.resolveApprovalKey?.(t)??t.action.toolName);if(n.length===0)return e.session;let r=getApprovedTools(e.session),i=[...new Set([...r,...n])],a={...e.session.state};return a[APPROVED_TOOLS_KEY]=i,{...e.session,state:a}}function resolveApprovalOutcome(e){return e===void 0?{approved:!1,reason:`Ignored because the user continued without responding.`,status:`ignored`}:e.optionId===`approve`?{approved:!0,reason:void 0,status:`approved`}:e.optionId===`deny`?{approved:!1,reason:TOOL_EXECUTION_DENIED_MESSAGE,status:`denied`}:{approved:!1,reason:`Invalid approval response.`,status:`invalid`}}function buildRejectedActionBatch(e,t){if(e.event===void 0)return;let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests){if(!isApprovalRequest(t))continue;let{approved:e,reason:i,status:a}=resolveApprovalOutcome(n.get(t.requestId));e||r.push({callId:t.action.callId,isError:!0,kind:`tool-result`,output:{approval:{requestId:t.requestId,status:a},code:`TOOL_EXECUTION_DENIED`,message:i??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}},toolName:t.action.toolName})}return r.length>0?{event:e.event,results:r}:void 0}function buildToolResponseParts(e,t){let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests)r.push(...buildToolResponsePartsForRequest(t,n.get(t.requestId)));return r}function buildToolResponsePartsForRequest(e,t){if(isSessionLimitContinuationRequest(e))return[];if(isApprovalRequest(e)){let{approved:n,reason:r}=resolveApprovalOutcome(t),i=[{approvalId:e.requestId,approved:n,reason:r,type:`tool-approval-response`}];return n||i.push({output:{type:`execution-denied`,reason:r},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}),i}return[{output:{type:`json`,value:t===void 0?{status:`ignored`}:{optionId:t.optionId,text:t.text,status:`answered`}},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}]}function createRuntimeToolCallActionFromToolCall(e){return{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}export{clearPendingSessionLimitPrompt,consumeDeferredStepInput,createRuntimeToolCallActionFromToolCall,getApprovedTools,getPendingInputRequestIds,hasDeferredStepInput,hasPendingInputBatch,hasStepInput,resolvePendingInput,setPendingInputBatch};
@@ -47,6 +47,16 @@ export interface InstrumentationAttemptTerminalEvent {
47
47
  readonly error?: unknown;
48
48
  readonly scope: InstrumentationAttemptScope;
49
49
  }
50
+ /**
51
+ * Provider metadata for one completed step, as reported by the AI SDK
52
+ * (`StepResult.providerMetadata`). Carries Vercel AI Gateway cost data when
53
+ * the request went through the gateway; absent for other providers.
54
+ */
55
+ export interface InstrumentationAttemptMetadataEvent {
56
+ readonly type: "attempt.metadata";
57
+ readonly scope: InstrumentationAttemptScope;
58
+ readonly providerMetadata: Readonly<Record<string, unknown>>;
59
+ }
50
60
  export interface InstrumentationModelCallStartedEvent {
51
61
  readonly type: "model.call.started";
52
62
  readonly id: string;
@@ -96,6 +106,7 @@ export interface InstrumentationProviderDefinition {
96
106
  readonly "attempt.started"?: (event: InstrumentationAttemptStartedEvent) => void | PromiseLike<void>;
97
107
  readonly "attempt.completed"?: (event: InstrumentationAttemptTerminalEvent) => void | PromiseLike<void>;
98
108
  readonly "attempt.failed"?: (event: InstrumentationAttemptTerminalEvent) => void | PromiseLike<void>;
109
+ readonly "attempt.metadata"?: (event: InstrumentationAttemptMetadataEvent) => void | PromiseLike<void>;
99
110
  readonly "session.completed"?: (event: InstrumentationSessionTransitionEvent) => void | PromiseLike<void>;
100
111
  readonly "session.failed"?: (event: InstrumentationSessionTransitionEvent) => void | PromiseLike<void>;
101
112
  readonly "session.started"?: (event: InstrumentationSessionStartedEvent) => void | PromiseLike<void>;
@@ -118,7 +129,7 @@ export interface InstrumentationRelatedEventMap {
118
129
  };
119
130
  }
120
131
  export type InstrumentationRelatedEventName = keyof InstrumentationRelatedEventMap;
121
- export type InstrumentationPointEvent = InstrumentationAttemptStartedEvent | InstrumentationAttemptTerminalEvent | InstrumentationSessionStartedEvent | InstrumentationSessionTransitionEvent | InstrumentationTurnStartedEvent | InstrumentationTurnTerminalEvent;
132
+ export type InstrumentationPointEvent = InstrumentationAttemptStartedEvent | InstrumentationAttemptMetadataEvent | InstrumentationAttemptTerminalEvent | InstrumentationSessionStartedEvent | InstrumentationSessionTransitionEvent | InstrumentationTurnStartedEvent | InstrumentationTurnTerminalEvent;
122
133
  /** Trusted framework operation for activating context around AI SDK execution. */
123
134
  export type InstrumentationContextRunner = <T>(operation: InstrumentationExecutionOperation, execute: () => PromiseLike<T>) => PromiseLike<T>;
124
135
  /** Stable identity supplied only to a trusted framework context runner. */
@@ -1,10 +1,16 @@
1
1
  import type { SubagentInputRequestHookPayload } from "#channel/types.js";
2
2
  import type { HarnessSession, SessionStateMap } from "#harness/types.js";
3
+ import type { InputRequestKind } from "#runtime/input/types.js";
4
+ /** Routing and control metadata for one descendant-owned input request. */
5
+ export interface ProxyInputRequest {
6
+ readonly childContinuationToken: string;
7
+ readonly kind: InputRequestKind;
8
+ }
3
9
  /**
4
10
  * Returns the proxy-routing map as a fresh `Map`. Never returns a live
5
11
  * reference so accidental mutation cannot corrupt session state.
6
12
  */
7
- export declare function getProxyInputRequests(state: SessionStateMap | undefined): ReadonlyMap<string, string>;
13
+ export declare function getProxyInputRequests(state: SessionStateMap | undefined): ReadonlyMap<string, ProxyInputRequest>;
8
14
  /**
9
15
  * Returns true when the session is currently proxying one or more
10
16
  * HITL requests on behalf of a descendant subagent.
@@ -16,7 +22,7 @@ export declare function hasProxyInputRequests(state: SessionStateMap | undefined
16
22
  * batch — the parent never keeps stale request metadata.
17
23
  */
18
24
  export declare function upsertProxyInputRequests(input: {
19
- readonly entries: readonly (readonly [requestId: string, childContinuationToken: string])[];
25
+ readonly entries: readonly (readonly [requestId: string, route: ProxyInputRequest])[];
20
26
  readonly forChildContinuationToken: string;
21
27
  readonly session: HarnessSession;
22
28
  }): HarnessSession;
@@ -32,6 +38,6 @@ export declare function clearProxyInputRequestsForChild(session: HarnessSession,
32
38
  export declare function clearAllProxyInputRequests(session: HarnessSession): HarnessSession;
33
39
  /**
34
40
  * Projects a {@link SubagentInputRequestHookPayload} into the
35
- * `(requestId, childContinuationToken)` tuples the session stores.
41
+ * `(requestId, route)` tuples the session stores.
36
42
  */
37
- export declare function toProxyInputRequestEntries(payload: SubagentInputRequestHookPayload): readonly (readonly [requestId: string, childContinuationToken: string])[];
43
+ export declare function toProxyInputRequestEntries(payload: SubagentInputRequestHookPayload): readonly (readonly [requestId: string, route: ProxyInputRequest])[];
@@ -1 +1 @@
1
- const PROXY_INPUT_REQUESTS_KEY=`eve.runtime.proxyInputRequests`;function getProxyInputRequests(e){return new Map(Object.entries(readMap(e)))}function hasProxyInputRequests(e){for(let t of Object.keys(readMap(e)))return!0;return!1}function upsertProxyInputRequests(e){let t={};for(let[n,r]of Object.entries(readMap(e.session.state)))r!==e.forChildContinuationToken&&(t[n]=r);for(let[n,r]of e.entries)t[n]=r;return writeMap(e.session,t)}function clearProxyInputRequestsForChild(e,t){let n=readMap(e.state),r={},i=!1;for(let[e,a]of Object.entries(n)){if(a===t){i=!0;continue}r[e]=a}return i?writeMap(e,r):e}function clearAllProxyInputRequests(e){return hasProxyInputRequests(e.state)?writeMap(e,{}):e}function toProxyInputRequestEntries(e){return e.event.requests.map(t=>[t.requestId,e.childContinuationToken])}function readMap(t){let n=t?.[PROXY_INPUT_REQUESTS_KEY];if(typeof n!=`object`||!n||Array.isArray(n))return{};let r={};for(let[e,t]of Object.entries(n))typeof t==`string`&&(r[e]=t);return r}function writeMap(t,n){let r={...t.state};return Object.keys(n).length===0?(delete r[PROXY_INPUT_REQUESTS_KEY],{...t,state:Object.keys(r).length>0?r:void 0}):(r[PROXY_INPUT_REQUESTS_KEY]=n,{...t,state:r})}export{clearAllProxyInputRequests,clearProxyInputRequestsForChild,getProxyInputRequests,hasProxyInputRequests,toProxyInputRequestEntries,upsertProxyInputRequests};
1
+ const PROXY_INPUT_REQUESTS_KEY=`eve.runtime.proxyInputRequests`,PROXY_INPUT_REQUEST_KINDS={question:!0,"session-limit":!0,"tool-approval":!0};function getProxyInputRequests(e){return new Map(Object.entries(readMap(e)))}function hasProxyInputRequests(e){for(let t of Object.keys(readMap(e)))return!0;return!1}function upsertProxyInputRequests(e){let t={};for(let[n,r]of Object.entries(readMap(e.session.state)))r.childContinuationToken!==e.forChildContinuationToken&&(t[n]=r);for(let[n,r]of e.entries)t[n]=r;return writeMap(e.session,t)}function clearProxyInputRequestsForChild(e,t){let n=readMap(e.state),r={},i=!1;for(let[e,a]of Object.entries(n)){if(a.childContinuationToken===t){i=!0;continue}r[e]=a}return i?writeMap(e,r):e}function clearAllProxyInputRequests(e){return hasProxyInputRequests(e.state)?writeMap(e,{}):e}function toProxyInputRequestEntries(e){return e.event.requests.map(t=>[t.requestId,{childContinuationToken:e.childContinuationToken,kind:t.kind}])}function readMap(t){let n=t?.[PROXY_INPUT_REQUESTS_KEY];if(typeof n!=`object`||!n||Array.isArray(n))return{};let r={};for(let[e,t]of Object.entries(n)){let n=parseProxyInputRequest(t);n!==void 0&&(r[e]=n)}return r}function writeMap(t,n){let r={...t.state};return Object.keys(n).length===0?(delete r[PROXY_INPUT_REQUESTS_KEY],{...t,state:Object.keys(r).length>0?r:void 0}):(r[PROXY_INPUT_REQUESTS_KEY]=n,{...t,state:r})}function parseProxyInputRequest(e){if(!(typeof e!=`object`||!e||Array.isArray(e))&&!(!(`childContinuationToken`in e)||!(`kind`in e))&&!(typeof e.childContinuationToken!=`string`||!isInputRequestKind(e.kind)))return{childContinuationToken:e.childContinuationToken,kind:e.kind}}function isInputRequestKind(e){return typeof e==`string`&&Object.hasOwn(PROXY_INPUT_REQUEST_KINDS,e)}export{clearAllProxyInputRequests,clearProxyInputRequestsForChild,getProxyInputRequests,hasProxyInputRequests,toProxyInputRequestEntries,upsertProxyInputRequests};
@@ -21,17 +21,6 @@ export declare const SESSION_LIMIT_STOP_OPTION_ID = "stop";
21
21
  */
22
22
  export declare function createSessionLimitContinuationRequest(input: {
23
23
  readonly sessionId: string;
24
- /**
25
- * Absolute session total of the violated kind (not the window-relative
26
- * `violation.usedTokens`, which can repeat across grants — e.g. a second
27
- * violation can land on exactly the same window usage). The absolute total
28
- * is strictly increasing across violations, so each prompt gets its own id
29
- * while staying deterministic: stale chat controls from an earlier,
30
- * already-resolved prompt carry an unknown requestId, resolve nothing, and
31
- * the harness harmlessly re-prompts instead of letting an old "Stop"
32
- * button end a freshly granted session.
33
- */
34
- readonly totalUsedTokens: number;
35
24
  readonly violation: SessionTokenLimitViolation;
36
25
  }): InputRequest;
37
26
  /**
@@ -1 +1 @@
1
- const SESSION_LIMIT_CONTINUATION_TOOL_NAME=`session_limit_continuation`,SESSION_LIMIT_CONTINUE_OPTION_ID=`continue`,SESSION_LIMIT_STOP_OPTION_ID=`stop`;function createSessionLimitContinuationRequest(r){let{sessionId:i,totalUsedTokens:a,violation:o}=r,s=`${i}:limit:${o.kind}:${String(a)}`;return{action:{callId:s,input:{kind:o.kind,limit:o.limit,usedTokens:o.usedTokens},kind:`tool-call`,toolName:SESSION_LIMIT_CONTINUATION_TOOL_NAME},allowFreeform:!1,display:`confirmation`,options:[{description:`Grant a fresh token budget`,id:SESSION_LIMIT_CONTINUE_OPTION_ID,label:`Approve`,style:`primary`},{description:`Stop now`,id:SESSION_LIMIT_STOP_OPTION_ID,label:`Stop`,style:`danger`}],prompt:`This session has hit the ${o.kind}-token limit (${formatCompactTokenCount(o.limit)}) per session. This is a guardrail against defective long-running sessions. If session activity looks fine, just approve to keep going.`,requestId:s}}function formatCompactTokenCount(e){return e>=1e6?`${trimTrailingZero(e/1e6)}M`:e>=1e3?`${trimTrailingZero(e/1e3)}K`:String(e)}function trimTrailingZero(e){let t=e.toFixed(1);return t.endsWith(`.0`)?t.slice(0,-2):t}function isSessionLimitContinuationRequest(t){return t.action.toolName===SESSION_LIMIT_CONTINUATION_TOOL_NAME}function isSessionLimitContinuationRequestId(e){return/:limit:(?:input|output):\d+$/u.test(e)}function resolveSessionLimitContinuation(e){let t=e.requests.find(isSessionLimitContinuationRequest);if(t===void 0)return;let n=e.responses.find(e=>e.requestId===t.requestId);if(n!==void 0){if(n.optionId===`continue`)return{granted:!0};if(n.optionId===`stop`)return{granted:!1}}}export{SESSION_LIMIT_CONTINUATION_TOOL_NAME,SESSION_LIMIT_CONTINUE_OPTION_ID,SESSION_LIMIT_STOP_OPTION_ID,createSessionLimitContinuationRequest,isSessionLimitContinuationRequest,isSessionLimitContinuationRequestId,resolveSessionLimitContinuation};
1
+ const SESSION_LIMIT_CONTINUATION_TOOL_NAME=`session_limit_continuation`,SESSION_LIMIT_CONTINUE_OPTION_ID=`continue`,SESSION_LIMIT_STOP_OPTION_ID=`stop`;function createSessionLimitContinuationRequest(r){let{sessionId:i,violation:a}=r,o=`${i}:limit:${a.kind}:${String(a.usedTokens)}`;return{action:{callId:o,input:{kind:a.kind,limit:a.limit,usedTokens:a.usedTokens},kind:`tool-call`,toolName:SESSION_LIMIT_CONTINUATION_TOOL_NAME},allowFreeform:!1,display:`confirmation`,kind:`session-limit`,options:[{description:`Grant a fresh token budget`,id:SESSION_LIMIT_CONTINUE_OPTION_ID,label:`Approve`,style:`primary`},{description:`Stop now`,id:SESSION_LIMIT_STOP_OPTION_ID,label:`Stop`,style:`danger`}],prompt:`This session has hit the ${a.kind}-token limit (${formatCompactTokenCount(a.limit)}) per session. This is a guardrail against defective long-running sessions. If session activity looks fine, just approve to keep going.`,requestId:o}}function formatCompactTokenCount(e){return e>=1e6?`${trimTrailingZero(e/1e6)}M`:e>=1e3?`${trimTrailingZero(e/1e3)}K`:String(e)}function trimTrailingZero(e){let t=e.toFixed(1);return t.endsWith(`.0`)?t.slice(0,-2):t}function isSessionLimitContinuationRequest(e){return e.kind===`session-limit`}function isSessionLimitContinuationRequestId(e){return/:limit:(?:input|output):\d+$/u.test(e)}function resolveSessionLimitContinuation(e){let t=e.requests.find(isSessionLimitContinuationRequest);if(t===void 0)return;let n=e.responses.find(e=>e.requestId===t.requestId);if(n!==void 0){if(n.optionId===`continue`)return{granted:!0};if(n.optionId===`stop`)return{granted:!1}}}export{SESSION_LIMIT_CONTINUATION_TOOL_NAME,SESSION_LIMIT_CONTINUE_OPTION_ID,SESSION_LIMIT_STOP_OPTION_ID,createSessionLimitContinuationRequest,isSessionLimitContinuationRequest,isSessionLimitContinuationRequestId,resolveSessionLimitContinuation};
@@ -23,8 +23,9 @@ interface SessionLimitPolicyInput {
23
23
  /**
24
24
  * Acts on a resolved session-limit continuation answer.
25
25
  *
26
- * Granted: resets the token budget windows via
27
- * {@link extendSessionTokenBudget} and lets the step continue transparently.
26
+ * Granted: bumps the runtime token limits via
27
+ * {@link bumpSessionRuntimeTokenLimits} and lets the step continue
28
+ * transparently.
28
29
  * Declined: a user decision, not an error — the decline cancels the
29
30
  * in-flight turn tree through the standard cancellation path, settling as
30
31
  * `turn.cancelled` → `session.waiting` with no failure surfaced anywhere.
@@ -1 +1 @@
1
- import{createInputRequestedEvent}from"#protocol/message.js";import{emitFailedStep,emitTurnEpilogue,setHarnessEmissionState}from"#harness/emission.js";import{SessionLimitDeclinedError}from"#harness/turn-cancellation.js";import{setPendingInputBatch}from"#harness/input-requests.js";import{extendSessionTokenBudget,getSessionTokenLimitViolation,getSessionTokenUsage}from"#harness/turn-tag-state.js";import{createSessionLimitContinuationRequest}from"#harness/session-limit-continuation.js";async function applySessionLimitContinuation(e){if(e.limitContinuation===void 0)return{result:null,session:e.session};if(e.limitContinuation.granted)return{result:null,session:extendSessionTokenBudget(e.session)};if(!(e.config.mode===`conversation`||e.session.continuationToken!==``)){let t=getSessionTokenLimitViolation(e.session);return{result:t===null?{next:{done:!0,output:``},session:e.session}:await failSessionTokenLimit({...e,violation:t}),session:e.session}}throw new SessionLimitDeclinedError}async function enforceSessionTokenLimit(e){let t=getSessionTokenLimitViolation(e.session);if(t===null)return null;let{emit:n}=e;return n!==void 0&&(e.config.mode===`conversation`||e.config.capabilities?.requestInput===!0)?parkOnSessionTokenLimit({...e,emit:n,violation:t}):failSessionTokenLimit({...e,violation:t})}async function parkOnSessionTokenLimit(t){let i=getSessionTokenUsage(t.session),a=createSessionLimitContinuationRequest({sessionId:t.session.sessionId,totalUsedTokens:t.violation.kind===`input`?i.inputTokens:i.outputTokens,violation:t.violation}),o=t.emissionState,s=setPendingInputBatch({event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},requests:[a],responseMessages:[],session:{...t.session,history:[...t.messages]}});return await t.emit(createInputRequestedEvent({requests:[a],sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),t.config.mode===`conversation`&&(o=await emitTurnEpilogue(t.emit,o,t.config.mode,s.continuationToken)),{next:null,session:setHarnessEmissionState(s,o)}}function formatSessionTokenLimitMessage(e){return`The session reached its configured ${e} token limit.`}async function failSessionTokenLimit(e){let n=getSessionTokenUsage(e.session),r=formatSessionTokenLimitMessage(e.violation.kind),i={inputTokens:n.inputTokens,kind:e.violation.kind,limit:e.violation.limit,outputTokens:n.outputTokens,usedTokens:e.violation.usedTokens};return e.emit&&await emitFailedStep(e.emit,e.emissionState,{code:`SESSION_TOKEN_LIMIT_REACHED`,details:i,message:r,sessionId:e.session.sessionId}),{next:{done:!0,isError:e.config.mode===`task`||void 0,output:e.config.mode===`task`?r:``},session:e.session}}export{applySessionLimitContinuation,enforceSessionTokenLimit};
1
+ import{createInputRequestedEvent}from"#protocol/message.js";import{emitFailedStep,emitTurnEpilogue,setHarnessEmissionState}from"#harness/emission.js";import{setPendingInputBatch}from"#harness/input-requests.js";import{createSessionLimitContinuationRequest}from"#harness/session-limit-continuation.js";import{SessionLimitDeclinedError}from"#harness/turn-cancellation.js";import{bumpSessionRuntimeTokenLimits,getSessionTokenLimitViolation,getSessionTokenUsage}from"#harness/turn-tag-state.js";async function applySessionLimitContinuation(e){if(e.limitContinuation===void 0)return{result:null,session:e.session};if(e.limitContinuation.granted)return{result:null,session:bumpSessionRuntimeTokenLimits(e.session)};if(!(e.config.mode===`conversation`||e.session.continuationToken!==``)){let t=getSessionTokenLimitViolation(e.session);return{result:t===null?{next:{done:!0,output:``},session:e.session}:await failSessionTokenLimit({...e,violation:t}),session:e.session}}throw new SessionLimitDeclinedError}async function enforceSessionTokenLimit(e){let t=getSessionTokenLimitViolation(e.session);if(t===null)return null;let{emit:n}=e;return t.limit>0&&n!==void 0&&(e.config.mode===`conversation`||e.config.capabilities?.requestInput===!0)?parkOnSessionTokenLimit({...e,emit:n,violation:t}):failSessionTokenLimit({...e,violation:t})}async function parkOnSessionTokenLimit(t){let a=createSessionLimitContinuationRequest({sessionId:t.session.sessionId,violation:t.violation}),o=t.emissionState,s=setPendingInputBatch({event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},requests:[a],responseMessages:[],session:{...t.session,history:[...t.messages]}});return await t.emit(createInputRequestedEvent({requests:[a],sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),t.config.mode===`conversation`&&(o=await emitTurnEpilogue(t.emit,o,t.config.mode,s.continuationToken)),{next:null,session:setHarnessEmissionState(s,o)}}function formatSessionTokenLimitMessage(e){return`The session reached its configured ${e} token limit.`}async function failSessionTokenLimit(e){let n=getSessionTokenUsage(e.session),r=formatSessionTokenLimitMessage(e.violation.kind),i={inputTokens:n.inputTokens,kind:e.violation.kind,limit:e.violation.limit,outputTokens:n.outputTokens,usedTokens:e.violation.usedTokens};return e.emit&&await emitFailedStep(e.emit,e.emissionState,{code:`SESSION_TOKEN_LIMIT_REACHED`,details:i,message:r,sessionId:e.session.sessionId}),{next:{done:!0,isError:e.config.mode===`task`||void 0,output:e.config.mode===`task`?r:``},session:e.session}}export{applySessionLimitContinuation,enforceSessionTokenLimit};
@@ -0,0 +1,41 @@
1
+ export interface SessionTokenAmounts {
2
+ readonly inputTokens: number;
3
+ readonly outputTokens: number;
4
+ }
5
+ export interface SessionRuntimeTokenLimits {
6
+ readonly inputTokens?: number;
7
+ readonly outputTokens?: number;
8
+ }
9
+ export type SessionTokenLimitViolation = {
10
+ readonly kind: "input";
11
+ readonly limit: number;
12
+ readonly usedTokens: number;
13
+ } | {
14
+ readonly kind: "output";
15
+ readonly limit: number;
16
+ readonly usedTokens: number;
17
+ };
18
+ /** Resolves per-axis lifetime ceilings, preferring a previously granted ceiling. */
19
+ export declare function resolveRuntimeTokenLimits(input: {
20
+ readonly configured: SessionRuntimeTokenLimits;
21
+ readonly stored?: SessionRuntimeTokenLimits;
22
+ }): SessionRuntimeTokenLimits;
23
+ /** Grants one full configured window from the current lifetime usage. */
24
+ export declare function grantRuntimeTokenLimits(input: {
25
+ readonly configured: SessionRuntimeTokenLimits;
26
+ readonly usage: SessionTokenAmounts;
27
+ }): SessionRuntimeTokenLimits;
28
+ /** Returns the unspent quota for each capped axis. */
29
+ export declare function remainingRuntimeTokenQuota(input: {
30
+ readonly runtime: SessionRuntimeTokenLimits;
31
+ readonly usage: SessionTokenAmounts;
32
+ }): {
33
+ readonly inputTokens: number | false;
34
+ readonly outputTokens: number | false;
35
+ };
36
+ /** Returns the first exhausted axis, with input taking precedence. */
37
+ export declare function findRuntimeTokenLimitViolation(input: {
38
+ readonly configured: SessionRuntimeTokenLimits;
39
+ readonly runtime: SessionRuntimeTokenLimits;
40
+ readonly usage: SessionTokenAmounts;
41
+ }): SessionTokenLimitViolation | null;
@@ -0,0 +1 @@
1
+ function resolveRuntimeTokenLimits(e){let t={},n=e.stored?.inputTokens??e.configured.inputTokens;n!==void 0&&(t.inputTokens=n);let r=e.stored?.outputTokens??e.configured.outputTokens;return r!==void 0&&(t.outputTokens=r),t}function grantRuntimeTokenLimits(e){let t={};return e.configured.inputTokens!==void 0&&(t.inputTokens=e.usage.inputTokens+e.configured.inputTokens),e.configured.outputTokens!==void 0&&(t.outputTokens=e.usage.outputTokens+e.configured.outputTokens),t}function remainingRuntimeTokenQuota(e){return{inputTokens:e.runtime.inputTokens!==void 0&&Math.max(0,e.runtime.inputTokens-e.usage.inputTokens),outputTokens:e.runtime.outputTokens!==void 0&&Math.max(0,e.runtime.outputTokens-e.usage.outputTokens)}}function findRuntimeTokenLimitViolation(e){return e.runtime.inputTokens!==void 0&&e.configured.inputTokens!==void 0&&e.usage.inputTokens>=e.runtime.inputTokens?{kind:`input`,limit:e.configured.inputTokens,usedTokens:e.usage.inputTokens}:e.runtime.outputTokens!==void 0&&e.configured.outputTokens!==void 0&&e.usage.outputTokens>=e.runtime.outputTokens?{kind:`output`,limit:e.configured.outputTokens,usedTokens:e.usage.outputTokens}:null}export{findRuntimeTokenLimitViolation,grantRuntimeTokenLimits,remainingRuntimeTokenQuota,resolveRuntimeTokenLimits};