eve 0.27.13 → 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 (144) hide show
  1. package/CHANGELOG.md +19 -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/dev/tui/runner.js +1 -1
  8. package/dist/src/cli/dev/tui/subagent-pump.d.ts +8 -2
  9. package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
  10. package/dist/src/cli/invoke/result.d.ts +15 -0
  11. package/dist/src/cli/invoke/result.js +1 -1
  12. package/dist/src/client/eve-agent-store.d.ts +7 -4
  13. package/dist/src/client/eve-agent-store.js +1 -1
  14. package/dist/src/client/index.d.ts +3 -3
  15. package/dist/src/client/index.js +1 -1
  16. package/dist/src/client/message-action-parts.js +1 -1
  17. package/dist/src/client/message-reducer-types.d.ts +5 -3
  18. package/dist/src/client/message-response.d.ts +4 -4
  19. package/dist/src/client/ndjson.d.ts +3 -3
  20. package/dist/src/client/open-stream.d.ts +2 -2
  21. package/dist/src/client/output-schema.d.ts +2 -2
  22. package/dist/src/client/reducer.d.ts +2 -2
  23. package/dist/src/client/session-utils.d.ts +5 -5
  24. package/dist/src/client/session.d.ts +2 -2
  25. package/dist/src/client/types.d.ts +2 -2
  26. package/dist/src/compiler/compile-from-memory.d.ts +1 -0
  27. package/dist/src/compiler/extension-compatibility.d.ts +8 -8
  28. package/dist/src/compiler/extension-compatibility.js +1 -1
  29. package/dist/src/compiler/manifest.d.ts +2 -2
  30. package/dist/src/compiler/manifest.js +1 -1
  31. package/dist/src/compiler/normalize-agent-config.js +1 -1
  32. package/dist/src/context/dynamic-instruction-lifecycle.d.ts +2 -2
  33. package/dist/src/context/dynamic-model-lifecycle.d.ts +2 -2
  34. package/dist/src/context/dynamic-skill-lifecycle.d.ts +2 -2
  35. package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -2
  36. package/dist/src/context/hook-lifecycle.d.ts +2 -2
  37. package/dist/src/evals/assertions/run.d.ts +3 -3
  38. package/dist/src/evals/match.d.ts +4 -4
  39. package/dist/src/evals/runner/derive-run-facts.d.ts +2 -2
  40. package/dist/src/evals/session.d.ts +3 -3
  41. package/dist/src/evals/types.d.ts +12 -12
  42. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  43. package/dist/src/execution/route-child-delivery.d.ts +4 -3
  44. package/dist/src/execution/route-child-delivery.js +1 -1
  45. package/dist/src/execution/session-delivery-hook.d.ts +1 -0
  46. package/dist/src/execution/session-delivery-hook.js +1 -1
  47. package/dist/src/execution/session-timeout-control.d.ts +9 -0
  48. package/dist/src/execution/session-timeout-control.js +1 -0
  49. package/dist/src/execution/session-timeout-steps.d.ts +13 -0
  50. package/dist/src/execution/session-timeout-steps.js +1 -0
  51. package/dist/src/execution/session-timeout-workflow.d.ts +6 -0
  52. package/dist/src/execution/session-timeout-workflow.js +1 -0
  53. package/dist/src/execution/session-timeout.d.ts +2 -0
  54. package/dist/src/execution/session-timeout.js +1 -0
  55. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  56. package/dist/src/execution/subagent-event-proxy-step.js +1 -1
  57. package/dist/src/execution/subagent-hitl-proxy.d.ts +5 -1
  58. package/dist/src/execution/subagent-hitl-proxy.js +1 -1
  59. package/dist/src/execution/terminal-session-completion-step.d.ts +5 -0
  60. package/dist/src/execution/terminal-session-completion-step.js +1 -0
  61. package/dist/src/execution/terminal-session-failure-step.js +1 -1
  62. package/dist/src/execution/turn-workflow.js +1 -1
  63. package/dist/src/execution/workflow-entry.d.ts +1 -0
  64. package/dist/src/execution/workflow-entry.js +1 -1
  65. package/dist/src/execution/workflow-runtime.d.ts +4 -0
  66. package/dist/src/execution/workflow-runtime.js +1 -1
  67. package/dist/src/execution/workflow-steps.d.ts +5 -2
  68. package/dist/src/execution/workflow-steps.js +1 -1
  69. package/dist/src/harness/agent-otel-provider.js +1 -1
  70. package/dist/src/harness/ai-sdk-hook-bridge.js +1 -1
  71. package/dist/src/harness/input-extraction.js +1 -1
  72. package/dist/src/harness/input-request-class.d.ts +23 -0
  73. package/dist/src/harness/input-request-class.js +1 -0
  74. package/dist/src/harness/input-requests.d.ts +20 -9
  75. package/dist/src/harness/input-requests.js +1 -1
  76. package/dist/src/harness/instrumentation-lifecycle.d.ts +12 -1
  77. package/dist/src/harness/proxy-input-requests.d.ts +10 -4
  78. package/dist/src/harness/proxy-input-requests.js +1 -1
  79. package/dist/src/harness/session-limit-continuation.d.ts +0 -11
  80. package/dist/src/harness/session-limit-continuation.js +1 -1
  81. package/dist/src/harness/session-limit-enforcement.d.ts +3 -2
  82. package/dist/src/harness/session-limit-enforcement.js +1 -1
  83. package/dist/src/harness/session-token-limits.d.ts +41 -0
  84. package/dist/src/harness/session-token-limits.js +1 -0
  85. package/dist/src/harness/stale-input-responses.js +1 -1
  86. package/dist/src/harness/subagent-token-budget.d.ts +6 -4
  87. package/dist/src/harness/subagent-token-budget.js +1 -1
  88. package/dist/src/harness/tool-loop.js +1 -1
  89. package/dist/src/harness/turn-tag-state.d.ts +26 -17
  90. package/dist/src/harness/turn-tag-state.js +1 -1
  91. package/dist/src/harness/types.d.ts +4 -4
  92. package/dist/src/harness/workflow-lifecycle.d.ts +2 -2
  93. package/dist/src/internal/application/package.js +1 -1
  94. package/dist/src/internal/authored-definition/core.js +1 -1
  95. package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +1 -1
  96. package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
  97. package/dist/src/protocol/event-dedupe.d.ts +25 -0
  98. package/dist/src/protocol/event-dedupe.js +1 -0
  99. package/dist/src/protocol/event-id.d.ts +16 -0
  100. package/dist/src/protocol/event-id.js +1 -0
  101. package/dist/src/protocol/message.d.ts +39 -23
  102. package/dist/src/protocol/message.js +2 -2
  103. package/dist/src/public/channels/discord/discordChannel.d.ts +3 -3
  104. package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
  105. package/dist/src/public/channels/linear/linearChannel.d.ts +3 -3
  106. package/dist/src/public/channels/slack/hitl.js +1 -1
  107. package/dist/src/public/channels/slack/slackChannel.d.ts +3 -3
  108. package/dist/src/public/channels/teams/hitl.js +1 -1
  109. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
  110. package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -3
  111. package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
  112. package/dist/src/public/definitions/channel.d.ts +4 -4
  113. package/dist/src/public/definitions/hook.d.ts +2 -2
  114. package/dist/src/react/use-eve-agent.d.ts +3 -2
  115. package/dist/src/runtime/framework-tools/ask-question.js +1 -1
  116. package/dist/src/runtime/hooks/registry.d.ts +2 -2
  117. package/dist/src/runtime/input/types.d.ts +19 -4
  118. package/dist/src/runtime/input/types.js +1 -1
  119. package/dist/src/runtime/resolve-agent.js +1 -1
  120. package/dist/src/runtime/types.d.ts +2 -2
  121. package/dist/src/setup/scaffold/create/project.js +1 -1
  122. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  123. package/dist/src/setup/scaffold/create/web-template.js +2 -2
  124. package/dist/src/shared/agent-definition.d.ts +12 -0
  125. package/dist/src/shared/dynamic-tool-definition.d.ts +2 -2
  126. package/dist/src/shared/ulid.d.ts +39 -0
  127. package/dist/src/shared/ulid.js +1 -0
  128. package/dist/src/svelte/index.js +1 -1
  129. package/dist/src/svelte/use-eve-agent.d.ts +4 -4
  130. package/dist/src/svelte/use-eve-agent.js +1 -1
  131. package/dist/src/vue/index.js +1 -1
  132. package/dist/src/vue/use-eve-agent.d.ts +4 -4
  133. package/dist/src/vue/use-eve-agent.js +1 -1
  134. package/docs/agent-config.md +28 -16
  135. package/docs/concepts/execution-model-and-durability.mdx +1 -1
  136. package/docs/concepts/sessions-runs-and-streaming.md +61 -0
  137. package/docs/guides/client/streaming.mdx +9 -3
  138. package/docs/guides/frontend/overview.mdx +4 -2
  139. package/docs/guides/frontend/use-eve-agent-svelte.mdx +1 -1
  140. package/docs/guides/frontend/use-eve-agent-vue.mdx +10 -10
  141. package/docs/guides/hooks.md +40 -2
  142. package/docs/guides/instrumentation.md +4 -0
  143. package/docs/tools/human-in-the-loop.md +5 -0
  144. package/package.json +1 -1
@@ -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};
@@ -1,3 +1,3 @@
1
- import{appendUserContent,normalizeUserContent}from"#harness/messages.js";import{isApprovalRequest}from"#harness/input-requests.js";import{isSessionLimitContinuationRequestId}from"#harness/session-limit-continuation.js";import{extractHistoricalInputRequests}from"#harness/input-extraction.js";function dropStaleSessionLimitContinuationResponses(e){let t=e.stepInput?.inputResponses;if(e.stepInput===void 0||t===void 0||t.length===0)return e.stepInput;let n=t.filter(t=>e.pendingRequestIds.has(t.requestId)||!isSessionLimitContinuationRequestId(t.requestId));if(n.length===t.length)return e.stepInput;let{inputResponses:i,...a}=e.stepInput;return n.length===0?a:{...a,inputResponses:n}}function convertStaleResponsesToUserMessage(e){let t=e.stepInput?.inputResponses;if(e.stepInput===void 0||t===void 0||t.length===0)return{kind:`unchanged`,stepInput:e.stepInput};let n=[],r=[];for(let i of t)e.pendingRequestIds.has(i.requestId)?n.push(i):r.push(i);if(r.length===0)return{kind:`unchanged`,stepInput:e.stepInput};let a=extractHistoricalInputRequests({history:e.history,requestIds:new Set(r.map(e=>e.requestId))}),o=appendOptionalUserContent(e.stepInput.message,formatModelMessage(r,a)),s=appendOptionalUserContent(e.stepInput.message,formatDisplayMessage(r,a)),{inputResponses:c,...l}=e.stepInput,u={...l,message:o};return n.length>0&&(u.inputResponses=n),{displayMessage:s,kind:`converted`,stepInput:u}}function formatModelMessage(e,t){let r=e.map(e=>{let r=t.get(e.requestId),i=r?.options?.find(t=>t.id===e.optionId),a={};if(e.optionId!==void 0&&(a.optionId=e.optionId),i!==void 0){let e={id:i.id,label:i.label};i.description!==void 0&&(e.description=i.description),a.selectedOption=e}e.text!==void 0&&(a.text=e.text);let o={requestId:e.requestId,response:a};return r!==void 0&&(o.prompt=r.prompt,o.requestType=isApprovalRequest(r)?`approval`:`question`),o});return[`The user submitted the following response to an earlier interactive prompt.`,`Treat it as new input at the current point in the conversation and decide whether it is still relevant.${e.some(e=>{let r=t.get(e.requestId);return r===void 0||isApprovalRequest(r)})?` This does not authorize an earlier action; request approval again if that action is still needed.`:``}`,JSON.stringify(r,null,2)].join(`
1
+ import{appendUserContent,normalizeUserContent}from"#harness/messages.js";import{isSessionLimitContinuationRequestId}from"#harness/session-limit-continuation.js";import{isApprovalRequest}from"#harness/input-request-class.js";import{extractHistoricalInputRequests}from"#harness/input-extraction.js";function dropStaleSessionLimitContinuationResponses(e){let t=e.stepInput?.inputResponses;if(e.stepInput===void 0||t===void 0||t.length===0)return e.stepInput;let r=t.filter(t=>e.pendingRequestIds.has(t.requestId)||!isSessionLimitContinuationRequestId(t.requestId));if(r.length===t.length)return e.stepInput;let{inputResponses:i,...a}=e.stepInput;return r.length===0?a:{...a,inputResponses:r}}function convertStaleResponsesToUserMessage(e){let t=e.stepInput?.inputResponses;if(e.stepInput===void 0||t===void 0||t.length===0)return{kind:`unchanged`,stepInput:e.stepInput};let n=[],r=[];for(let i of t)e.pendingRequestIds.has(i.requestId)?n.push(i):r.push(i);if(r.length===0)return{kind:`unchanged`,stepInput:e.stepInput};let a=extractHistoricalInputRequests({history:e.history,requestIds:new Set(r.map(e=>e.requestId))}),o=appendOptionalUserContent(e.stepInput.message,formatModelMessage(r,a)),s=appendOptionalUserContent(e.stepInput.message,formatDisplayMessage(r,a)),{inputResponses:c,...l}=e.stepInput,u={...l,message:o};return n.length>0&&(u.inputResponses=n),{displayMessage:s,kind:`converted`,stepInput:u}}function formatModelMessage(e,t){let n=e.map(e=>{let n=t.get(e.requestId),i=n?.options?.find(t=>t.id===e.optionId),a={};if(e.optionId!==void 0&&(a.optionId=e.optionId),i!==void 0){let e={id:i.id,label:i.label};i.description!==void 0&&(e.description=i.description),a.selectedOption=e}e.text!==void 0&&(a.text=e.text);let o={requestId:e.requestId,response:a};return n!==void 0&&(o.prompt=n.prompt,o.requestType=isApprovalRequest(n)?`approval`:`question`),o});return[`The user submitted the following response to an earlier interactive prompt.`,`Treat it as new input at the current point in the conversation and decide whether it is still relevant.${e.some(e=>{let n=t.get(e.requestId);return n===void 0||isApprovalRequest(n)})?` This does not authorize an earlier action; request approval again if that action is still needed.`:``}`,JSON.stringify(n,null,2)].join(`
2
2
  `)}function formatDisplayMessage(e,t){return e.map(e=>e.text!==void 0&&e.text.length>0?e.text:t.get(e.requestId)?.options?.find(t=>t.id===e.optionId)?.label??e.optionId??`Response to an earlier interactive prompt`).join(`
3
3
  `)}function appendOptionalUserContent(n,r){let i=normalizeUserContent(n);return i===void 0?r:appendUserContent({appended:r,existing:i})}export{convertStaleResponsesToUserMessage,dropStaleSessionLimitContinuationResponses};
@@ -1,14 +1,16 @@
1
1
  import type { RunSessionLimits } from "#channel/types.js";
2
2
  import type { HarnessSession } from "#harness/types.js";
3
3
  /**
4
- * Computes the session token limits a delegated child inherits from its parent:
5
- * the remaining quota (configured limit minus accumulated usage) split evenly
6
- * across the batch's delegated calls, per axis, at dispatch time. `false`
7
- * marks an axis with no inherited cap.
4
+ * Computes the session token limits a delegated child inherits from its
5
+ * parent: the parent's remaining runtime-limit quota split evenly across the
6
+ * batch's delegated calls, per axis, at dispatch time. `false` marks an axis
7
+ * with no inherited cap.
8
8
  *
9
9
  * Splitting by `fanoutSize` makes one dispatch batch collectively
10
10
  * bounded by the parent's remainder. N parallel children cannot each spend
11
11
  * the full remainder. Sequential batches see the quota net of completed
12
12
  * children because their usage folds back into the parent's session totals.
13
+ * A granted continuation bumps the parent's runtime limit, so children
14
+ * dispatched after a grant draw from the fresh window.
13
15
  */
14
16
  export declare function resolveRemainingSessionTokenLimits(session: Pick<HarnessSession, "limits" | "state">, fanoutSize?: number): RunSessionLimits;
@@ -1 +1 @@
1
- import{getSessionTokenUsage}from"#harness/turn-tag-state.js";function resolveRemainingSessionTokenLimits(t,n=1){let r=Math.max(1,Math.floor(n)),i=getSessionTokenUsage(t);return{maxInputTokensPerSession:grantShare(remainingQuota(t.limits?.maxInputTokensPerSession,i.inputTokens),r),maxOutputTokensPerSession:grantShare(remainingQuota(t.limits?.maxOutputTokensPerSession,i.outputTokens),r)}}function remainingQuota(e,t){return e!==void 0&&Math.max(0,e-t)}function grantShare(e,t){return e!==!1&&Math.floor(e/t)}export{resolveRemainingSessionTokenLimits};
1
+ import{getSessionRemainingTokenQuota}from"#harness/turn-tag-state.js";function resolveRemainingSessionTokenLimits(t,n=1){let r=Math.max(1,Math.floor(n)),i=getSessionRemainingTokenQuota(t);return{maxInputTokensPerSession:grantShare(i.inputTokens,r),maxOutputTokensPerSession:grantShare(i.outputTokens,r)}}function grantShare(e,t){return e!==!1&&Math.floor(e/t)}export{resolveRemainingSessionTokenLimits};
@@ -1,3 +1,3 @@
1
- import{createErrorId,createLogger,formatError,logError,recordErrorOnSpan}from"#internal/logging.js";import{isScheduleAppAuth}from"#channel/schedule-auth.js";import{AuthKey,ParentSessionKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{toErrorMessage}from"#shared/errors.js";import{createActionResultEvent,createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createInputRequestedEvent,createResultCompletedEvent,createStepStartedEvent}from"#protocol/message.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{resolveProviderHeaders}from"#internal/gateway.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{contextStorage}from"#context/container.js";import{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStepStarted,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{ToolLoopAgent,isStepCount}from"ai";import{createRuntimeActionRequestFromToolCall,resolvePendingRuntimeActions,setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{normalizeUserContent,resolveAssistantStepText}from"#harness/messages.js";import{clearPendingWorkflowInterrupt,getPendingWorkflowInterrupt,setPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getWorkflowRuntimeActionInterrupts,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{getActiveDynamicModelSelection}from"#context/dynamic-model-lifecycle.js";import{activeTurnId}from"#harness/active-turn-id.js";import{createInstrumentationHandleEvent}from"#harness/instrumentation-native-events.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{isAuthorizationSignal,setPendingAuthorization}from"#harness/authorization.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{buildDynamicInstructionMessages}from"#context/dynamic-instruction-lifecycle.js";import{PendingSkillAnnouncementKey}from"#context/dynamic-skill-lifecycle.js";import{consumeDeferredStepInput,getApprovedTools,getPendingInputRequestIds,hasDeferredStepInput,hasStepInput,resolvePendingInput,setPendingInputBatch}from"#harness/input-requests.js";import{accumulateTurnUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{getWorkflowContinuationSecurity,readWorkflowContinuationSecurity}from"#harness/workflow-continuation-security.js";import{buildWorkflowHostTools,resolveWorkflowSandboxBridgeRequestLimit}from"#harness/workflow-sandbox.js";import{CONDITIONAL_DELIVERY_INSTRUCTION,EMPTY_DELIVERY_SENTINEL,hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{createToolResultMessagePartFromToolError}from"#harness/action-result-helpers.js";import{getInvalidToolCallInputError,isInvalidToolCall}from"#harness/tool-call-input-errors.js";import{EmptyModelResponseError,classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,extractUpstreamRejectionMessage,isNoOutputGeneratedError}from"#harness/model-call-error.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";import{extractQuestionInputRequests,extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyLastToolCacheBreakpoint,applySystemCacheBreakpoint,detectPromptCachePath,getAnthropicCacheMarker}from"#harness/prompt-cache.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{hydrateSandboxAttachments,stageAttachmentsToSandbox}from"#harness/attachment-staging.js";import{createWorkflowLifecycle}from"#harness/workflow-lifecycle.js";import{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact}from"#harness/compaction.js";import{applySessionLimitContinuation,enforceSessionTokenLimit}from"#harness/session-limit-enforcement.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{buildTelemetryRuntimeContext}from"#harness/instrumentation-runtime-context.js";import{createAiSdkHookBridge}from"#harness/ai-sdk-hook-bridge.js";import{convertStaleResponsesToUserMessage,dropStaleSessionLimitContinuationResponses}from"#harness/stale-input-responses.js";import{getInstrumentationConfig}from"#harness/instrumentation-config.js";import{normalizeProviderToolHistory}from"#harness/provider-tool-history.js";import{extractWorkflowStreamWriteErrorDetails}from"#harness/workflow-stream-error.js";import{createOtelIntegration,ensureOtelIntegration}from"#harness/otel-integration.js";import{getAdvertisedTools}from"#harness/advertised-tools.js";import{resolveFrameworkToolFromUpstreamType}from"#harness/provider-tools.js";import{buildStepHooks,emitStepActions}from"#harness/step-hooks.js";import{buildToolApproval,buildToolSetFromDefinitions,buildToolSetWithProviderTools}from"#harness/tools.js";import{continueWorkflowSandboxInterrupt,getWorkflowSandboxInterrupt,unwrapWorkflowSandboxResult}from"#shared/workflow-sandbox.js";import{FINAL_OUTPUT_TOOL_NAME,buildFinalOutputTool}from"#runtime/framework-tools/final-output.js";const environment=process.env.NODE_ENV??`unknown`,eveVersion=resolveInstalledPackageInfo().version,log=createLogger(`harness.tool-loop`);function logToolExecutionError(e){e.toolOutput.type===`tool-error`&&logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function enrichTelemetry(e,t,n,r){if(e===void 0&&r===void 0)return;let i={};for(let e of Object.keys(n??{}))i[e]=!0;return{functionId:e?.functionId??t,includeRuntimeContext:i,integrations:r===void 0?void 0:e===void 0?[r]:[r,createOtelIntegration()],isEnabled:!0,recordInputs:e?.recordInputs??!0,recordOutputs:e?.recordOutputs??!0}}function mergeSystemInstructions(e){if(e.length===0)return;if(e.length===1)return{...e[0]};let t;for(let n of e)n.providerOptions!==void 0&&(t={...t,...n.providerOptions});let n={role:`system`,content:e.map(e=>e.content).join(`
1
+ import{createErrorId,createLogger,formatError,logError,recordErrorOnSpan}from"#internal/logging.js";import{isScheduleAppAuth}from"#channel/schedule-auth.js";import{AuthKey,ParentSessionKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{toErrorMessage}from"#shared/errors.js";import{createActionResultEvent,createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createInputRequestedEvent,createResultCompletedEvent,createStepStartedEvent}from"#protocol/message.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{resolveProviderHeaders}from"#internal/gateway.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{contextStorage}from"#context/container.js";import{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStepStarted,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{ToolLoopAgent,isStepCount}from"ai";import{createRuntimeActionRequestFromToolCall,resolvePendingRuntimeActions,setPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{normalizeUserContent,resolveAssistantStepText}from"#harness/messages.js";import{clearPendingWorkflowInterrupt,getPendingWorkflowInterrupt,setPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getWorkflowRuntimeActionInterrupts,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{getActiveDynamicModelSelection}from"#context/dynamic-model-lifecycle.js";import{activeTurnId}from"#harness/active-turn-id.js";import{consumeDeferredStepInput,getApprovedTools,getPendingInputRequestIds,hasDeferredStepInput,hasStepInput,resolvePendingInput,setPendingInputBatch}from"#harness/input-requests.js";import{createInstrumentationHandleEvent}from"#harness/instrumentation-native-events.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{isAuthorizationSignal,setPendingAuthorization}from"#harness/authorization.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{buildDynamicInstructionMessages}from"#context/dynamic-instruction-lifecycle.js";import{PendingSkillAnnouncementKey}from"#context/dynamic-skill-lifecycle.js";import{accumulateTurnUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{getWorkflowContinuationSecurity,readWorkflowContinuationSecurity}from"#harness/workflow-continuation-security.js";import{buildWorkflowHostTools,resolveWorkflowSandboxBridgeRequestLimit}from"#harness/workflow-sandbox.js";import{CONDITIONAL_DELIVERY_INSTRUCTION,EMPTY_DELIVERY_SENTINEL,hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{createToolResultMessagePartFromToolError}from"#harness/action-result-helpers.js";import{getInvalidToolCallInputError,isInvalidToolCall}from"#harness/tool-call-input-errors.js";import{EmptyModelResponseError,classifyModelCallError,extractModelCallErrorDetails,extractUnsupportedProviderToolTypes,extractUpstreamRejectionMessage,isNoOutputGeneratedError}from"#harness/model-call-error.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";import{ASK_QUESTION_TOOL_NAME}from"#runtime/framework-tools/ask-question.js";import{extractQuestionInputRequests,extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyLastToolCacheBreakpoint,applySystemCacheBreakpoint,detectPromptCachePath,getAnthropicCacheMarker}from"#harness/prompt-cache.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{hydrateSandboxAttachments,stageAttachmentsToSandbox}from"#harness/attachment-staging.js";import{createWorkflowLifecycle}from"#harness/workflow-lifecycle.js";import{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact}from"#harness/compaction.js";import{applySessionLimitContinuation,enforceSessionTokenLimit}from"#harness/session-limit-enforcement.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{buildTelemetryRuntimeContext}from"#harness/instrumentation-runtime-context.js";import{createAiSdkHookBridge}from"#harness/ai-sdk-hook-bridge.js";import{convertStaleResponsesToUserMessage,dropStaleSessionLimitContinuationResponses}from"#harness/stale-input-responses.js";import{getInstrumentationConfig}from"#harness/instrumentation-config.js";import{normalizeProviderToolHistory}from"#harness/provider-tool-history.js";import{extractWorkflowStreamWriteErrorDetails}from"#harness/workflow-stream-error.js";import{createOtelIntegration,ensureOtelIntegration}from"#harness/otel-integration.js";import{getAdvertisedTools}from"#harness/advertised-tools.js";import{resolveFrameworkToolFromUpstreamType}from"#harness/provider-tools.js";import{buildStepHooks,emitStepActions}from"#harness/step-hooks.js";import{buildToolApproval,buildToolSetFromDefinitions,buildToolSetWithProviderTools}from"#harness/tools.js";import{continueWorkflowSandboxInterrupt,getWorkflowSandboxInterrupt,unwrapWorkflowSandboxResult}from"#shared/workflow-sandbox.js";import{FINAL_OUTPUT_TOOL_NAME,buildFinalOutputTool}from"#runtime/framework-tools/final-output.js";const environment=process.env.NODE_ENV??`unknown`,eveVersion=resolveInstalledPackageInfo().version,log=createLogger(`harness.tool-loop`);function logToolExecutionError(e){e.toolOutput.type===`tool-error`&&logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function enrichTelemetry(e,t,n,r){if(e===void 0&&r===void 0)return;let i={};for(let e of Object.keys(n??{}))i[e]=!0;return{functionId:e?.functionId??t,includeRuntimeContext:i,integrations:r===void 0?void 0:e===void 0?[r]:[r,createOtelIntegration()],isEnabled:!0,recordInputs:e?.recordInputs??!0,recordOutputs:e?.recordOutputs??!0}}function mergeSystemInstructions(e){if(e.length===0)return;if(e.length===1)return{...e[0]};let t;for(let n of e)n.providerOptions!==void 0&&(t={...t,...n.providerOptions});let n={role:`system`,content:e.map(e=>e.content).join(`
2
2
 
3
3
  `)};return t!==void 0&&(n.providerOptions=t),n}function buildGatewayAttributionHeaders(e,t){let n=resolveProviderHeaders(e);if(n===void 0)return;let r=t?.agentName??t?.agentId,i=process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.VERCEL_URL,a=i?`https://${i}`:void 0,o={...n};return r&&(o[`x-title`]=r),a&&(o[`http-referer`]=a),o}async function resolveActiveRuntimeModel(e){if(e.ctx===void 0)return{model:await e.config.resolveModel(e.session.agent.modelReference),session:e.session};let t=e.session.agent.dynamicModelDefaultReference??e.session.agent.modelReference,n=getActiveDynamicModelSelection(e.ctx);return n===null?{model:await e.config.resolveModel(t),session:updateSessionModelReference(e.session,t)}:{model:n.model===void 0?await e.config.resolveModel(n.reference):n.model,session:updateSessionModelReference(e.session,n.reference)}}function updateSessionModelReference(e,t){let n=e.agent.modelReference;return{...e,agent:{...e.agent,modelReference:t},compaction:updateCompactionThresholdForModelReference({compaction:e.compaction,modelReference:t,priorReference:n})}}function updateCompactionThresholdForModelReference(e){if(e.modelReference.contextWindowTokens===void 0||e.priorReference.contextWindowTokens===void 0)return e.compaction;let t=e.compaction.threshold/e.priorReference.contextWindowTokens;return{...e.compaction,threshold:Math.max(1,Math.floor(e.modelReference.contextWindowTokens*t))}}const TURN_TRACE_STATE_KEY=`eve.harness.turnTrace`;function getTurnTraceState(e){return e.state?.[TURN_TRACE_STATE_KEY]}function setTurnTraceState(e,t){let n={traceId:t.traceId,spanId:t.spanId,traceFlags:t.traceFlags};return{...e,state:{...e.state,[TURN_TRACE_STATE_KEY]:n}}}function resolveStepOtelContext(e,t,n){if(t)return trace.setSpan(context.active(),t);if(e){let e=getTurnTraceState(n);if(e){let t=trace.wrapSpanContext({traceId:e.traceId,spanId:e.spanId,traceFlags:e.traceFlags});return trace.setSpan(context.active(),t)}}}function createToolLoopHarness(t){let n=t.handleEvent,c=getInstrumentationConfig();c!==void 0&&ensureOtelIntegration();let d=c===void 0?void 0:trace.getTracer(`eve`),f=t.runtimeIdentity?.agentName;async function runStep(e,t){let n;if(d&&hasStepInput(t)){let t=c?.functionId??f,r={"eve.version":eveVersion,"eve.environment":environment,"eve.session.id":e.sessionId};t&&(r[`ai.telemetry.functionId`]=t),n=d.startSpan(`ai.eve.turn`,{attributes:r})}let r=resolveStepOtelContext(d,n,e),executeStep=()=>executeStepBody(e,t,n);try{return r?await context.with(r,executeStep):await executeStep()}finally{n?.end()}}async function executeStepBody(d,p,m){let h=d;m&&(h=setTurnTraceState(h,m.spanContext()));let _=getHarnessEmissionState(h.state),te=contextStorage.getStore()?.get(ParentSessionKey),O=createInstrumentationHandleEvent({agentName:t.runtimeIdentity?.agentName,handleEvent:n,hooks:t.instrumentation?.hooks,rootSessionId:te?.rootSessionId,sessionId:h.sessionId,turnId:activeTurnId(_)}),k=consumeDeferredStepInput({input:p,session:h});h=k.session;let j=await resolvePendingRuntimeActions({emit:O,session:h,stepInput:k.input});if(j.outcome===`unresolved`)return{next:null,session:j.session};h=j.session;let M=getPendingInputRequestIds(h.state),N=convertStaleResponsesToUserMessage({history:j.messages,pendingRequestIds:M,stepInput:dropStaleSessionLimitContinuationResponses({pendingRequestIds:M,stepInput:k.input})}),P=N.stepInput,F=N.kind===`converted`?{...P,message:N.displayMessage}:P,I=resolvePendingInput({history:j.messages,resolveApprovalKey:resolveApprovalKeyFromTools(t.tools),session:h,stepInput:P});if(I.outcome===`unresolved`)return O&&I.deferredMessage===!0&&hasStepInput(p)?(_=await emitTurnPreamble(O,F??{},_,t.runtimeIdentity),_=await emitTurnEpilogue(O,_,t.mode,I.session.continuationToken),{next:null,session:setHarnessEmissionState(I.session,_)}):{next:null,session:I.session};if(O&&I.rejectedActions)for(let e of I.rejectedActions.results)await O(createActionResultEvent({rejected:!0,result:e,sequence:I.rejectedActions.event.sequence,stepIndex:I.rejectedActions.event.stepIndex,turnId:I.rejectedActions.event.turnId}));O&&hasStepInput(p)&&(_=await emitTurnPreamble(O,F??{},_,t.runtimeIdentity),h=setHarnessEmissionState(h,_),m&&m.setAttribute(`eve.turn.id`,_.turnId)),h=I.session;let L=I.messages,R=await applySessionLimitContinuation({config:t,emit:O,emissionState:_,limitContinuation:I.limitContinuation,session:h});if(R.result!==null)return R.result;if(h=R.session,P?.context!==void 0&&I.deferredContext!==!0)for(let e of P.context)L.push({content:e,role:`user`});let z=normalizeUserContent(P?.message);if(z!==void 0&&!I.deferredMessage&&!I.consumedMessage){let e=await stageAttachmentsToSandbox(z);L.push({content:e,role:`user`})}let B=contextStorage.getStore();B!==void 0&&t.dispatchDynamicModelEvent!==void 0&&await t.dispatchDynamicModelEvent({ctx:B,event:createStepStartedEvent({sequence:_.sequence,stepIndex:_.stepIndex,turnId:_.turnId}),fallback:h.agent.dynamicModelDefaultReference??h.agent.modelReference,messages:L});let V=await resolveActiveRuntimeModel({config:t,ctx:B,session:h});h=V.session;let H=V.model,U=detectPromptCachePath(H),W=U.kind===`anthropic-direct`?getAnthropicCacheMarker():void 0,re=buildGatewayAttributionHeaders(H,t.runtimeIdentity);({messages:L,session:h}=await maybeCompact({abortSignal:t.abortSignal,emit:O,emissionState:_,messages:L,model:H,onCompaction:t.onCompaction,resolveModel:t.resolveModel,runtimeIdentity:t.runtimeIdentity,session:h,telemetry:enrichTelemetry(c,f)??void 0}));let G=getApprovedTools(h),K=h.outputSchema===void 0&&B!==void 0&&isScheduleAppAuth(B.get(AuthKey))&&B.get(ParentSessionKey)===void 0,ie=await hydrateSandboxAttachments(L),q=[],J=[];for(let e of ie)e.role===`system`?q.push(e):J.push(e);if(B!==void 0){q.push(...buildDynamicInstructionMessages(B));let e=B.get(PendingSkillAnnouncementKey);e!==void 0&&e.length>0&&q.push({role:`system`,content:e})}K&&q.push({role:`system`,content:CONDITIONAL_DELIVERY_INSTRUCTION});let Y=J,prepareModelCallInput=e=>{let t=e?[{role:`system`,content:e}]:[],n=h.agent.system?[{role:`system`,content:h.agent.system}]:[],r=q.length>0||t.length>0?[...t,...n,...q]:void 0,i=r!==void 0&&W?applySystemCacheBreakpoint(r,W):r,a=i===void 0?h.agent.system??void 0:mergeSystemInstructions(i);return{instructions:a,telemetryRuntimeContext:buildTelemetryRuntimeContext({eveVersion,authored:c,emissionState:_,environment,modelInput:{instructions:a,messages:Y},session:h})}},runSingleModelCall=async e=>{let{instructions:n,telemetryRuntimeContext:i={}}=e.preparedInput??prepareModelCallInput(e.extraSystemNote);e.retryReason&&(i[`eve.retry.reason`]=e.retryReason);let a=e.trailingUserNote?[...Y,{role:`user`,content:e.trailingUserNote}]:Y,o=getAdvertisedTools({session:h,tools:t.tools}),s=await buildToolSetWithProviderTools({approvedTools:G,capabilities:t.capabilities,disabledProviderTools:e.disabledProviderTools,modelReference:h.agent.modelReference,tools:o});if(B!==void 0){let n=getAdvertisedTools({session:h,tools:buildDynamicTools(B)}),r=buildToolSetFromDefinitions({approvedTools:G,capabilities:t.capabilities,disabledProviderTools:e.disabledProviderTools,tools:n});for(let[e,t]of Object.entries(r))s[e]=t}h.outputSchema!==void 0&&(s[FINAL_OUTPUT_TOOL_NAME]=buildFinalOutputTool(h.outputSchema));let l=O===void 0?void 0:({tools:e})=>createWorkflowLifecycle({emit:O,emissionState:_,tools:e}),u=t.workflow===!0?{lifecycle:l,maxSubagents:t.workflowMaxSubagents}:void 0,d=await getAdvertisedTools({modelTools:s,session:h,tools:o,workflow:u});h=d.session;let p=d.modelTools,m=W?applyLastToolCacheBreakpoint(p,W):p,g=t.instrumentation?.hooks,v=activeTurnId(_),y=g===void 0?void 0:{attemptId:`${h.sessionId}:${v}:${_.stepIndex}:${e.attemptIndex}`,attemptIndex:e.attemptIndex,functionId:c?.functionId??f,rootSessionId:te?.rootSessionId??h.sessionId,sessionId:h.sessionId,stepIndex:_.stepIndex,turnId:v},b=y===void 0||g===void 0?void 0:createAiSdkHookBridge(y,g,t.instrumentation?.runInContext),x=buildStepHooks({cachePath:U,emit:O,emissionState:_,emitStepStarted:e.suppressStepStartedEmission!==!0,marker:W,session:h}),S=new ToolLoopAgent({headers:re,instructions:n,model:H,onToolExecutionEnd:logToolExecutionError,onError(e){summarizeKnownError(e.error)?.tags.includes(`config`)!==!0&&logError(log,`tool-loop stream error`,e.error)},onStepFinish:x.onStepFinish,prepareStep:x.prepareStep,reasoning:h.agent.reasoning,runtimeContext:i,stopWhen:isStepCount(1),telemetry:enrichTelemetry(c,f,i,b),toolApproval:buildToolApproval(p),tools:m}),executeModelCall=async()=>{if(O){let e=[...t.tools].filter(([e,t])=>t.runtimeAction!==void 0&&o.get(e)===void 0).map(([e])=>e),n=new Set([ASK_QUESTION_TOOL_NAME,FINAL_OUTPUT_TOOL_NAME,...e]),r=await S.stream({abortSignal:t.abortSignal,messages:a}),{emittedActionCallIds:i,handledInlineToolResultCallIds:s,invalidInputToolCallIds:c,inlineAuthorizationResults:l,trailingInlineToolResultParts:u}=await emitStreamContent(O,_,r.fullStream,{excludedActionToolNames:n,tools:t.tools});throwIfTurnAborted(t.abortSignal);let[d,f]=await Promise.all([x.stepResult,r.responseMessages]);if(isEmptyModelResponse(d)&&extractToolResultCallIds(f).size===0&&l.length===0&&u.length===0)throw new EmptyModelResponseError;await emitStepActions(O,_,d,{emittedActionCallIds:i,excludedActionCallIds:c,excludedActionToolNames:n,handledInlineToolResultCallIds:s,tools:o});let p=d.toolResults,m=new Map(p.map(e=>[e.toolCallId,e]));for(let e of l)m.set(e.toolCallId,e);return withAccumulatedResponseMessages({invalidInputToolCallIds:c,responseMessages:appendMissingToolResultMessages({append:u,responseMessages:f}),stepResult:d,toolResults:[...m.values()]})}let e=await S.generate({abortSignal:t.abortSignal,messages:a});throwIfTurnAborted(t.abortSignal);let n=await x.stepResult;if(isEmptyModelResponse(n)&&extractToolResultCallIds(e.responseMessages).size===0)throw new EmptyModelResponseError;return withAccumulatedResponseMessages({responseMessages:e.responseMessages,stepResult:n})};try{let e=await executeModelCall();return y!==void 0&&await g?.publish({scope:y,type:`attempt.completed`}),e}catch(e){return y!==void 0&&await g?.publish({error:e,scope:y,type:`attempt.failed`}),rethrowNoOutputAsEmptyResponse(e)}},ae=0,runOneModelCall=async e=>runModelCallWithRetries(t=>runSingleModelCall({...e,attemptIndex:ae++,preparedInput:t===1?e.preparedInput:void 0,suppressStepStartedEmission:t!==1||e.suppressStepStartedEmission}),{sessionId:h.sessionId,turnId:_.turnId},t.abortSignal),oe=prepareModelCallInput();O&&await emitStepStarted(O,_,L);let X=await continuePendingWorkflowInterrupt({childResults:P?.runtimeActionResults,config:t,emit:O,emissionState:_,runStep,session:h});if(X!==null)return X;let se=await enforceSessionTokenLimit({config:t,emit:O,emissionState:_,messages:L,session:h});if(se!==null)return se;let Z;try{Z=await runOneModelCall({preparedInput:oe,suppressStepStartedEmission:!0})}catch(n){throwIfTurnAborted(t.abortSignal);let r=await runModelCallRecoveryPipeline({error:n,stages:[e=>attemptUnsupportedProviderToolRecovery({error:e.error,runOneModelCall,sessionId:h.sessionId,turnId:_.turnId}),e=>attemptEmptyResponseRecovery({emptyDeliveryEnabled:K,error:e.error,retryCallOptions:e.retryCallOptions,runOneModelCall,sessionId:h.sessionId,turnId:_.turnId})]});if(throwIfTurnAborted(t.abortSignal),r.outcome===`recovered`)Z=r.result;else{let n=r.error;if(m&&recordErrorOnSpan(m,n),!O)throw n;let a=extractWorkflowStreamWriteErrorDetails(n);if(a!==null){let t=createErrorId();return log.error(`workflow stream write failed — parking session for retry by the user`,{...a,errorId:t,error:n,sessionId:h.sessionId,turnId:_.turnId}),_=await emitRecoverableFailedTurn(O,_,{code:`WORKFLOW_STREAM_WRITE_FAILED`,continuationToken:h.continuationToken,details:{...a,errorId:t},message:toErrorMessage(n)}),{next:null,session:setHarnessEmissionState(h,_)}}let o=classifyModelCallError(n),s=createErrorId(),c=summarizeKnownError(n),u=c===null?extractUpstreamRejectionMessage(n):null,d=c?.message??u?.message??toErrorMessage(n),f=c?.hint===void 0?d:`${d} ${c.hint}`,p=extractModelCallErrorDetails(n),g=buildModelCallFailureDetails({catalogSummary:c,error:n,errorId:s,modelCallDetails:p,upstreamRejection:u}),v=buildModelCallFailureLogFields({error:n,errorId:s,modelCallDetails:p,recognized:c!==null||u!==null,sessionId:h.sessionId,turnId:_.turnId});if(o===`terminal`)return c===null?log.error(u?.message??`model call failed terminally`,v):log.error(`${c.name}: ${c.message}`,{errorId:s,hint:c.hint,sessionId:h.sessionId,turnId:_.turnId}),await emitFailedStep(O,_,{code:`MODEL_CALL_FAILED`,details:g,message:d,sessionId:h.sessionId}),{next:t.mode===`task`?{done:!0,isError:!0,output:f}:{done:!0,output:``},session:h};if(t.mode===`task`){if(o===`recoverable`&&!(n instanceof EmptyModelResponseError))throw log.warn(u?.message??`model call failed recoverably in task mode — rethrowing for durable step retry`,v),n;return log.error(u?.message??`model call failed; failing the task run`,v),await emitFailedStep(O,_,{code:`MODEL_CALL_FAILED`,details:g,message:d,sessionId:h.sessionId}),{next:{done:!0,isError:!0,output:f},session:h}}return log.error(u?.message??`model call failed — parking session for retry by the user`,v),_=await emitRecoverableFailedTurn(O,_,{code:`MODEL_CALL_FAILED`,continuationToken:h.continuationToken,details:g,message:d}),{next:null,session:setHarnessEmissionState(h,_)}}}let Q=accumulateTurnUsage({previous:getTurnUsageState(h.state),turnId:_.turnId,usage:extractTokenUsageDelta({costUsd:extractGatewayCostUsd(Z.providerMetadata),usage:Z.usage})});h=setTurnUsageState(h,Q);let $;try{$=formatLanguageModelGatewayId(H)}catch{$=void 0}return await setEveAttributes({"$eve.model":$,"$eve.input_tokens":Q.inputTokens,"$eve.output_tokens":Q.outputTokens,"$eve.cache_read_tokens":Q.cacheReadTokens,"$eve.cache_write_tokens":Q.cacheWriteTokens,"$eve.cost_usd":Q.sawCost?Q.costUsd:void 0,"$eve.tool_count":t.tools.size}),handleStepResult({config:t,emit:O,emissionState:_,promptMessages:L,result:Z,runStep,session:h})}return runStep}function extractTokenUsageDelta(e){let t=e.usage;if(!(t===void 0&&e.costUsd===void 0))return{cacheReadTokens:t?.inputTokenDetails?.cacheReadTokens,cacheWriteTokens:t?.inputTokenDetails?.cacheWriteTokens,costUsd:e.costUsd,inputTokens:t?.inputTokens,outputTokens:t?.outputTokens}}function extractGatewayCostUsd(e){let t=readGatewayMetadata(e)?.cost;if(typeof t==`number`&&Number.isFinite(t))return t;if(typeof t==`string`){let e=Number(t);return Number.isFinite(e)?e:void 0}}function readGatewayMetadata(e){let t=e?.gateway;return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}function buildModelCallFailureDetails(e){let{catalogSummary:t,error:r,errorId:i,modelCallDetails:a,upstreamRejection:o}=e;if(t!==null){let e={errorId:i,message:t.message,name:t.name,semanticErrorId:t.id,...a};return t.hint!==void 0&&(e.hint=t.hint),e}return o===null?{...formatError(r,i),...a}:{errorId:i,message:toErrorMessage(r),name:o.name,...a}}function buildModelCallFailureLogFields(e){let t={errorId:e.errorId,sessionId:e.sessionId,turnId:e.turnId};return e.recognized?{...t,details:e.modelCallDetails}:{...t,error:e.error}}async function runModelCallRecoveryPipeline(e){let t=e.error,n;for(let r of e.stages){let e=await r({error:t,retryCallOptions:n});if(e.outcome===`recovered`)return e;e.outcome===`failed`&&(t=e.error,n=e.retryCallOptions)}return{outcome:`failed`,error:t}}function withAccumulatedResponseMessages(e){let{stepResult:t}=e;return{content:t.content,finishReason:t.finishReason,...e.invalidInputToolCallIds===void 0?{}:{invalidInputToolCallIds:e.invalidInputToolCallIds},providerMetadata:t.providerMetadata,response:{...t.response,messages:[...e.responseMessages]},text:t.text,toolCalls:t.toolCalls,toolResults:e.toolResults===void 0?t.toolResults:[...e.toolResults],usage:t.usage}}function appendMissingToolResultMessages(e){let t=extractToolResultCallIds(e.responseMessages),n=e.append.filter(e=>!t.has(e.toolCallId));return[...e.responseMessages,...n.length>0?[{role:`tool`,content:[...n]}]:[]]}function getInvalidToolCallInputErrors(e){let t=[];for(let n of e.toolCalls){if(n.toolName===FINAL_OUTPUT_TOOL_NAME)continue;let e=getInvalidToolCallInputError({toolCall:n});e!==void 0&&t.push(e)}return t}function extractToolResultCallIds(e){let t=new Set;for(let n of e)if(!(n.role!==`tool`||!Array.isArray(n.content)))for(let e of n.content)e.type===`tool-result`&&t.add(e.toolCallId);return t}async function attemptUnsupportedProviderToolRecovery(e){let t=extractUnsupportedProviderToolTypes(e.error);if(t.length===0)return{outcome:`skipped`};let n=[];for(let e of t){let t=resolveFrameworkToolFromUpstreamType(e);t!==null&&!n.includes(t)&&n.push(t)}if(n.length===0)return{outcome:`skipped`};log.warn(`disabling unsupported provider tool(s); retrying step once`,{disabled:n,sessionId:e.sessionId,turnId:e.turnId,upstreamTypes:t});let r={disabledProviderTools:new Set(n),extraSystemNote:buildDisabledToolNote(n)};try{return{outcome:`recovered`,result:await e.runOneModelCall({...r,suppressStepStartedEmission:!0})}}catch(e){return{outcome:`failed`,error:e,retryCallOptions:r}}}function buildDisabledToolNote(e){let t=e.join(`, `);return`The following ${e.length===1?`tool is`:`tools are`} not available with the current model and has been removed: ${t}. Proceed using the remaining tools or your training knowledge.`}function isEmptyModelResponse(e){return e.toolCalls.length===0&&e.toolResults.length===0&&resolveAssistantStepText(e.response.messages,e.text)===null}function rethrowNoOutputAsEmptyResponse(e){throw isNoOutputGeneratedError(e)?new EmptyModelResponseError({cause:e}):e}const EMPTY_RESPONSE_NUDGE=`Your previous reply was empty and was not delivered. Answer now from the tool results above; do not re-run tools or mention this notice.`;function buildEmptyResponseNudge(e){return e?`${EMPTY_RESPONSE_NUDGE} If the current task explicitly requires conditional delivery and there is nothing to report, reply with exactly ${EMPTY_DELIVERY_SENTINEL}.`:EMPTY_RESPONSE_NUDGE}async function attemptEmptyResponseRecovery(e){if(!(e.error instanceof EmptyModelResponseError))return{outcome:`skipped`};log.warn(`empty model response; reissuing the model call once`,{sessionId:e.sessionId,turnId:e.turnId});try{return{outcome:`recovered`,result:await e.runOneModelCall({...e.retryCallOptions,retryReason:`empty-response`,suppressStepStartedEmission:!0,trailingUserNote:buildEmptyResponseNudge(e.emptyDeliveryEnabled)})}}catch(t){return{outcome:`failed`,error:t,retryCallOptions:e.retryCallOptions}}}async function handleStepResult(e){let{config:t,emit:n,promptMessages:r,result:i,runStep:a}=e,{emissionState:o,session:s}=e,c=resolveAssistantStepText(i.response.messages,i.text),l=i.finishReason!==`tool-calls`&&i.toolCalls.length===0&&hasEmptyDeliverySentinel(c),u=getInvalidToolCallInputErrors({toolCalls:i.toolCalls}),f=new Set([...i.invalidInputToolCallIds??[],...i.toolCalls.filter(isInvalidToolCall).map(e=>e.toolCallId),...u.map(e=>e.toolCallId)]),p=l?[]:appendMissingToolResultMessages({append:u.map(e=>createToolResultMessagePartFromToolError(e)),responseMessages:i.response.messages}),h=l?null:c,g=new Set;for(let e of[...i.content??[],...i.toolResults??[]])(e.type===`tool-result`||e.type===`tool-error`)&&e.providerExecuted===!0&&g.add(e.toolCallId);let ee=normalizeProviderToolHistory({messages:p,providerExecutedOutcomeIds:g}),_=ee.messages,v={...s,compaction:createNextCompactionConfig(s.compaction,r,i)},y=t.workflow===!0?readWorkflowContinuationSecurity(v):void 0;if(y!==void 0){let e=await getWorkflowSandboxInterrupt(i,y);if(e!==void 0){if(!isWorkflowRuntimeActionInterrupt(e))throw Error(`Unsupported Workflow interrupt kind "${e.payload.kind}".`);return parkOnWorkflowInterrupt({baseSession:v,emissionState:o,interrupt:e,promptMessages:r,responseMessages:_})}}let b=extractToolApprovalInputRequests({content:i.content??[],excludedCallIds:f}),x=new Set(b.map(e=>e.action.callId)),S=extractQuestionInputRequests({toolCalls:i.toolCalls,excludedCallIds:new Set([...f,...x])}),C=[...b,...S],w=getAdvertisedTools({session:v,tools:t.tools}),T=(i.toolCalls??[]).filter(e=>!f.has(e.toolCallId)).filter(e=>t.tools.get(e.toolName)?.runtimeAction!==void 0).filter(e=>w.get(e.toolName)?.runtimeAction===void 0?(log.warn(`runtime action tool call blocked because tool is not advertised`,{callId:e.toolCallId,sessionId:v.sessionId,toolName:e.toolName}),!1):!0).map(e=>createRuntimeActionRequestFromToolCall({toolCall:e,tools:w}));if(T.length>0)return{next:null,session:setHarnessEmissionState(setPendingRuntimeActionBatch({actions:T,event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},responseMessages:_,session:{...v,history:[...r]}}),o)};if(C.length>0){let e=setPendingInputBatch({event:{sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId},requests:C,responseMessages:_,session:{...v,history:[...r]}});return n&&(await n(createInputRequestedEvent({requests:C,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),t.mode===`conversation`&&(o=await emitTurnEpilogue(n,o,t.mode,e.continuationToken),e=setHarnessEmissionState(e,o))),{next:null,session:e}}let E=findAuthorizationSignalFromToolResults(i.toolResults);if(E){let{challenges:e}=E;if(n)for(let t of e)await n(createAuthorizationRequiredEvent({authorization:t.challenge,name:t.name,description:t.challenge.instructions??`Authorization required for ${t.name}`,webhookUrl:t.hookUrl,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));return{next:null,session:setHarnessEmissionState({...v,history:[...r],state:setPendingAuthorization(v.state,{challenges:e})},o)}}let D=_,ne=[...r,...D],A={...v,history:ne};return!(A.outputSchema!==void 0&&extractFinalOutput(i)!==void 0)&&(D.at(-1)?.role===`tool`||ee.outcomeEndsResponse||hasDeferredStepInput(A))?(n&&(o=advanceStep(o),A=setHarnessEmissionState(A,o)),{next:a,session:A}):t.mode===`task`?finishTaskTurn({emissionState:o,emit:n,history:r,result:i,schema:A.outputSchema,session:A,stepOutput:h}):finishConversationTurn({emissionState:o,emit:n,history:r,result:i,schema:A.outputSchema,session:A})}const OUTPUT_SCHEMA_NOT_FULFILLED={code:`OUTPUT_SCHEMA_NOT_FULFILLED`,message:`The agent could not produce a result matching the requested schema.`};function extractFinalOutput(e){return(e.toolCalls??[]).find(e=>e.toolName===FINAL_OUTPUT_TOOL_NAME&&!isInvalidToolCall(e))?.input}function persistStructuredAssistantTurn(e,t,n){return{...e,history:[...t,{content:JSON.stringify(n),role:`assistant`}],outputSchema:void 0}}async function emitStructuredResult(e,t,n,r,i){return await e(createResultCompletedEvent({result:n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),emitTurnEpilogue(e,t,r,i)}async function finishTaskTurn(e){let{emit:t,history:n,result:r,schema:i,stepOutput:a}=e,{emissionState:o,session:s}=e;if(i===void 0)return t&&(o=await emitTurnEpilogue(t,o,`task`,s.continuationToken),s=setHarnessEmissionState(s,o)),{next:{done:!0,output:a??``},session:s};let c=extractFinalOutput(r);return c===void 0?(t&&await emitFailedStep(t,o,{...OUTPUT_SCHEMA_NOT_FULFILLED,sessionId:s.sessionId}),{next:{done:!0,isError:!0,output:OUTPUT_SCHEMA_NOT_FULFILLED.message},session:s}):(s=persistStructuredAssistantTurn(s,n,c),t&&(o=await emitStructuredResult(t,o,c,`task`,s.continuationToken),s=setHarnessEmissionState(s,o)),{next:{done:!0,output:c},session:s})}async function finishConversationTurn(e){let{emit:t,history:n,result:r,schema:i}=e,{emissionState:a,session:o}=e;if(i===void 0)return t&&(a=await emitTurnEpilogue(t,a,`conversation`,o.continuationToken),o=setHarnessEmissionState(o,a)),{next:null,session:o};let s=extractFinalOutput(r);return s===void 0?(t&&(a=await emitRecoverableFailedTurn(t,a,{...OUTPUT_SCHEMA_NOT_FULFILLED,continuationToken:o.continuationToken}),o=setHarnessEmissionState(o,a)),{next:null,session:o}):(o=persistStructuredAssistantTurn(o,n,s),t&&(a=await emitStructuredResult(t,a,s,`conversation`,o.continuationToken),o=setHarnessEmissionState(o,a)),{next:null,session:o})}async function continuePendingWorkflowInterrupt(e){let t=getPendingWorkflowInterrupt(e.session.state);if(t===void 0)return null;let n=t.interrupt;if(!isWorkflowRuntimeActionInterrupt(n))throw Error(`Unsupported Workflow interrupt kind "${n.payload.kind}".`);let i=e.emit===void 0?void 0:createWorkflowLifecycle({emit:e.emit,emissionState:e.emissionState,skipReplayed:!0,tools:e.config.tools}),a=getWorkflowContinuationSecurity(e.session),o;try{let t=buildWorkflowHostTools({tools:e.config.tools}),r=e.childResults??[],s=n,c=0;for(;;){o=await continueWorkflowSandboxInterrupt({bridgeRequestLimit:resolveWorkflowSandboxBridgeRequestLimit(e.config.workflowMaxSubagents),continuationSecurity:a,interrupt:s,lifecycle:i,resolution:r[c]?.output,tools:t});let n=await unwrapWorkflowSandboxResult(o,a);if(n.status!==`interrupted`||!isWorkflowRuntimeActionInterrupt(n.interrupt)||c+1>=r.length)break;let l=getWorkflowRuntimeActionInterrupts(n.interrupt)[0];if(l===void 0)throw Error(`Workflow continuation contains no pending runtime-action interrupt.`);c++,s=l}}catch(e){logError(log,`Workflow interrupt continuation failed`,e),o={error:`workflow_continuation_failed`,message:toErrorMessage(e),retryable:!1}}let s=await unwrapWorkflowSandboxResult(o,a),c=s.status===`interrupted`?s.interrupt:s.output,u=replaceWorkflowToolResult([...e.session.history,...t.responseMessages],n.outerToolCallId,c),d=clearPendingWorkflowInterrupt({...e.session,history:u});if(s.status===`interrupted`){if(!isWorkflowRuntimeActionInterrupt(s.interrupt))throw Error(`Unsupported Workflow interrupt kind "${s.interrupt.payload.kind}".`);let t=e.session.history.length,n=u.slice(0,t),r=u.slice(t);return d={...d,history:n},parkOnWorkflowInterrupt({baseSession:d,emissionState:e.emissionState,interrupt:s.interrupt,promptMessages:n,responseMessages:r})}return{next:e.runStep,session:d}}function replaceWorkflowToolResult(e,t,n){if(t===void 0)return[...e];let r=typeof n==`string`?{type:`text`,value:n}:{type:`json`,value:n};return e.map(e=>{if(e.role!==`tool`)return e;let n=e.content.map(e=>e.type!==`tool-result`||e.toolCallId!==t?e:{...e,output:r});return{...e,content:n}})}function parkOnWorkflowInterrupt(e){let t=getWorkflowRuntimeActionInterrupts(e.interrupt)[0];if(t===void 0)throw Error(`Workflow continuation contains no pending runtime-action interrupt.`);let n={...e.baseSession,history:[...e.promptMessages]};return{next:null,session:setHarnessEmissionState(setPendingWorkflowInterrupt({interrupt:t,responseMessages:e.responseMessages,session:n}),e.emissionState)}}function createNextCompactionConfig(e,t,n){let r={recentWindowSize:e.recentWindowSize,threshold:e.threshold};return n.usage?.inputTokens!==void 0&&(r.lastKnownInputTokens=n.usage.inputTokens,r.lastKnownPromptMessageCount=t.length),r}async function maybeCompact(e){let{emit:t,emissionState:n}=e,r=e.messages,i=e.session;if(!shouldCompact(r,i.compaction))return{messages:r,session:i};let a=await resolveCompactionModel({compactionModelReference:i.agent.compactionModelReference,model:e.model,modelReference:i.agent.modelReference,resolveModel:e.resolveModel});if(t&&await t(createCompactionRequestedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId,usageInputTokens:getInputTokenCount(r,i.compaction)})),r=await compactMessages(r,a.model,i.compaction,a.providerOptions,e.telemetry,buildGatewayAttributionHeaders(a.model,e.runtimeIdentity),e.abortSignal),e.onCompaction)for(let t of e.onCompaction())r.push(t);return t&&await t(createCompactionCompletedEvent({modelId:formatLanguageModelGatewayId(a.model),sequence:n.sequence,sessionId:i.sessionId,turnId:n.turnId})),{messages:r,session:i}}function resolveApprovalKeyFromTools(e){return t=>{let n=e.get(t.action.toolName);if(n?.approvalKey!==void 0)return n.approvalKey(t.action.input)}}async function runModelCallWithRetries(e,t,n){for(let r=1;;r++){throwIfTurnAborted(n);try{return await e(r)}catch(e){if(throwIfTurnAborted(n),r===3||classifyModelCallError(e)!==`retry`)throw e;let i=500*2**(r-1)+Math.floor(Math.random()*250);log.warn(`model call failed transiently — retrying`,{attempt:r,delayMs:i,sessionId:t.sessionId,turnId:t.turnId,error:e}),await new Promise(e=>setTimeout(e,i))}}}function findAuthorizationSignalFromToolResults(e){let t=contextStorage.getStore();if(t!==void 0)for(let n of e??[]){let e=readToolInterrupt(t,n.toolCallId);if(e!==void 0&&isAuthorizationSignal(e))return e}for(let t of e??[])if(isAuthorizationSignal(t.output))return t.output}export{createToolLoopHarness};
@@ -23,7 +23,9 @@
23
23
  * session total crosses into it.
24
24
  */
25
25
  import type { HarnessSession, SessionStateMap } from "#harness/types.js";
26
+ import { type SessionRuntimeTokenLimits, type SessionTokenLimitViolation } from "#harness/session-token-limits.js";
26
27
  import type { TokenUsage } from "#shared/token-usage.js";
28
+ export type { SessionRuntimeTokenLimits, SessionTokenLimitViolation };
27
29
  export interface TokenUsageTotals {
28
30
  readonly cacheReadTokens: number;
29
31
  readonly cacheWriteTokens: number;
@@ -46,28 +48,35 @@ export interface TurnUsageState extends TokenUsageTotals {
46
48
  }
47
49
  /** Reads the stored per-turn token state, or `undefined` when absent. */
48
50
  export declare function getTurnUsageState(state: SessionStateMap | undefined): TurnUsageState | undefined;
49
- export type SessionTokenLimitViolation = {
50
- readonly kind: "input";
51
- readonly limit: number;
52
- readonly usedTokens: number;
53
- } | {
54
- readonly kind: "output";
55
- readonly limit: number;
56
- readonly usedTokens: number;
57
- };
58
51
  export declare function getSessionTokenUsage(session: Pick<HarnessSession, "state">): TokenUsageTotals;
59
52
  /** Projects a {@link TokenUsageTotals} down to the cross-cutting {@link TokenUsage} shape. */
60
53
  export declare function toUsage(totals: TokenUsageTotals): TokenUsage;
61
54
  /**
62
- * Resets the session token budget windows to the current usage totals.
63
- *
64
- * Called when the user grants a continuation after a session token limit was
65
- * reached. The configured limits keep their values and act as the size of the
66
- * next budget window, measured from the moment of the grant. Both windows
67
- * reset together so a session near two limits gets one prompt, not two
68
- * back-to-back.
55
+ * The lifetime-usage ceilings currently in force, per axis. An axis is
56
+ * absent when the configured limit leaves it uncapped. Before any granted
57
+ * continuation the runtime limit equals the configured limit; each grant
58
+ * re-anchors it to `usage + configured limit` via
59
+ * {@link bumpSessionRuntimeTokenLimits}.
60
+ */
61
+ export declare function getSessionRuntimeTokenLimits(session: Pick<HarnessSession, "limits" | "state">): SessionRuntimeTokenLimits;
62
+ /**
63
+ * Bumps the runtime token limits after the user grants a continuation:
64
+ * each capped axis is re-anchored to `current usage + configured limit`, so
65
+ * one approval always buys one full configured window from the moment of
66
+ * the grant (even when the last model call overshot by more than a window).
67
+ * Both axes bump together so a session near two limits gets one prompt, not
68
+ * two back-to-back. The configured limits never change.
69
69
  */
70
- export declare function extendSessionTokenBudget(session: HarnessSession): HarnessSession;
70
+ export declare function bumpSessionRuntimeTokenLimits(session: HarnessSession): HarnessSession;
71
+ /**
72
+ * Remaining lifetime-token quota under the runtime limits, per axis.
73
+ * `false` marks an uncapped axis. This is the pool a delegated child's
74
+ * budget is granted from.
75
+ */
76
+ export declare function getSessionRemainingTokenQuota(session: Pick<HarnessSession, "limits" | "state">): {
77
+ inputTokens: number | false;
78
+ outputTokens: number | false;
79
+ };
71
80
  export declare function getSessionTokenLimitViolation(session: Pick<HarnessSession, "limits" | "state">): SessionTokenLimitViolation | null;
72
81
  /** Writes per-turn token state onto a new copy of the session. */
73
82
  export declare function setTurnUsageState(session: HarnessSession, next: TurnUsageState): HarnessSession;